From f556e4b4664e9774b664ab40d0134218e5f172dd Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 12 Jun 2012 09:09:06 +0000 Subject: [PATCH] Add GEOMETRYCOLLECTION input support for ST_MakeValid (#1719) git-svn-id: http://svn.osgeo.org/postgis/trunk@9892 b70326c6-7e19-0410-871a-916f4a2858ee --- NEWS | 1 + liblwgeom/cunit/cu_clean.c | 19 ++++++++++ liblwgeom/lwgeom_geos_clean.c | 66 +++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/NEWS b/NEWS index 8d05901aa..2b637dd34 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PostGIS 2.1.0 - ST_Raster2WorldCoord, ST_World2RasterCoord (Bborie Park / UC Davis) - Tiger Geocoder - Tiger 2011 loader (Regina Obe / Paragon Corporation) Funded by Hunter Systems Group + - GEOMETRYCOLLECTION support for ST_MakeValid (Sandro Santilli / Vizzuality) * Enhancements * diff --git a/liblwgeom/cunit/cu_clean.c b/liblwgeom/cunit/cu_clean.c index 367659509..be771db8c 100644 --- a/liblwgeom/cunit/cu_clean.c +++ b/liblwgeom/cunit/cu_clean.c @@ -21,6 +21,7 @@ static void test_lwgeom_make_valid(void) #if POSTGIS_GEOS_VERSION >= 33 LWGEOM *gin, *gout; int ret; + char *ewkt; /* Because i don't trust that much prior tests... ;) */ cu_error_msg_reset(); @@ -42,6 +43,24 @@ static void test_lwgeom_make_valid(void) lwgeom_free(gout); lwgeom_free(gin); + + gin = lwgeom_from_wkt( +"GEOMETRYCOLLECTION(LINESTRING(0 0, 0 0), POLYGON((0 0, 10 10, 10 0, 0 10, 0 0)), LINESTRING(10 0, 10 10))", + LW_PARSER_CHECK_NONE); + CU_ASSERT(gin); + + gout = lwgeom_make_valid(gin); + CU_ASSERT(gout); + + ewkt = lwgeom_to_ewkt(gout); + printf("c = %s\n", ewkt); + CU_ASSERT_STRING_EQUAL(ewkt, +"GEOMETRYCOLLECTION(POINT(0 0),MULTIPOLYGON(((5 5,0 0,0 10,5 5)),((5 5,10 10,10 0,5 5))),LINESTRING(10 0,10 10))"); + lwfree(ewkt); + + lwgeom_free(gout); + lwgeom_free(gin); + #endif /* POSTGIS_GEOS_VERSION >= 33 */ } diff --git a/liblwgeom/lwgeom_geos_clean.c b/liblwgeom/lwgeom_geos_clean.c index 887fc745c..f0ec20faa 100644 --- a/liblwgeom/lwgeom_geos_clean.c +++ b/liblwgeom/lwgeom_geos_clean.c @@ -613,6 +613,7 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) /* cleanup and throw */ GEOSGeom_destroy(geos_cut_edges); GEOSGeom_destroy(geos_area); + /* TODO: Shouldn't this be an lwerror ? */ lwnotice("GEOSDifference() threw an error: %s", lwgeom_geos_errmsg); return NULL; @@ -664,6 +665,7 @@ LWGEOM_GEOS_makeValidPolygon(const GEOSGeometry* gin) if ( ! gout ) /* an exception again */ { /* cleanup and throw */ + /* TODO: Shouldn't this be an lwerror ? */ lwnotice("GEOSGeom_createCollection() threw an error: %s", lwgeom_geos_errmsg); /* TODO: cleanup! */ @@ -792,6 +794,58 @@ LWGEOM_GEOS_makeValidMultiLine(const GEOSGeometry* gin) return gout; } +static GEOSGeometry* LWGEOM_GEOS_makeValid(const GEOSGeometry*); + +/* + * We expect initGEOS being called already. + * Will return NULL on error (expect error handler being called by then) + */ +static GEOSGeometry* +LWGEOM_GEOS_makeValidCollection(const GEOSGeometry* gin) +{ + int nvgeoms; + GEOSGeometry **vgeoms; + GEOSGeom gout; + unsigned int i; + + nvgeoms = GEOSGetNumGeometries(gin); + if ( nvgeoms == -1 ) { + lwerror("GEOSGetNumGeometries: %s", lwgeom_geos_errmsg); + return 0; + } + + vgeoms = lwalloc( sizeof(GEOSGeometry*) * nvgeoms ); + if ( ! vgeoms ) { + lwerror("LWGEOM_GEOS_makeValidCollection: out of memory"); + return 0; + } + + for ( i=0; i