PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ 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 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:268
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:118
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
Definition: gserialized.c:251
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
#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:682
#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:695
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: