From: Sandro Santilli Date: Wed, 18 May 2011 08:58:34 +0000 (+0000) Subject: topology.GetRingEdges() implementation and test. This is the first real user of next_... X-Git-Tag: 2.0.0alpha1~1626 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=906fd8cd0a82d38e0bc4716fcd1e92505537d158;p=postgis topology.GetRingEdges() implementation and test. This is the first real user of next_left_edge/next_right_edge fields in the edge table. [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7185 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/topology/Makefile.in b/topology/Makefile.in index 72d6e6368..77c82a62a 100644 --- a/topology/Makefile.in +++ b/topology/Makefile.in @@ -42,7 +42,7 @@ endif $(SQL_OBJS): %.in: %.in.c $(CPP) -traditional-cpp $< | grep -v '^#' > $@ -topology.sql.in: sql/sqlmm.sql sql/populate.sql sql/polygonize.sql sql/gml.sql sql/query/getnodebypoint.sql sql/query/getedgebypoint.sql sql/query/getfacebypoint.sql sql/manage/TopologySummary.sql sql/manage/CopyTopology.sql +topology.sql.in: sql/sqlmm.sql sql/populate.sql sql/polygonize.sql sql/gml.sql sql/query/getnodebypoint.sql sql/query/getedgebypoint.sql sql/query/getfacebypoint.sql sql/query/GetRingEdges.sql sql/manage/TopologySummary.sql sql/manage/CopyTopology.sql check: topology.sql $(MAKE) -C test $@ diff --git a/topology/sql/query/GetRingEdges.sql b/topology/sql/query/GetRingEdges.sql new file mode 100644 index 000000000..5514f02c1 --- /dev/null +++ b/topology/sql/query/GetRingEdges.sql @@ -0,0 +1,99 @@ +-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-- +-- PostGIS - Spatial Types for PostgreSQL +-- http://postgis.refractions.net +-- +-- Copyright (C) 2011 Sandro Santilli +-- +-- 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 +-- 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 + curedge int; + nextedge int; + rec RECORD; + bounds geometry; + retrec topology.GetFaceEdges_ReturnType; + n int; + sql text; +BEGIN + + curedge := anedge; + n := 1; + + WHILE true LOOP + sql := 'SELECT edge_id, next_left_edge, next_right_edge FROM ' + || quote_ident(atopology) || '.edge_data WHERE edge_id = ' + || abs(curedge); + EXECUTE sql INTO rec; + retrec.sequence := n; + retrec.edge := curedge; + + RAISE DEBUG 'Edge:% left:% right:%', + curedge, rec.next_left_edge, rec.next_right_edge; + + RETURN NEXT retrec; + + IF curedge < 0 THEN + nextedge := rec.next_right_edge; + ELSE + nextedge := rec.next_left_edge; + END IF; + + IF nextedge = anedge THEN + RAISE DEBUG ' finish'; + RETURN; + END IF; + + IF nextedge = curedge THEN + RAISE EXCEPTION 'Detected bogus loop traversing edge %', curedge; + END IF; + + curedge := nextedge; + + RAISE DEBUG ' curedge:% anedge:%', curedge, anedge; + + n := n + 1; + + IF n > maxedges THEN + RAISE EXCEPTION 'Max traversing limit hit: %', maxedges; + END IF; + END LOOP; + +END +$$ +LANGUAGE 'plpgsql' STABLE; +--} GetRingEdges diff --git a/topology/test/Makefile b/topology/test/Makefile index 41a6dadeb..51c0e539a 100644 --- a/topology/test/Makefile +++ b/topology/test/Makefile @@ -43,7 +43,8 @@ TESTS = regress/legacy_validate.sql regress/legacy_predicate.sql \ regress/gml.sql \ regress/getnodebypoint.sql \ regress/getedgebypoint.sql \ - regress/getfacebypoint.sql + regress/getfacebypoint.sql \ + regress/getringedges.sql check: topo_predicates.sql load_topology.sql load_topology-4326.sql $(MAKE) -C ../../regress postgis.sql staged-install diff --git a/topology/test/regress/getringedges.sql b/topology/test/regress/getringedges.sql new file mode 100644 index 000000000..4ac24a711 --- /dev/null +++ b/topology/test/regress/getringedges.sql @@ -0,0 +1,11 @@ +set client_min_messages to ERROR; + +\i load_topology.sql + +SELECT 'R'||edge_id, (topology.GetRingEdges('city_data', edge_id)).* + FROM city_data.edge; + +SELECT 'R-'||edge_id, (topology.GetRingEdges('city_data', -edge_id)).* + FROM city_data.edge; + +SELECT topology.DropTopology('city_data'); diff --git a/topology/test/regress/getringedges_expected b/topology/test/regress/getringedges_expected new file mode 100644 index 000000000..25a36fee5 --- /dev/null +++ b/topology/test/regress/getringedges_expected @@ -0,0 +1,237 @@ +BEGIN +t +9 +22 +26 +COMMIT +R1|1|1 +R2|1|2 +R2|2|3 +R2|3|-3 +R3|1|3 +R3|2|-3 +R3|3|2 +R4|1|4 +R4|2|-5 +R4|3|5 +R4|4|-4 +R5|1|5 +R5|2|-4 +R5|3|4 +R5|4|-5 +R6|1|6 +R6|2|7 +R6|3|8 +R6|4|-15 +R6|5|-16 +R6|6|-14 +R6|7|-13 +R6|8|-12 +R6|9|22 +R6|10|21 +R7|1|7 +R7|2|8 +R7|3|-15 +R7|4|-16 +R7|5|-14 +R7|6|-13 +R7|7|-12 +R7|8|22 +R7|9|21 +R7|10|6 +R8|1|8 +R8|2|-15 +R8|3|-16 +R8|4|-14 +R8|5|-13 +R8|6|-12 +R8|7|22 +R8|8|21 +R8|9|6 +R8|10|7 +R9|1|9 +R9|2|19 +R9|3|-6 +R9|4|-21 +R10|1|10 +R10|2|-20 +R10|3|13 +R10|4|18 +R11|1|11 +R11|2|15 +R11|3|-8 +R11|4|-17 +R12|1|12 +R12|2|20 +R12|3|-9 +R12|4|-22 +R13|1|13 +R13|2|18 +R13|3|10 +R13|4|-20 +R14|1|14 +R14|2|16 +R14|3|-11 +R14|4|-18 +R15|1|15 +R15|2|-8 +R15|3|-17 +R15|4|11 +R16|1|16 +R16|2|-11 +R16|3|-18 +R16|4|14 +R17|1|17 +R17|2|-7 +R17|3|-19 +R17|4|-10 +R18|1|18 +R18|2|10 +R18|3|-20 +R18|4|13 +R19|1|19 +R19|2|-6 +R19|3|-21 +R19|4|9 +R20|1|20 +R20|2|-9 +R20|3|-22 +R20|4|12 +R21|1|21 +R21|2|6 +R21|3|7 +R21|4|8 +R21|5|-15 +R21|6|-16 +R21|7|-14 +R21|8|-13 +R21|9|-12 +R21|10|22 +R22|1|22 +R22|2|21 +R22|3|6 +R22|4|7 +R22|5|8 +R22|6|-15 +R22|7|-16 +R22|8|-14 +R22|9|-13 +R22|10|-12 +R25|1|25 +R25|2|-25 +R26|1|26 +R-1|1|-1 +R-2|1|-2 +R-3|1|-3 +R-3|2|2 +R-3|3|3 +R-4|1|-4 +R-4|2|4 +R-4|3|-5 +R-4|4|5 +R-5|1|-5 +R-5|2|5 +R-5|3|-4 +R-5|4|4 +R-6|1|-6 +R-6|2|-21 +R-6|3|9 +R-6|4|19 +R-7|1|-7 +R-7|2|-19 +R-7|3|-10 +R-7|4|17 +R-8|1|-8 +R-8|2|-17 +R-8|3|11 +R-8|4|15 +R-9|1|-9 +R-9|2|-22 +R-9|3|12 +R-9|4|20 +R-10|1|-10 +R-10|2|17 +R-10|3|-7 +R-10|4|-19 +R-11|1|-11 +R-11|2|-18 +R-11|3|14 +R-11|4|16 +R-12|1|-12 +R-12|2|22 +R-12|3|21 +R-12|4|6 +R-12|5|7 +R-12|6|8 +R-12|7|-15 +R-12|8|-16 +R-12|9|-14 +R-12|10|-13 +R-13|1|-13 +R-13|2|-12 +R-13|3|22 +R-13|4|21 +R-13|5|6 +R-13|6|7 +R-13|7|8 +R-13|8|-15 +R-13|9|-16 +R-13|10|-14 +R-14|1|-14 +R-14|2|-13 +R-14|3|-12 +R-14|4|22 +R-14|5|21 +R-14|6|6 +R-14|7|7 +R-14|8|8 +R-14|9|-15 +R-14|10|-16 +R-15|1|-15 +R-15|2|-16 +R-15|3|-14 +R-15|4|-13 +R-15|5|-12 +R-15|6|22 +R-15|7|21 +R-15|8|6 +R-15|9|7 +R-15|10|8 +R-16|1|-16 +R-16|2|-14 +R-16|3|-13 +R-16|4|-12 +R-16|5|22 +R-16|6|21 +R-16|7|6 +R-16|8|7 +R-16|9|8 +R-16|10|-15 +R-17|1|-17 +R-17|2|11 +R-17|3|15 +R-17|4|-8 +R-18|1|-18 +R-18|2|14 +R-18|3|16 +R-18|4|-11 +R-19|1|-19 +R-19|2|-10 +R-19|3|17 +R-19|4|-7 +R-20|1|-20 +R-20|2|13 +R-20|3|18 +R-20|4|10 +R-21|1|-21 +R-21|2|9 +R-21|3|19 +R-21|4|-6 +R-22|1|-22 +R-22|2|12 +R-22|3|20 +R-22|4|-9 +R-25|1|-25 +R-25|2|25 +R-26|1|-26 +Topology 'city_data' dropped diff --git a/topology/topology.sql.in.c b/topology/topology.sql.in.c index 501535b1f..ebc92b4ef 100644 --- a/topology/topology.sql.in.c +++ b/topology/topology.sql.in.c @@ -2445,6 +2445,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT; -- SQL/MM block #include "sql/sqlmm.sql" +#include "sql/query/GetRingEdges.sql" // needs getfaceedges_returntype --COMMIT;