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

◆ lwgeom_make_valid_params()

LWGEOM * lwgeom_make_valid_params ( LWGEOM geom,
char *  make_valid_params 
)

Definition at line 293 of file liblwgeom/lwgeom_geos_clean.c.

294{
295 int is3d;
296 GEOSGeom geosgeom;
297 GEOSGeometry* geosout;
298 LWGEOM* lwgeom_out;
299
300 LWDEBUG(1, "lwgeom_make_valid enter");
301
302 is3d = FLAGS_GET_Z(lwgeom_in->flags);
303
304 /*
305 * Step 1 : try to convert to GEOS, if impossible, clean that up first
306 * otherwise (adding only duplicates of existing points)
307 */
308
310
311 lwgeom_out = lwgeom_make_geos_friendly(lwgeom_in);
312 if (!lwgeom_out) lwerror("Could not make a geos friendly geometry out of input");
313
314 LWDEBUGF(4, "Input geom %p made GEOS-valid as %p", lwgeom_in, lwgeom_out);
315
316 geosgeom = LWGEOM2GEOS(lwgeom_out, 1);
317 if ( lwgeom_in != lwgeom_out ) {
318 lwgeom_free(lwgeom_out);
319 }
320 if (!geosgeom)
321 {
322 lwerror("Couldn't convert POSTGIS geom to GEOS: %s", lwgeom_geos_errmsg);
323 return NULL;
324 }
325 else
326 {
327 LWDEBUG(4, "geom converted to GEOS");
328 }
329
330#if POSTGIS_GEOS_VERSION < 31000
331 geosout = GEOSMakeValid(geosgeom);
332#else
333 if (!make_valid_params) {
334 geosout = GEOSMakeValid(geosgeom);
335 }
336 else {
337 /*
338 * Set up a parameters object for this
339 * make valid operation before calling
340 * it
341 */
342 const char *value;
343 char *param_list[OPTION_LIST_SIZE];
344 char param_list_text[OPTION_LIST_SIZE];
345 strncpy(param_list_text, make_valid_params, OPTION_LIST_SIZE-1);
346 param_list_text[OPTION_LIST_SIZE-1] = '\0'; /* ensure null-termination */
347 memset(param_list, 0, sizeof(param_list));
348 option_list_parse(param_list_text, param_list);
349 GEOSMakeValidParams *params = GEOSMakeValidParams_create();
350 value = option_list_search(param_list, "method");
351 if (value) {
352 if (strcasecmp(value, "linework") == 0) {
353 GEOSMakeValidParams_setMethod(params, GEOS_MAKE_VALID_LINEWORK);
354 }
355 else if (strcasecmp(value, "structure") == 0) {
356 GEOSMakeValidParams_setMethod(params, GEOS_MAKE_VALID_STRUCTURE);
357 }
358 else
359 {
360 GEOSMakeValidParams_destroy(params);
361 lwerror("Unsupported value for 'method', '%s'. Use 'linework' or 'structure'.", value);
362 }
363 }
364 value = option_list_search(param_list, "keepcollapsed");
365 if (value) {
366 if (strcasecmp(value, "true") == 0) {
367 GEOSMakeValidParams_setKeepCollapsed(params, 1);
368 }
369 else if (strcasecmp(value, "false") == 0) {
370 GEOSMakeValidParams_setKeepCollapsed(params, 0);
371 }
372 else
373 {
374 GEOSMakeValidParams_destroy(params);
375 lwerror("Unsupported value for 'keepcollapsed', '%s'. Use 'true' or 'false'", value);
376 }
377 }
378 geosout = GEOSMakeValidWithParams(geosgeom, params);
379 GEOSMakeValidParams_destroy(params);
380 }
381#endif
382 GEOSGeom_destroy(geosgeom);
383 if (!geosout) return NULL;
384
385 lwgeom_out = GEOS2LWGEOM(geosout, is3d);
386 GEOSGeom_destroy(geosout);
387
388 if (lwgeom_is_collection(lwgeom_in) && !lwgeom_is_collection(lwgeom_out))
389 {
390 LWGEOM** ogeoms = lwalloc(sizeof(LWGEOM*));
391 LWGEOM* ogeom;
392 LWDEBUG(3, "lwgeom_make_valid: forcing multi");
393 /* NOTE: this is safe because lwgeom_out is surely not lwgeom_in or
394 * otherwise we couldn't have a collection and a non-collection */
395 assert(lwgeom_in != lwgeom_out);
396 ogeoms[0] = lwgeom_out;
398 MULTITYPE[lwgeom_out->type], lwgeom_out->srid, lwgeom_out->bbox, 1, ogeoms);
399 lwgeom_out->bbox = NULL;
400 lwgeom_out = ogeom;
401 }
402
403 lwgeom_out->srid = lwgeom_in->srid;
404 return lwgeom_out;
405}
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
void lwgeom_geos_error(const char *fmt,...)
void(*) LWGEOM GEOS2LWGEOM)(const GEOSGeometry *geom, uint8_t want3d)
static LWGEOM * lwgeom_make_geos_friendly(LWGEOM *geom)
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
void * lwalloc(size_t size)
Definition lwutil.c:227
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM contains sub-geometries or not This basically just checks that the struct ...
Definition lwgeom.c:1125
uint8_t MULTITYPE[NUMTYPES]
Look-up for the correct MULTI* type promotion for singleton types.
Definition lwgeom.c:382
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
int value
Definition genraster.py:62
const char * option_list_search(char **olist, const char *key)
Returns null if the key cannot be found.
Definition optionlist.c:54
void option_list_parse(char *input, char **olist)
option_list is a null-terminated list of strings, where every odd string is a key and every even stri...
Definition optionlist.c:86
#define OPTION_LIST_SIZE
Definition optionlist.h:31
uint8_t type
Definition liblwgeom.h:462
GBOX * bbox
Definition liblwgeom.h:458
int32_t srid
Definition liblwgeom.h:460

References LWGEOM::bbox, LWGEOM::flags, FLAGS_GET_Z, lwalloc(), lwcollection_construct(), LWDEBUG, LWDEBUGF, lwerror(), LWGEOM2GEOS(), lwgeom_free(), lwgeom_geos_errmsg, lwgeom_geos_error(), lwgeom_is_collection(), lwgeom_make_geos_friendly(), MULTITYPE, option_list_parse(), option_list_search(), OPTION_LIST_SIZE, LWGEOM::srid, and LWGEOM::type.

Referenced by lwgeom_make_valid(), and ST_MakeValid().

Here is the call graph for this function:
Here is the caller graph for this function: