From 36e109773a1c7d97e92d6132f76ddea243ab9958 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Sat, 13 Mar 2010 11:16:53 +0000 Subject: [PATCH] Split-line-by-line: handle overlap cases by raising an exception git-svn-id: http://svn.osgeo.org/postgis/trunk@5434 b70326c6-7e19-0410-871a-916f4a2858ee --- postgis/lwgeom_geos_split.c | 33 +++++++++++++++++++++++++++++++-- regress/split.sql | 9 +++++++-- regress/split_expected | 2 ++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/postgis/lwgeom_geos_split.c b/postgis/lwgeom_geos_split.c index 246c98fb9..fc49837b0 100644 --- a/postgis/lwgeom_geos_split.c +++ b/postgis/lwgeom_geos_split.c @@ -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) { diff --git a/regress/split.sql b/regress/split.sql index afad002cb..022df6c1a 100644 --- a/regress/split.sql +++ b/regress/split.sql @@ -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)')); diff --git a/regress/split_expected b/regress/split_expected index 14be28fc5..5dd2d459e 100644 --- a/regress/split_expected +++ b/regress/split_expected @@ -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 -- 2.40.0