]> granicus.if.org Git - postgis/commitdiff
topology.AddNode: add 2 additional optional arguments to allow splitting edges and...
authorSandro Santilli <strk@keybit.net>
Sat, 31 Dec 2011 09:47:26 +0000 (09:47 +0000)
committerSandro Santilli <strk@keybit.net>
Sat, 31 Dec 2011 09:47:26 +0000 (09:47 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8627 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/populate.sql
topology/test/regress/addnode.sql
topology/test/regress/addnode_expected

index 12b36971f7bd5cc30a31acd0def01b97d83241a8..cf89137fd72a9154ed171e701876411ace9359b4 100644 (file)
@@ -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.
 --
 -- 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)
index cc5ed9730c1d1fbb9da495633218cb05bb9ea0ea..02e64ecba77d55caec88bd4d3a50158f8a603646 100644 (file)
@@ -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;
 
index 1967cbb862ee32c400ad88f094fed0463301770e..8ecdd26f67c8f1b6fbaae207f8d62bc1ed6adc36 100644 (file)
@@ -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