1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- PostGIS - Spatial Types for PostgreSQL
-- http://postgis.net
--
-- Copyright (C) 2011 2012 Sandro Santilli <strk@kbt.io>
--
-- This is free software; you can redistribute and/or modify it under
-- the terms of the GNU General Public Licence. See the COPYING file.
--
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Developed by Sandro Santilli <strk@kbt.io>
-- for Faunalia (http://www.faunalia.it) with funding from
-- Regione Toscana - Sistema Informativo per la Gestione del Territorio
-- e dell' Ambiente [RT-SIGTA].
-- For the project: "Sviluppo strumenti software per il trattamento di dati
-- geografici basati su QuantumGIS e Postgis (CIG 0494241492)"
--
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--{
--
-- Return a list of edges (sequence, id) resulting by starting from the
-- given edge and following the leftmost turn at each encountered node.
--
-- Edge ids are signed, they are negative if traversed backward.
-- Sequence numbers start with 1.
--
-- Use a negative starting_edge to follow its rigth face rather than
-- left face (to start traversing it in reverse).
--
-- Optionally pass a limit on the number of edges to traverse. This is a
-- safety measure against not-properly linked topologies, where you may
-- end up looping forever (single edge loops edge are detected but longer
-- ones are not). Default is no limit (good luck!)
--
-- GetRingEdges(atopology, anedge, [maxedges])
--
CREATE OR REPLACE FUNCTION topology.GetRingEdges(atopology varchar, anedge int, maxedges int DEFAULT null)
RETURNS SETOF topology.GetFaceEdges_ReturnType
AS
$$
DECLARE
rec RECORD;
retrec topology.GetFaceEdges_ReturnType;
n int;
sql text;
BEGIN
sql := 'WITH RECURSIVE edgering AS ( SELECT '
|| anedge
|| ' as signed_edge_id, edge_id, next_left_edge, next_right_edge FROM '
|| quote_ident(atopology)
|| '.edge_data WHERE edge_id = '
|| abs(anedge)
|| ' UNION '
|| ' SELECT CASE WHEN p.signed_edge_id < 0 THEN p.next_right_edge '
|| ' ELSE p.next_left_edge END, e.edge_id, e.next_left_edge, e.next_right_edge '
|| ' FROM ' || quote_ident(atopology)
|| '.edge_data e, edgering p WHERE e.edge_id = CASE WHEN p.signed_edge_id < 0 '
|| 'THEN abs(p.next_right_edge) ELSE abs(p.next_left_edge) END ) SELECT * FROM edgering';
n := 1;
FOR rec IN EXECUTE sql
LOOP
retrec.sequence := n;
retrec.edge := rec.signed_edge_id;
RETURN NEXT retrec;
n := n + 1;
IF n > maxedges THEN
RAISE EXCEPTION 'Max traversing limit hit: %', maxedges;
END IF;
END LOOP;
END
$$
LANGUAGE 'plpgsql' STABLE;
--} GetRingEdges
|