]> granicus.if.org Git - postgis/commitdiff
topology.GetRingEdges() implementation and test. This is the first real user of next_...
authorSandro Santilli <strk@keybit.net>
Wed, 18 May 2011 08:58:34 +0000 (08:58 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 18 May 2011 08:58:34 +0000 (08:58 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7185 b70326c6-7e19-0410-871a-916f4a2858ee

topology/Makefile.in
topology/sql/query/GetRingEdges.sql [new file with mode: 0644]
topology/test/Makefile
topology/test/regress/getringedges.sql [new file with mode: 0644]
topology/test/regress/getringedges_expected [new file with mode: 0644]
topology/topology.sql.in.c

index 72d6e6368be2ea40f50684195494dc98df779ef0..77c82a62a5fb7ce727b4ea66afd03a222a47d7c1 100644 (file)
@@ -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 (file)
index 0000000..5514f02
--- /dev/null
@@ -0,0 +1,99 @@
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-- 
+-- PostGIS - Spatial Types for PostgreSQL
+-- http://postgis.refractions.net
+--
+-- Copyright (C) 2011 Sandro Santilli <strk@keybit.net>
+--
+-- 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@keybit.net>
+-- 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
index 41a6dadeb3d2f3c2b0639336b2ccb855a717d142..51c0e539acb48ac27eb164d1372a65b3323ab037 100644 (file)
@@ -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 (file)
index 0000000..4ac24a7
--- /dev/null
@@ -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 (file)
index 0000000..25a36fe
--- /dev/null
@@ -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
index 501535b1f961c2fb14079148c2057c26be029061..ebc92b4ef1c8c7ada77b8c13d714aa3fd30d45e2 100644 (file)
@@ -2445,6 +2445,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
 
 --  SQL/MM block
 #include "sql/sqlmm.sql"
+#include "sql/query/GetRingEdges.sql" // needs getfaceedges_returntype
 
 
 --COMMIT;