]> granicus.if.org Git - postgis/commitdiff
ST_AddEdge*: make update of old face edges more robust (#2025)
authorSandro Santilli <strk@keybit.net>
Wed, 3 Oct 2012 06:16:51 +0000 (06:16 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 3 Oct 2012 06:16:51 +0000 (06:16 +0000)
Include tests for adding an edge that splits an hole in a face
while forming a left ring which constitutes an invalid polygon ring.

Also fixes one case of invalid topology creation (when the formed
ring has a dangling edge but not a new area on the other side).

git-svn-id: http://svn.osgeo.org/postgis/trunk@10365 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/sqlmm.sql.in.c
topology/test/regress/st_addedgemodface.sql
topology/test/regress/st_addedgemodface_expected
topology/test/regress/st_addedgenewfaces.sql
topology/test/regress/st_addedgenewfaces_expected

index 0176de6b5480d6d65d19f0bfb7ee7d336f8a4c4e..eb7ef3ac92cf3463bc44c14b5208872fd639db22 100644 (file)
@@ -3075,7 +3075,7 @@ BEGIN
     ishole := false;
   END IF; -- }
 
-  -- Update edges having new face on the left
+  -- Update edges bounding the old face
   sql := 'UPDATE '
     || quote_ident(atopology)
     || '.edge_data SET left_face = CASE WHEN left_face = '
@@ -3090,9 +3090,11 @@ BEGIN
        )::text )
     || ') AND ';
   IF ishole THEN sql := sql || 'NOT '; END IF;
-  sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+  sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
+    -- We only need to check a single point, but must not be an endpoint
+    || '::geometry, ST_Line_Interpolate_Point(geom, 0.2))';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
-  RAISE DEBUG 'Updating edges binding old face';
+  RAISE DEBUG 'Updating edges bounding the old face';
 #endif
   EXECUTE sql;
 
index 6cfe8657c2b49b82e19524609642651fb1669bd0..7c35188477946d50b04913975a9087ab0700b804 100644 (file)
@@ -430,6 +430,38 @@ SELECT 'T26', 'E'||edge_id, next_left_edge, next_right_edge,
     UNION VALUES (4),(5) )
   ORDER BY edge_id;
 
+--
+-- Split a face closing a ring inside a face
+-- and with the ring containing another edge
+--
+
+INSERT INTO newedge SELECT 27, topology.st_addedgemodface('city_data',
+  5, 6, 'LINESTRING(36 38, 50 38, 57 33)');
+SELECT 'T27', 'E'||edge_id, next_left_edge, next_right_edge,
+  left_face, right_face FROM
+  city_data.edge WHERE edge_id IN ( 
+    SELECT edge_id FROM newedge WHERE id IN (27, 17, 18, 26)
+    UNION VALUES (4),(5) )
+  ORDER BY edge_id;
+
+--
+-- Split a face closing a ring inside a face
+-- and with the left ring containing another edge
+-- and forming an invalid polygon of this shape: <>---<>
+--
+-- See http://trac.osgeo.org/postgis/ticket/2025
+--
+
+INSERT INTO newedge SELECT 28, topology.st_addedgemodface('city_data',
+  7, 7, 'LINESTRING(41 40, 38 40, 41 43, 41 40)');
+SELECT 'T28', 'E'||edge_id, next_left_edge, next_right_edge,
+  left_face, right_face FROM
+  city_data.edge WHERE edge_id IN ( 
+    SELECT edge_id FROM newedge WHERE id IN (26, 27, 28, 17, 18)
+    UNION VALUES (4),(5) )
+  ORDER BY edge_id;
+
+
 ---------------------------------------------------------------------
 -- Check new relations and faces status
 ---------------------------------------------------------------------
@@ -450,6 +482,7 @@ SELECT f.id, r.element_type||':'||r.element_id as comp
 
 SELECT 'F'||face_id, st_astext(mbr) FROM city_data.face ORDER BY face_id;
 
+
 ---------------------------------------------------------------------
 -- Cleanups
 ---------------------------------------------------------------------
index db2da980f692bc92b64aae3a2811203614e5aa72..69d18c4481b9ba72f949fa69f1a1b02fcbec8de4 100644 (file)
@@ -149,6 +149,19 @@ T26|E5|-4|5|32|32
 T26|E43|-44|44|32|0
 T26|E44|-43|43|0|32
 T26|E52|-5|4|32|24
