383 GEOSGeom geos_cut_edges, geos_area, collapse_points;
384 GEOSGeometry *vgeoms[3];
385 unsigned int nvgeoms=0;
387 assert (GEOSGeomTypeId(gin) == GEOS_POLYGON ||
388 GEOSGeomTypeId(gin) == GEOS_MULTIPOLYGON);
390 geos_bound = GEOSBoundary(gin);
391 if ( NULL == geos_bound )
402 #ifdef LWGEOM_PROFILE_MAKEVALID 403 lwnotice(
"ST_MakeValid: noding lines");
408 if ( NULL == geos_cut_edges )
410 GEOSGeom_destroy(geos_bound);
421 #ifdef LWGEOM_PROFILE_MAKEVALID 422 lwnotice(
"ST_MakeValid: extracting unique points from bounds");
425 pi = GEOSGeom_extractUniquePoints(geos_bound);
428 GEOSGeom_destroy(geos_bound);
429 lwnotice(
"GEOSGeom_extractUniquePoints(): %s",
435 "Boundaries input points %s",
438 #ifdef LWGEOM_PROFILE_MAKEVALID 439 lwnotice(
"ST_MakeValid: extracting unique points from cut_edges");
442 po = GEOSGeom_extractUniquePoints(geos_cut_edges);
445 GEOSGeom_destroy(geos_bound);
446 GEOSGeom_destroy(pi);
447 lwnotice(
"GEOSGeom_extractUniquePoints(): %s",
453 "Boundaries output points %s",
456 #ifdef LWGEOM_PROFILE_MAKEVALID 457 lwnotice(
"ST_MakeValid: find collapse points");
460 collapse_points = GEOSDifference(pi, po);
461 if ( NULL == collapse_points )
463 GEOSGeom_destroy(geos_bound);
464 GEOSGeom_destroy(pi);
465 GEOSGeom_destroy(po);
471 "Collapse points: %s",
474 #ifdef LWGEOM_PROFILE_MAKEVALID 475 lwnotice(
"ST_MakeValid: cleanup(1)");
478 GEOSGeom_destroy(pi);
479 GEOSGeom_destroy(po);
481 GEOSGeom_destroy(geos_bound);
484 "Noded Boundaries: %s",
488 geos_area = GEOSGeom_createEmptyPolygon();
492 GEOSGeom_destroy(geos_cut_edges);
502 while (GEOSGetNumGeometries(geos_cut_edges))
504 GEOSGeometry* new_area=0;
505 GEOSGeometry* new_area_bound=0;
506 GEOSGeometry* symdif=0;
507 GEOSGeometry* new_cut_edges=0;
509 #ifdef LWGEOM_PROFILE_MAKEVALID 510 lwnotice(
"ST_MakeValid: building area from %d edges", GEOSGetNumGeometries(geos_cut_edges));
520 GEOSGeom_destroy(geos_cut_edges);
521 GEOSGeom_destroy(geos_area);
522 lwnotice(
"LWGEOM_GEOS_buildArea() threw an error: %s",
527 if ( GEOSisEmpty(new_area) )
530 GEOSGeom_destroy(new_area);
538 #ifdef LWGEOM_PROFILE_MAKEVALID 539 lwnotice(
"ST_MakeValid: ring built with %d cut edges, saving boundaries", GEOSGetNumGeometries(geos_cut_edges));
546 new_area_bound = GEOSBoundary(new_area);
547 if ( ! new_area_bound )
551 lwnotice(
"GEOSBoundary('%s') threw an error: %s",
554 GEOSGeom_destroy(new_area);
555 GEOSGeom_destroy(geos_area);
559 #ifdef LWGEOM_PROFILE_MAKEVALID 560 lwnotice(
"ST_MakeValid: running SymDifference with new area");
566 symdif = GEOSSymDifference(geos_area, new_area);
569 GEOSGeom_destroy(geos_cut_edges);
570 GEOSGeom_destroy(new_area);
571 GEOSGeom_destroy(new_area_bound);
572 GEOSGeom_destroy(geos_area);
573 lwnotice(
"GEOSSymDifference() threw an error: %s",
578 GEOSGeom_destroy(geos_area);
579 GEOSGeom_destroy(new_area);
594 #ifdef LWGEOM_PROFILE_MAKEVALID 595 lwnotice(
"ST_MakeValid: computing new cut_edges (GEOSDifference)");
598 new_cut_edges = GEOSDifference(geos_cut_edges, new_area_bound);
599 GEOSGeom_destroy(new_area_bound);
600 if ( ! new_cut_edges )
603 GEOSGeom_destroy(geos_cut_edges);
604 GEOSGeom_destroy(geos_area);
606 lwnotice(
"GEOSDifference() threw an error: %s",
610 GEOSGeom_destroy(geos_cut_edges);
611 geos_cut_edges = new_cut_edges;
614 #ifdef LWGEOM_PROFILE_MAKEVALID 615 lwnotice(
"ST_MakeValid: final checks");
618 if ( ! GEOSisEmpty(geos_area) )
620 vgeoms[nvgeoms++] = geos_area;
624 GEOSGeom_destroy(geos_area);
627 if ( ! GEOSisEmpty(geos_cut_edges) )
629 vgeoms[nvgeoms++] = geos_cut_edges;
633 GEOSGeom_destroy(geos_cut_edges);
636 if ( ! GEOSisEmpty(collapse_points) )
638 vgeoms[nvgeoms++] = collapse_points;
642 GEOSGeom_destroy(collapse_points);
653 gout = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, vgeoms, nvgeoms);
658 lwnotice(
"GEOSGeom_createCollection() threw an error: %s",
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, char want3d)
#define LWDEBUGF(level, msg,...)
static GEOSGeometry * LWGEOM_GEOS_nodeLines(const GEOSGeometry *lines)
GEOSGeometry * LWGEOM_GEOS_buildArea(const GEOSGeometry *geom_in)