Schema
Owner
postgres
Descriptions
There is no description for function _st_addfacesplit
Options
Option | Value |
---|---|
Returns |
integer |
Language |
|
Parameters |
atopology varchar anedge integer oface integer mbr_only boolean |
Definition
CREATE OR REPLACE FUNCTION topology._st_addfacesplit (
atopology varchar,
anedge integer,
oface integer,
mbr_only boolean
)
RETURNS integer AS
$span$
DECLARE
fan RECORD;
newface INTEGER;
sql TEXT;
isccw BOOLEAN;
ishole BOOLEAN;
BEGIN
IF oface = 0 AND mbr_only THEN
RETURN NULL;
END IF;
SELECT null::int[] as newring_edges,
null::geometry as shell
INTO fan;
SELECT array_agg(edge)
FROM topology.getringedges(atopology, anedge)
INTO STRICT fan.newring_edges;
-- You can't get to the other side of an edge forming a ring
IF fan.newring_edges @> ARRAY[-anedge] THEN
RETURN 0;
END IF;
sql := 'WITH ids as ( select row_number() over () as seq, edge '
|| 'from unnest($1) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 '
|| 'THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
|| quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) '
|| 'ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g';
EXECUTE sql INTO fan.shell USING
fan.newring_edges
;
isccw := NOT ST_OrderingEquals(fan.shell, ST_ForceRHR(fan.shell));
IF oface = 0 THEN
IF NOT isccw THEN
RETURN NULL;
END IF;
END IF;
IF mbr_only AND oface != 0 THEN
-- Update old face mbr (nothing to do if we're opening an hole)
IF isccw THEN -- {
sql := 'UPDATE '
|| quote_ident(atopology)
|| '.face SET mbr = $1 WHERE face_id = $2';
EXECUTE sql USING
ST_Envelope(fan.shell),
oface
;
END IF; -- }
RETURN NULL;
END IF;
IF oface != 0 AND NOT isccw THEN -- {
-- Face created an hole in an outer face
sql := 'INSERT INTO '
|| quote_ident(atopology) || '.face(mbr) SELECT mbr FROM '
|| quote_ident(atopology)
|| '.face WHERE face_id = ' || oface
|| ' RETURNING face_id';
ELSE
sql := 'INSERT INTO '
|| quote_ident(atopology) || '.face(mbr) VALUES ($1) RETURNING face_id';
END IF; -- }
-- Insert new face
EXECUTE sql INTO STRICT newface USING ST_Envelope(fan.shell);
-- Update forward edges
sql := 'UPDATE ' || quote_ident(atopology) ||
'.edge_data SET left_face = $1 WHERE edge_id = ANY($3)'
;
EXECUTE sql USING newface, oface,
array(select +x from unnest(fan.newring_edges) u(x) where x > 0)
;
-- Update backward edges
sql := 'UPDATE ' || quote_ident(atopology) ||
'.edge_data SET right_face = $1 WHERE edge_id = ANY($3)'
;
EXECUTE sql USING newface, oface,
array(select -x from unnest(fan.newring_edges) u(x) where x < 0)
;
IF oface != 0 AND NOT isccw THEN -- {
-- face shrinked, must update all non-contained edges and nodes
ishole := true;
ELSE
ishole := false;
END IF; -- }
-- Update edges bounding the old face
sql := 'UPDATE '
|| quote_ident(atopology)
|| '.edge_data SET left_face = CASE WHEN left_face = $2 THEN $3'
|| ' ELSE left_face END, right_face = CASE WHEN right_face = $2 '
|| ' THEN $3 ELSE right_face END WHERE ( left_face = $2 '
|| ' OR right_face = $2 ) AND NOT edge_id = ANY ($4) AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || '($1 && geom AND _ST_Contains($1'
-- We only need to check a single point, but must not be an endpoint
|| ', ST_LineInterpolatePoint(geom, 0.2)) )';
EXECUTE sql USING fan.shell, oface, newface,
array(select abs(x) from unnest(fan.newring_edges) u(x));
-- Update isolated nodes in new new face
sql := 'UPDATE '
|| quote_ident(atopology) || '.node SET containing_face = $2 '
|| ' WHERE containing_face = $3 AND ';
IF ishole THEN sql := sql || 'NOT '; END IF;
sql := sql || 'ST_Contains($1, geom)';
EXECUTE sql USING fan.shell, newface, oface;
RETURN newface;
END
$span$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
This file was generated with SQL Manager for PostgreSQL (www.pgsqlmanager.com) at 13/03/2014 13:23 |