Schema
Owner
postgres
Descriptions
args: toponame, aline - Adds a linestring edge to the edge table and associated start and end points to the point nodes table of the specified topology schema using the specified linestring geometry and returns the edgeid of the new (or existing) edge.
Options
Option | Value |
---|---|
Returns |
integer |
Language |
|
Parameters |
atopology varchar aline public.geometry |
Definition
CREATE OR REPLACE FUNCTION topology.addedge (
atopology varchar,
aline public.geometry
)
RETURNS integer AS
$span$
DECLARE
edgeid int;
rec RECORD;
ix geometry;
BEGIN
--
-- Atopology and apoint are required
--
IF atopology IS NULL OR aline IS NULL THEN
RAISE EXCEPTION 'Invalid null argument';
END IF;
--
-- Aline must be a linestring
--
IF substring(geometrytype(aline), 1, 4) != 'LINE'
THEN
RAISE EXCEPTION 'Edge geometry must be a linestring';
END IF;
--
-- Check there's no face registered in the topology
--
FOR rec IN EXECUTE 'SELECT count(face_id) FROM '
|| quote_ident(atopology) || '.face '
|| ' WHERE face_id != 0 LIMIT 1'
LOOP
IF rec.count > 0 THEN
RAISE EXCEPTION 'AddEdge can only be used against topologies with no faces defined';
END IF;
END LOOP;
--
-- Check if the edge crosses an existing node
--
FOR rec IN EXECUTE 'SELECT node_id FROM '
|| quote_ident(atopology) || '.node '
|| 'WHERE ST_Crosses($1, geom)'
USING aline
LOOP
RAISE EXCEPTION 'Edge crosses node %', rec.node_id;
END LOOP;
--
-- Check if the edge intersects an existing edge
-- on anything but endpoints
--
-- Following DE-9 Intersection Matrix represent
-- the only relation we accept.
--
-- F F 1
-- F * *
-- 1 * 2
--
-- Example1: linestrings touching at one endpoint
-- FF1 F00 102
-- FF1 F** 1*2 <-- our match
--
-- Example2: linestrings touching at both endpoints
-- FF1 F0F 1F2
-- FF1 F** 1*2 <-- our match
--
FOR rec IN EXECUTE 'SELECT edge_id, geom, ST_Relate($1, geom, 2) as im FROM '
|| quote_ident(atopology) || '.edge WHERE $1 && geom'
USING aline
LOOP
IF ST_RelateMatch(rec.im, 'FF1F**1*2') THEN
CONTINUE; -- no interior intersection
END IF;
-- Reuse an EQUAL edge (be it closed or not)
IF ST_RelateMatch(rec.im, '1FFF*FFF2') THEN
RETURN rec.edge_id;
END IF;
-- WARNING: the constructive operation might throw an exception
BEGIN
ix = ST_Intersection(rec.geom, aline);
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Could not compute intersection between input edge (%) and edge % (%)', aline::text, rec.edge_id, rec.geom::text;
END;
RAISE EXCEPTION 'Edge intersects (not on endpoints) with existing edge % at or near point %', rec.edge_id, ST_AsText(ST_PointOnSurface(ix));
END LOOP;
--
-- Get new edge id from sequence
--
FOR rec IN EXECUTE 'SELECT nextval(' ||
quote_literal(
quote_ident(atopology) || '.edge_data_edge_id_seq'
) || ')'
LOOP
edgeid = rec.nextval;
END LOOP;
--
-- Insert the new row
--
EXECUTE 'INSERT INTO '
|| quote_ident(atopology)
|| '.edge(edge_id, start_node, end_node, '
|| 'next_left_edge, next_right_edge, '
|| 'left_face, right_face, '
|| 'geom) '
|| ' VALUES('
-- edge_id
|| edgeid ||','
-- start_node
|| 'topology.addNode('
|| quote_literal(atopology)
|| ', ST_StartPoint($1)), '
-- end_node
|| 'topology.addNode('
|| quote_literal(atopology)
|| ', ST_EndPoint($1)), '
-- next_left_edge
|| -edgeid ||','
-- next_right_edge
|| edgeid ||','
-- left_face
|| '0,'
-- right_face
|| '0,'
-- geom
|| '$1)'
USING aline;
RETURN edgeid;
END
$span$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
COMMENT ON FUNCTION topology.addedge(atopology varchar, aline public.geometry)
IS 'args: toponame, aline - Adds a linestring edge to the edge table and associated start and end points to the point nodes table of the specified topology schema using the specified linestring geometry and returns the edgeid of the new (or existing) edge.';
This file was generated with SQL Manager for PostgreSQL (www.pgsqlmanager.com) at 13/03/2014 13:23 |