Commit 1f0cf9a4 authored by Sandro Santilli's avatar Sandro Santilli
Browse files

topology.AddNode: add 2 additional optional arguments to allow splitting edges...

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
parent 531e202f
Loading
Loading
Loading
Loading
+32 −7
Original line number Diff line number Diff line
@@ -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
    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)
+16 −5
Original line number Diff line number Diff line
@@ -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,
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 'p5',  topology.addNode('nodes', 'POINT(0 20)'); -- good
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;

+7 −1
Original line number Diff line number Diff line
@@ -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