+T27|E4|-52|53|24|33
+T27|E5|-4|5|33|33
+T27|E43|-44|44|33|0
+T27|E44|-43|43|0|33
+T27|E52|-53|4|32|24
+T27|E53|-5|52|33|32
+T28|E4|-52|53|24|34
+T28|E5|-4|54|34|34
+T28|E43|-44|44|34|0
+T28|E44|-43|43|0|34
+T28|E52|-53|4|32|24
+T28|E53|-5|52|34|32
+T28|E54|5|-54|34|33
 F3,F4|{3:3,3:4,3:10,3:16,3:17}
 F5,N4|{1:4,3:5,3:11}
 F0|
@@ -183,5 +196,7 @@ F28|POLYGON((19.5 32.5,19.5 37.5,24.5 37.5,24.5 32.5,19.5 32.5))
 F29|POLYGON((25 30,25 37,29 37,29 30,25 30))
 F30|POLYGON((17 30,17 40,31 40,31 30,17 30))
 F31|POLYGON((19 31,19 38,26 38,26 31,19 31))
-F32|POLYGON((35 25,35 45,63 45,63 25,35 25))
+F32|POLYGON((36 33,36 38,57 38,57 33,36 33))
+F33|POLYGON((38 40,38 43,41 43,41 40,38 40))
+F34|POLYGON((35 25,35 45,63 45,63 25,35 25))
 Topology 'city_data' dropped
index eaaa934334479c4091c247dccf8c0eab7492e6af..b3b296f1d3f623f62b7a9bbd755b27e41e014fc1 100644 (file)
@@ -430,6 +430,37 @@ SELECT 'T26', 'E'||edge_id, next_left_edge, next_right_edge,
     UNION VALUES (4),(5) )
   ORDER BY edge_id;
 
+--
+-- Split a face closing a ring inside a face
+-- and with the ring containing another edge
+--
+
+INSERT INTO newedge SELECT 27, topology.st_addedgenewfaces('city_data',
+  5, 6, 'LINESTRING(36 38, 50 38, 57 33)');
+SELECT 'T27', 'E'||edge_id, next_left_edge, next_right_edge,
+  left_face, right_face FROM
+  city_data.edge WHERE edge_id IN ( 
+    SELECT edge_id FROM newedge WHERE id IN (27, 17, 18, 26)
+    UNION VALUES (4),(5) )
+  ORDER BY edge_id;
+
+--
+-- Split a face closing a ring inside a face
+-- and with the left ring containing another edge
+-- and forming an invalid polygon of this shape: <>---<>
+--
+-- See http://trac.osgeo.org/postgis/ticket/2025
+--
+
+INSERT INTO newedge SELECT 28, topology.st_addedgenewfaces('city_data',
+  7, 7, 'LINESTRING(41 40, 38 40, 41 43, 41 40)');
+SELECT 'T28', 'E'||edge_id, next_left_edge, next_right_edge,
+  left_face, right_face FROM
+  city_data.edge WHERE edge_id IN ( 
+    SELECT edge_id FROM newedge WHERE id IN (26, 27, 28, 17, 18)
+    UNION VALUES (4),(5) )
+  ORDER BY edge_id;
+
 ---------------------------------------------------------------------
 -- Check new relations and faces status
 ---------------------------------------------------------------------
index da609ae2d362493b12a65cf787882e8e054463a9..8fa933c2716ab92ae7b9c32a0a6cc56b7ff857d6 100644 (file)
@@ -149,6 +149,19 @@ T26|E5|-4|5|46|46
 T26|E43|-44|44|46|0
 T26|E44|-43|43|0|46
 T26|E52|-5|4|46|45
+T27|E4|-52|53|45|48
+T27|E5|-4|5|48|48
+T27|E43|-44|44|48|0
+T27|E44|-43|43|0|48
+T27|E52|-53|4|47|45
+T27|E53|-5|52|48|47
+T28|E4|-52|53|45|50
+T28|E5|-4|54|50|50
+T28|E43|-44|44|50|0
+T28|E44|-43|43|0|50
+T28|E52|-53|4|47|45
+T28|E53|-5|52|50|47
+T28|E54|5|-54|50|49
 F3,F4|{3:10,3:11,3:22,3:24,3:25}
 F5,N4|{1:4,3:12,3:13}
 F0|
@@ -183,5 +196,7 @@ F41|POLYGON((19.5 32.5,19.5 37.5,24.5 37.5,24.5 32.5,19.5 32.5))
 F43|POLYGON((17 30,17 40,31 40,31 30,17 30))
 F44|POLYGON((19 31,19 38,26 38,26 31,19 31))
 F45|POLYGON((36 28,36 38,57 38,57 28,36 28))
-F46|POLYGON((35 25,35 45,63 45,63 25,35 25))
+F47|POLYGON((36 33,36 38,57 38,57 33,36 33))
+F49|POLYGON((38 40,38 43,41 43,41 40,38 40))
+F50|POLYGON((35 25,35 45,63 45,63 25,35 25))
 Topology 'city_data' dropped