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