PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ lwgeom_make_valid_params()

LWGEOM* lwgeom_make_valid_params ( LWGEOM lwgeom_in,
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;
397  ogeom = (LWGEOM*)lwcollection_construct(
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)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
#define FLAGS_GET_Z(flags)
Definition: liblwgeom.h:165
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:1097
void * lwalloc(size_t size)
Definition: lwutil.c:227
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
uint8_t MULTITYPE[NUMTYPES]
Look-up for the correct MULTI* type promotion for singleton types.
Definition: lwgeom.c:354
#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
lwflags_t flags
Definition: liblwgeom.h:461

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, LWGEOM::type, and genraster::value.

Referenced by lwgeom_make_valid(), and ST_MakeValid().

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