PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ ST_RemoveSmallParts()

Datum ST_RemoveSmallParts ( PG_FUNCTION_ARGS  )

Definition at line 77 of file lwgeom_remove_small_parts.c.

77 {
78
79 double mindx = 0, mindy = 0;
80 unsigned int i, j, iw, jw;
81
82 GSERIALIZED *serialized_in;
83 GSERIALIZED *serialized_out;
84
85 LWGEOM *geom;
86
87 // geom input check
88 if (PG_GETARG_POINTER(0) == NULL) {
89 PG_RETURN_NULL();
90 }
91
92 serialized_in = (GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
93
94 if (PG_NARGS() == 3) {
95
96 if (PG_ARGISNULL(1) || PG_ARGISNULL(2)) {
97 // no valid args given, leave untouched
98 PG_RETURN_POINTER(serialized_in);
99 }
100
101 mindx = PG_GETARG_FLOAT8(1);
102 mindy = PG_GETARG_FLOAT8(2);
103 if (mindx <= 0 && mindy <= 0) {
104 // nothing to do
105 PG_RETURN_POINTER(serialized_in);
106 }
107
108 // type check (only polygon and line types are supported yet)
109 if (gserialized_get_type(serialized_in) != POLYGONTYPE &&
110 gserialized_get_type(serialized_in) != MULTIPOLYGONTYPE &&
111 gserialized_get_type(serialized_in) != LINETYPE &&
112 gserialized_get_type(serialized_in) != MULTILINETYPE) {
113
114 // no (multi)polygon or (multi)linetype, leave untouched
115 PG_RETURN_POINTER(serialized_in);
116 }
117
118 }
119
120 else {
121 // unknown params, leave untouched
122 PG_RETURN_POINTER(serialized_in);
123 }
124
125 // deserialize geom and copy coordinates (no clone_deep)
126 geom = lwgeom_from_gserialized(serialized_in);
127
128 if (geom->type == LINETYPE) {
129
130 LWLINE* line = (LWLINE*)geom;
131 ptarray_remove_dim_helper(line->points, mindx, mindy);
132 }
133
134 if (geom->type == MULTILINETYPE) {
135
136 LWMLINE* mline = (LWMLINE*)geom;
137 iw = 0;
138 for (i=0; i<mline->ngeoms; i++) {
139 LWLINE* line = mline->geoms[i];
140 ptarray_remove_dim_helper(line->points, mindx, mindy);
141
142 if (line->points->npoints) {
143 // keep (reduced) line
144 mline->geoms[iw++] = line;
145 }
146 else {
147 // discard current line
148 lwfree(line);
149 }
150 }
151 mline->ngeoms = iw;
152 }
153
154 if (geom->type == POLYGONTYPE) {
155
156 LWPOLY* polygon = (LWPOLY*)geom;
157 iw = 0;
158 for (i=0; i<polygon->nrings; i++) {
159 ptarray_remove_dim_helper(polygon->rings[i], mindx, mindy);
160
161 if (polygon->rings[i]->npoints) {
162 // keep (reduced) ring
163 polygon->rings[iw++] = polygon->rings[i];
164 }
165 else {
166 if (!i) {
167 // exterior ring too small, free and skip all rings
168 unsigned int k;
169 for (k=0; k<polygon->nrings; k++) {
170 lwfree(polygon->rings[k]);
171 }
172 break;
173 }
174 else {
175 // free and remove current interior ring
176 lwfree(polygon->rings[i]);
177 }
178 }
179 }
180 polygon->nrings = iw;
181 }
182
183 if (geom->type == MULTIPOLYGONTYPE) {
184
185 LWMPOLY* mpolygon = (LWMPOLY*)geom;
186 jw = 0;
187 for (j=0; j<mpolygon->ngeoms; j++) {
188
189 LWPOLY* polygon = mpolygon->geoms[j];
190 iw = 0;
191 for (i=0; i<polygon->nrings; i++) {
192 ptarray_remove_dim_helper(polygon->rings[i], mindx, mindy);
193
194 if (polygon->rings[i]->npoints) {
195 // keep (reduced) ring
196 polygon->rings[iw++] = polygon->rings[i];
197 }
198 else {
199 if (!i) {
200 // exterior ring too small, free and skip all rings
201 unsigned int k;
202 for (k=0; k<polygon->nrings; k++) {
203 lwfree(polygon->rings[k]);
204 }
205 break;
206 }
207 else {
208 // free and remove current interior ring
209 lwfree(polygon->rings[i]);
210 }
211 }
212 }
213 polygon->nrings = iw;
214
215 if (iw) {
216 mpolygon->geoms[jw++] = polygon;
217 }
218 else {
219 // free and remove polygon from multipolygon
220 lwfree(polygon);
221 }
222 }
223 mpolygon->ngeoms = jw;
224 }
225
226 // recompute bbox if computed previously (may result in NULL)
227 lwgeom_drop_bbox(geom);
228 lwgeom_add_bbox(geom);
229
230 serialized_out = gserialized_from_lwgeom(geom, 0);
231 lwgeom_free(geom);
232
233 PG_FREE_IF_COPY(serialized_in, 0);
234 PG_RETURN_POINTER(serialized_out);
235}
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition lwgeom.c:710
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
void lwfree(void *mem)
Definition lwutil.c:248
#define POLYGONTYPE
Definition liblwgeom.h:104
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Definition lwgeom.c:723
static void ptarray_remove_dim_helper(POINTARRAY *points, double mindx, double mindy)
uint8_t type
Definition liblwgeom.h:462
POINTARRAY * points
Definition liblwgeom.h:483
LWLINE ** geoms
Definition liblwgeom.h:547
uint32_t ngeoms
Definition liblwgeom.h:552
uint32_t ngeoms
Definition liblwgeom.h:566
LWPOLY ** geoms
Definition liblwgeom.h:561
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
uint32_t npoints
Definition liblwgeom.h:427

References LWMLINE::geoms, LWMPOLY::geoms, gserialized_from_lwgeom(), gserialized_get_type(), LINETYPE, lwfree(), lwgeom_add_bbox(), lwgeom_drop_bbox(), lwgeom_free(), lwgeom_from_gserialized(), MULTILINETYPE, MULTIPOLYGONTYPE, LWMLINE::ngeoms, LWMPOLY::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, LWLINE::points, POLYGONTYPE, ptarray_remove_dim_helper(), LWPOLY::rings, and LWGEOM::type.

Here is the call graph for this function: