From 8f010b34dfec62b85bb62fbec96b8fb7cfb17342 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 24 May 2011 07:04:43 +0000 Subject: [PATCH] ST_AddIsoEdge: tell that a node is isolated by only looking at containing_face rather than recomputing it. Closes ticket #978. [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7223 b70326c6-7e19-0410-871a-916f4a2858ee --- topology/sql/sqlmm.sql | 80 ++++++-------------- topology/test/regress/st_addisoedge.sql | 7 ++ topology/test/regress/st_addisoedge_expected | 3 + 3 files changed, 35 insertions(+), 55 deletions(-) diff --git a/topology/sql/sqlmm.sql b/topology/sql/sqlmm.sql index cbe8bd687..bb2a24157 100644 --- a/topology/sql/sqlmm.sql +++ b/topology/sql/sqlmm.sql @@ -1570,6 +1570,13 @@ BEGIN 'SQL/MM Spatial exception - null argument'; END IF; + -- NOT IN THE SPECS: + -- A closed edge is never isolated (as it forms a face) + IF anode = anothernode THEN + RAISE EXCEPTION + 'Closed edges would not be isolated, try ST_AddEdgeNewFaces'; + END IF; + -- -- Acurve must be a LINESTRING -- @@ -1580,12 +1587,11 @@ BEGIN END IF; -- - -- Acurve must be a simple + -- Acurve must be simple -- IF NOT ST_IsSimple(acurve) THEN - RAISE EXCEPTION - 'SQL/MM Spatial exception - curve not simple'; + RAISE EXCEPTION 'SQL/MM Spatial exception - curve not simple'; END IF; -- @@ -1603,11 +1609,17 @@ BEGIN WHERE node_id = ' || anode || ' OR node_id = ' || anothernode LOOP - IF count > 0 AND aface != rec.containing_face THEN - RAISE EXCEPTION - 'SQL/MM Spatial exception - nodes in different faces'; - ELSE + + IF rec.containing_face IS NULL THEN + RAISE EXCEPTION 'SQL/MM Spatial exception - not isolated node'; + END IF; + + IF aface IS NULL THEN aface := rec.containing_face; + ELSE + IF aface != rec.containing_face THEN + RAISE EXCEPTION 'SQL/MM Spatial exception - nodes in different faces'; + END IF; END IF; -- Get nodes geom @@ -1620,57 +1632,13 @@ BEGIN count = count+1; END LOOP; + + -- TODO: don't need count, can do with snodegeom/enodegeom instead.. IF count < 2 THEN - IF count = 1 AND anode = anothernode THEN - RAISE EXCEPTION - 'Closed edges would not be isolated, try ST_AddEdgeNewFaces'; - ELSE - RAISE EXCEPTION - 'SQL/MM Spatial exception - non-existent node'; - END IF; + RAISE EXCEPTION 'SQL/MM Spatial exception - non-existent node'; END IF; - -- - -- Check nodes isolation. - -- - FOR rec IN EXECUTE 'SELECT edge_id FROM ' - || quote_ident(atopology) || '.edge_data ' || - ' WHERE start_node = ' || anode || - ' OR end_node = ' || anode || - ' OR start_node = ' || anothernode || - ' OR end_node = ' || anothernode - LOOP - RAISE EXCEPTION - 'SQL/MM Spatial exception - not isolated node'; - END LOOP; - - -- - -- Check acurve to be within endpoints containing face - -- (unless it is the world face, I suppose) - -- - IF aface IS NOT NULL THEN - - -- - -- Extract endpoints face geometry - -- - FOR rec IN EXECUTE 'SELECT topology.ST_GetFaceGeometry(' - || quote_literal(atopology) || - ',' || aface || ') as face' - LOOP - face := rec.face; - END LOOP; - - -- - -- Check acurve to be within face - -- - IF NOT ST_Within(acurve, face) THEN - RAISE EXCEPTION - 'SQL/MM Spatial exception - geometry not within face.'; - END IF; - - END IF; - -- -- l) Check that start point of acurve match start node -- geoms. @@ -1727,7 +1695,9 @@ BEGIN END LOOP; -- TODO: this should likely be an exception instead ! - IF aface IS NULL THEN aface := 0; END IF; + IF aface IS NULL THEN + aface := 0; + END IF; -- -- Insert the new row diff --git a/topology/test/regress/st_addisoedge.sql b/topology/test/regress/st_addisoedge.sql index 7121876aa..4b3f066c0 100644 --- a/topology/test/regress/st_addisoedge.sql +++ b/topology/test/regress/st_addisoedge.sql @@ -15,6 +15,8 @@ INSERT INTO tt.node (containing_face, geom) VALUES (0, 'POINT(10 10)') RETURNING 'N' || node_id; -- 5 INSERT INTO tt.node (containing_face, geom) VALUES (0, 'POINT(20 10)') RETURNING 'N' || node_id; -- 6 +INSERT INTO tt.node (containing_face, geom) VALUES + (null, 'POINT(30 10)') RETURNING 'N' || node_id; -- 7 -- null input SELECT topology.ST_AddIsoEdge('tt', 1, 2, NULL); @@ -61,6 +63,11 @@ SELECT topology.ST_AddIsoEdge('tt', SELECT topology.ST_AddIsoEdge('tt', 3, 3, 'LINESTRING(5 0, 4 -2, 6 -2, 5 0)'); +-- Not isolated edge (one of the endpoints has [bogusly] containin_face=null) +-- See http://trac.osgeo.org/postgis/ticket/978 +SELECT topology.ST_AddIsoEdge('tt', 6, 7, 'LINESTRING(20 10, 30 10)'); + + -- Edge intersection (geometry intersects an edge) SELECT topology.ST_AddIsoEdge('tt', 3, 6, 'LINESTRING(5 0, 20 10)'); diff --git a/topology/test/regress/st_addisoedge_expected b/topology/test/regress/st_addisoedge_expected index e42bdf0bc..182dc6ae7 100644 --- a/topology/test/regress/st_addisoedge_expected +++ b/topology/test/regress/st_addisoedge_expected @@ -5,6 +5,7 @@ N3 N4 N5 N6 +N7 ERROR: SQL/MM Spatial exception - null argument ERROR: SQL/MM Spatial exception - null argument ERROR: SQL/MM Spatial exception - null argument @@ -23,8 +24,10 @@ N3|0 N4| N5| N6|0 +N7| ERROR: SQL/MM Spatial exception - not isolated node ERROR: SQL/MM Spatial exception - not isolated node ERROR: Closed edges would not be isolated, try ST_AddEdgeNewFaces +ERROR: SQL/MM Spatial exception - not isolated node ERROR: SQL/MM Spatial exception - geometry intersects an edge Topology 'tt' dropped -- 2.50.1