From 1f0cf9a48dc8493f30fc6fb650fabc15b21a9858 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Sat, 31 Dec 2011 09:47:26 +0000 Subject: [PATCH] topology.AddNode: add 2 additional optional arguments to allow splitting edges and computing containing_face git-svn-id: http://svn.osgeo.org/postgis/trunk@8627 b70326c6-7e19-0410-871a-916f4a2858ee --- topology/sql/populate.sql | 39 +++++++++++++++++++++----- topology/test/regress/addnode.sql | 21 ++++++++++---- topology/test/regress/addnode_expected | 8 +++++- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/topology/sql/populate.sql b/topology/sql/populate.sql index 12b36971f..cf89137fd 100644 --- a/topology/sql/populate.sql +++ b/topology/sql/populate.sql @@ -26,7 +26,7 @@ --{ -- --- AddNode(atopology, point) +-- AddNode(atopology, point, allowEdgeSplitting, setContainingFace) -- -- Add a node primitive to a topology and get its identifier. -- Returns an existing node at the same location, if any. @@ -36,14 +36,15 @@ -- -- The newly added nodes have no containing face. -- --- -CREATE OR REPLACE FUNCTION topology.AddNode(atopology varchar, apoint geometry) +-- }{ +CREATE OR REPLACE FUNCTION topology.AddNode(atopology varchar, apoint geometry, allowEdgeSplitting boolean, setContainingFace boolean DEFAULT false) RETURNS int AS $$ DECLARE nodeid int; rec RECORD; + containing_face int; BEGIN -- -- Atopology and apoint are required @@ -88,9 +89,20 @@ BEGIN || quote_literal(apoint::text) || ', ST_EndPoint(geom))' LOOP - RAISE EXCEPTION 'An edge crosses the given node.'; + IF allowEdgeSplitting THEN + RETURN ST_ModEdgeSplit(atopology, rec.edge_id, apoint); + ELSE + RAISE EXCEPTION 'An edge crosses the given node.'; + END IF; END LOOP; + IF setContainingFace THEN + containing_face := topology.GetFaceByPoint(atopology, apoint, 0); + RAISE DEBUG 'containing face: %', containing_face; + ELSE + containing_face := NULL; + END IF; + -- -- Get new node id from sequence -- @@ -106,9 +118,9 @@ BEGIN -- Insert the new row -- EXECUTE 'INSERT INTO ' || quote_ident(atopology) - || '.node(node_id, geom) - VALUES('||nodeid||','||quote_literal(apoint::text)|| - ')'; + || '.node(node_id, containing_face, geom) + VALUES(' || nodeid || ',' || coalesce(containing_face::text, 'NULL') || ',' + || quote_literal(apoint::text) || ')'; RETURN nodeid; @@ -117,6 +129,19 @@ $$ LANGUAGE 'plpgsql' VOLATILE; --} AddNode +--{ +-- +-- AddNode(atopology, point) +-- +CREATE OR REPLACE FUNCTION topology.AddNode(atopology varchar, apoint geometry) + RETURNS int +AS +$$ + SELECT topology.AddNode($1, $2, false, false); +$$ +LANGUAGE 'sql' VOLATILE; +--} AddNode + --{ -- -- AddEdge(atopology, line) diff --git a/topology/test/regress/addnode.sql b/topology/test/regress/addnode.sql index cc5ed9730..02e64ecba 100644 --- a/topology/test/regress/addnode.sql +++ b/topology/test/regress/addnode.sql @@ -14,17 +14,28 @@ SELECT 'p2b', topology.addNode('nodes', 'POINT(1 0)'); -- Check that adding a node in the middle of an existing edge is refused -- While adding one on the endpoint is fine -INSERT INTO nodes.edge VALUES(1,1,1,1,-1,0,0,'LINESTRING(0 10,10 10)'); +INSERT INTO nodes.edge VALUES(nextval('nodes.edge_data_edge_id_seq'),1,1,1,-1,0,0, + 'LINESTRING(0 10,10 10)'); SELECT 'p3*1', topology.addNode('nodes', 'POINT(5 10)'); -- refused SELECT 'p3', topology.addNode('nodes', 'POINT(0 10)'); -- good SELECT 'p4', topology.addNode('nodes', 'POINT(10 10)'); -- good + +-- Now allow edge splitting: +SELECT 'p5', topology.addNode('nodes', 'POINT(5 10)', true); +-- ... and verify the edge was split +SELECT 'post-p5', edge_id, ST_AsText(geom) FROM nodes.edge ORDER BY edge_id; + + -- And same against a closed edge -INSERT INTO nodes.edge VALUES(2,2,2,2,-2,0,0, - 'LINESTRING(0 20,10 20,10 30, 0 30, 0 20)'); -SELECT 'p5', topology.addNode('nodes', 'POINT(0 20)'); -- good +INSERT INTO nodes.face VALUES(nextval('nodes.face_face_id_seq'), 'POLYGON((0 20, 10 20, 10 30, 0 30, 0 20))'); +INSERT INTO nodes.edge VALUES(nextval('nodes.edge_data_edge_id_seq'),2,2,2,-2,1,0, + 'LINESTRING(0 20,10 20,10 30, 0 30, 0 20)'); +SELECT 'p6', topology.addNode('nodes', 'POINT(0 20)'); -- good --- Check we only have two points, both with unknown containing face +-- Now allow computing containing face: +SELECT 'p7', topology.addNode('nodes', 'POINT(5 25)', false, true); +-- Check all nodes SELECT node_id, containing_face, st_astext(geom) from nodes.node ORDER by node_id; diff --git a/topology/test/regress/addnode_expected b/topology/test/regress/addnode_expected index 1967cbb86..8ecdd26f6 100644 --- a/topology/test/regress/addnode_expected +++ b/topology/test/regress/addnode_expected @@ -7,11 +7,17 @@ ERROR: An edge crosses the given node. p3|3 p4|4 p5|5 +post-p5|1|LINESTRING(0 10,5 10) +post-p5|2|LINESTRING(5 10,10 10) +p6|6 +p7|7 1||POINT(0 0) 2||POINT(1 0) 3||POINT(0 10) 4||POINT(10 10) -5||POINT(0 20) +5||POINT(5 10) +6||POINT(0 20) +7|1|POINT(5 25) Topology 'nodes' dropped t MiX|1 -- 2.50.1