From: Sandro Santilli Date: Wed, 3 Oct 2012 06:16:51 +0000 (+0000) Subject: ST_AddEdge*: make update of old face edges more robust (#2025) X-Git-Tag: 2.1.0beta2~593 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bde285f4b39eeb8d8027b78a7dae4f58d996a760;p=postgis ST_AddEdge*: make update of old face edges more robust (#2025) 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 --- diff --git a/topology/sql/sqlmm.sql.in.c b/topology/sql/sqlmm.sql.in.c index 0176de6b5..eb7ef3ac9 100644 --- a/topology/sql/sqlmm.sql.in.c +++ b/topology/sql/sqlmm.sql.in.c @@ -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; diff --git a/topology/test/regress/st_addedgemodface.sql b/topology/test/regress/st_addedgemodface.sql index 6cfe8657c..7c3518847 100644 --- a/topology/test/regress/st_addedgemodface.sql +++ b/topology/test/regress/st_addedgemodface.sql @@ -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 --------------------------------------------------------------------- diff --git a/topology/test/regress/st_addedgemodface_expected b/topology/test/regress/st_addedgemodface_expected index db2da980f..69d18c448 100644 --- a/topology/test/regress/st_addedgemodface_expected +++ b/topology/test/regress/st_addedgemodface_expected @@ -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 diff --git a/topology/test/regress/st_addedgenewfaces.sql b/topology/test/regress/st_addedgenewfaces.sql index eaaa93433..b3b296f1d 100644 --- a/topology/test/regress/st_addedgenewfaces.sql +++ b/topology/test/regress/st_addedgenewfaces.sql @@ -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 --------------------------------------------------------------------- diff --git a/topology/test/regress/st_addedgenewfaces_expected b/topology/test/regress/st_addedgenewfaces_expected index da609ae2d..8fa933c27 100644 --- a/topology/test/regress/st_addedgenewfaces_expected +++ b/topology/test/regress/st_addedgenewfaces_expected @@ -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