]> granicus.if.org Git - postgis/commitdiff
ST_MakeValid: don't choke on MULTILINESTRING containing invalid LINESTRING elements
authorSandro Santilli <strk@keybit.net>
Mon, 3 May 2010 15:59:16 +0000 (15:59 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 3 May 2010 15:59:16 +0000 (15:59 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@5601 b70326c6-7e19-0410-871a-916f4a2858ee

postgis/lwgeom_geos_clean.c
regress/clean.sql
regress/clean_expected

index f7796fbb1be9efef11b53ad59e322210ac42c5a2..982fa9c5b6ec5c8ddd617d60041a37528d65fee5 100644 (file)
@@ -640,14 +640,15 @@ LWGEOM_GEOS_makeValidMultiLine(const GEOSGeometry* gin)
        GEOSGeometry* mline_out=0;
        GEOSGeometry* mpoint_out=0;
        GEOSGeometry* gout;
-       uint32 nlines;
+       uint32 nlines, nlines_alloc;
        uint32 npoints=0;
-       uint32 ngeoms=0;
-       uint32 i;
+       uint32 ngeoms=0, nsubgeoms;
+       uint32 i, j;
 
        ngeoms = GEOSGetNumGeometries(gin);
 
-       lines = lwalloc(sizeof(GEOSGeometry*)*ngeoms);
+       nlines_alloc = ngeoms;
+       lines = lwalloc(sizeof(GEOSGeometry*)*nlines_alloc);
        points = lwalloc(sizeof(GEOSGeometry*)*ngeoms);
 
        for (i=0; i<ngeoms; ++i)
@@ -667,6 +668,19 @@ LWGEOM_GEOS_makeValidMultiLine(const GEOSGeometry* gin)
                {
                        lines[nlines++] = vg;
                }
+               else if ( GEOSGeomTypeId(vg) == GEOS_MULTILINESTRING )
+               {
+                 nsubgeoms=GEOSGetNumGeometries(vg); 
+                 nlines_alloc += nsubgeoms;
+                 lines = lwrealloc(lines, sizeof(GEOSGeometry*)*nlines_alloc);
+                 for (j=0; j<nsubgeoms; ++j)
+                 {
+                   const GEOSGeometry* gc = GEOSGetGeometryN(vg, j);
+                   /* NOTE: ownership of the cloned geoms will be
+                    *       taken by final collection */
+                   lines[nlines++] = GEOSGeom_clone(gc);
+                 }
+               }
                else
                {
                        /* NOTE: return from GEOSGeomType will leak
index bdb973463e0df9d98d74e8e09beec737a9b80c06..2b852f5217d72c83a8962d34a1bb77ed430ac167 100644 (file)
@@ -29,6 +29,7 @@ PG    1       SRID=1;0103000000010000000100000000000000000000000000000000000000       SRID=1;PO
 PG     2       SRID=3;LINESTRING(0 0, 0 0)     SRID=3;POINT(0 0)
 PG     3       SRID=43;MULTILINESTRING((0 0, 10 0),(20 20, 20 20))     SRID=43;GEOMETRYCOLLECTION(LINESTRING(0 0, 10 0),POINT(20 20))
 PG     4       SRID=2;MULTIPOLYGON(((5 3, 7 4, 9 5, 11 6, 13 7, 5 3)),((14 14, 14 14, 14 14, 14 14)))  SRID=2;GEOMETRYCOLLECTION(MULTILINESTRING((5 3,7 4),(7 4,9 5),(9 5,11 6),(11 6,13 7)),POINT(14 14))
+PG     5       SRID=4;MULTILINESTRING((5 3 0, 7 4 5, 9 5 3, 11 6 4, 13 7 9, 5 3 0),(14 14 2, 14 14 3, 14 14 4, 14 14 5))       SRID=4;GEOMETRYCOLLECTION(MULTILINESTRING((5 3 0,7 4 3.625),(7 4 3.625,9 5 3.75),(9 5 3.75,11 6 5.375),(11 6 5.375,13 7 9)),POINT(14 14 2))
 \.
 
 -- PG.1 : polygon with single ring with single point in it
index ad1b869d2099502e6115e78ead46cc170f0b6d35..480225c1a98d007953054964df53653acf0faaa8 100644 (file)
@@ -25,3 +25,4 @@ PG|1|t|t|f
 PG|2|t|t|f
 PG|3|t|t|f
 PG|4|t|t|f
+PG|5|t|t|f