]> granicus.if.org Git - postgis/commitdiff
Split-line-by-line: handle overlap cases by raising an exception
authorSandro Santilli <strk@keybit.net>
Sat, 13 Mar 2010 11:16:53 +0000 (11:16 +0000)
committerSandro Santilli <strk@keybit.net>
Sat, 13 Mar 2010 11:16:53 +0000 (11:16 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@5434 b70326c6-7e19-0410-871a-916f4a2858ee

postgis/lwgeom_geos_split.c
regress/split.sql
regress/split_expected

index 246c98fb9a1c517f89db580f1b73a6e0db3130b2..fc49837b0811cf584f1fecbad38fd37246bd42ff 100644 (file)
@@ -59,7 +59,7 @@ lwline_split_by_line(LWLINE* lwline_in, LWLINE* blade_in)
 
        /* Possible outcomes:
         *
-        *  1. The lines do not cross (touch != cross)
+        *  1. The lines do not cross or overlap 
         *      -> Return a collection with single element
         *  2. The lines cross
         *      -> Return a collection 2 elements:
@@ -81,13 +81,42 @@ lwline_split_by_line(LWLINE* lwline_in, LWLINE* blade_in)
                return NULL;
        }
        gdiff = GEOSDifference(g1,g2);
-       GEOSGeom_destroy(g1);
        GEOSGeom_destroy(g2);
        if (gdiff == NULL) {
+               GEOSGeom_destroy(g1);
                lwerror("GEOSDifference: %s", lwgeom_geos_errmsg);
                return NULL;
        }
 
+       /* If we lost any point, raise an exception */
+       g2 = GEOSDifference(g1, gdiff);
+       if (gdiff == NULL) {
+               GEOSGeom_destroy(g1);
+               lwerror("GEOSDifference (check): %s", lwgeom_geos_errmsg);
+               return NULL;
+       }
+       if ( ! GEOSisEmpty(g2) )
+       {
+               GEOSGeom_destroy(g1);
+               GEOSGeom_destroy(g2);
+               lwerror("Splitter line overlaps input");
+               return NULL;
+       }
+
+/*
+       lwnotice("Difference between original (%s) and split (%s) is not empty (%s)", 
+                       lwgeom_to_ewkt(GEOS2LWGEOM(gdiff, 0),
+                                      PARSER_CHECK_NONE),
+                       lwgeom_to_ewkt(GEOS2LWGEOM(g1, 0),
+                                      PARSER_CHECK_NONE),
+                       lwgeom_to_ewkt(GEOS2LWGEOM(g2, 0),
+                                      PARSER_CHECK_NONE));
+*/
+
+       GEOSGeom_destroy(g1);
+       GEOSGeom_destroy(g2);
+
+
        diff = GEOS2LWGEOM(gdiff, TYPE_HASZ(lwline_in->type));
        GEOSGeom_destroy(gdiff);
        if (NULL == diff) {
index afad002cbf722d43bbb9b06cc42e23ab7577cc3a..022df6c1aaf4692a5c2bcdeb3069e00c315acb39 100644 (file)
@@ -20,8 +20,13 @@ select '4', st_asewkt(ST_SplitGeometry('SRID=10;LINESTRING(0 0, 10 0)', 'SRID=10
 -- Split line by touching line
 select '5', st_asewkt(ST_SplitGeometry('SRID=10;LINESTRING(0 0, 10 0)', 'SRID=10;LINESTRING(10 -5, 10 5)'));
 
--- Split line by intersecting line
+-- Split line by crossing line
 select '6', st_asewkt(ST_SplitGeometry('SRID=10;LINESTRING(0 0, 10 0)', 'SRID=10;LINESTRING(5 -5, 5 5)'));
 
--- Split line by multiply-intersecting line
+-- Split line by multiply-crossing line
 select '7', st_asewkt(ST_SplitGeometry('SRID=10;LINESTRING(0 0, 10 0, 10 10, 0 10, 0 20, 10 20)', 'SRID=10;LINESTRING(5 -5, 5 25)'));
+
+-- Split line by overlapping line (1)
+select '8.1', st_asewkt(ST_SplitGeometry('SRID=10;LINESTRING(0 0, 10 0)', 'SRID=10;LINESTRING(5 0, 20 0)'));
+-- Split line by overlapping line (2)
+select '8.2', st_asewkt(ST_SplitGeometry('SRID=10;LINESTRING(0 0, 10 0)', 'SRID=10;LINESTRING(5 0, 8 0)'));
index 14be28fc5c0a145b1117943aeaaf104409c7f993..5dd2d459e861ea24598d7108ad72a278d74acc71 100644 (file)
@@ -8,3 +8,5 @@ ERROR:  Operation on mixed SRID geometries
 5|SRID=10;GEOMETRYCOLLECTION(LINESTRING(0 0,10 0))
 6|SRID=10;GEOMETRYCOLLECTION(LINESTRING(0 0,5 0),LINESTRING(5 0,10 0))
 7|SRID=10;GEOMETRYCOLLECTION(LINESTRING(0 0,5 0),LINESTRING(5 0,10 0,10 10,5 10),LINESTRING(5 10,0 10,0 20,5 20),LINESTRING(5 20,10 20))
+ERROR:  Splitter line overlaps input
+ERROR:  Splitter line overlaps input