From: Sandro Santilli Date: Thu, 16 Feb 2012 10:25:50 +0000 (+0000) Subject: Add a topology.GetNodeEdges function X-Git-Tag: 2.0.0alpha6~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e6571a3a237830ff33c4f3ddd84e476d461265cd;p=postgis Add a topology.GetNodeEdges function This function is a fundamental topological primitive to do things like SQL-based poligonization. git-svn-id: http://svn.osgeo.org/postgis/trunk@9219 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml index 0f6246eb0..229b2ff2b 100644 --- a/doc/extras_topology.xml +++ b/doc/extras_topology.xml @@ -1869,7 +1869,63 @@ when dealing with possibly invalid topologies. See Also - + +, + + + + + + + + GetNodeEdges + + +Returns an ordered set of edges incident to the given node. + + + + + + + getfaceedges_returntype GetNodeEdges + varchar atopology + integer anode + + + + + + Description + + +Returns an ordered set of edges incident to the given node. +Each output consists of a sequence and a signed edge id. +Sequence numbers start with value 1. +A positive edge starts at the given node. +A negative edge ends into the given node. +Closed edges will appear twice (with both signs). +Order is clockwise starting from northbound. + + + + +This function computes ordering rather than deriving from metadata +and is thus usable to build edge ring linking. + + + + + Availability: 2.0 + + + + + See Also + +, + + diff --git a/topology/Makefile.in b/topology/Makefile.in index 2a114005d..6be2a3ef6 100644 --- a/topology/Makefile.in +++ b/topology/Makefile.in @@ -81,7 +81,7 @@ topology_upgrade.sql: topology.sql topology_upgrade_20_minor.sql: topology_drop_before.sql topology_upgrade.sql topology_drop_after.sql cat $^ > $@ -topology.sql.in: sql/sqlmm.sql.in.c sql/populate.sql.in.c sql/polygonize.sql.in.c sql/gml.sql.in.c sql/query/getnodebypoint.sql.in.c sql/query/getedgebypoint.sql.in.c sql/query/getfacebypoint.sql.in.c sql/query/GetRingEdges.sql.in.c sql/manage/TopologySummary.sql.in.c sql/manage/CopyTopology.sql.in.c sql/manage/ManageHelper.sql.in.c sql/topoelement/topoelement_agg.sql.in.c sql/topogeometry/type.sql.in.c sql/topogeometry/totopogeom.sql.in.c sql/predicates.sql.in.c +topology.sql.in: sql/sqlmm.sql.in.c sql/populate.sql.in.c sql/polygonize.sql.in.c sql/gml.sql.in.c sql/query/getnodebypoint.sql.in.c sql/query/getedgebypoint.sql.in.c sql/query/getfacebypoint.sql.in.c sql/query/GetRingEdges.sql.in.c sql/query/GetNodeEdges.sql.in.c sql/manage/TopologySummary.sql.in.c sql/manage/CopyTopology.sql.in.c sql/manage/ManageHelper.sql.in.c sql/topoelement/topoelement_agg.sql.in.c sql/topogeometry/type.sql.in.c sql/topogeometry/totopogeom.sql.in.c sql/predicates.sql.in.c uninstall_topology.sql: topology.sql ../utils/create_undef.pl $(PERL) ../utils/create_undef.pl $< $(POSTGIS_PGSQL_VERSION) > $@ diff --git a/topology/sql/query/GetNodeEdges.sql.in.c b/topology/sql/query/GetNodeEdges.sql.in.c new file mode 100644 index 000000000..424d83eb3 --- /dev/null +++ b/topology/sql/query/GetNodeEdges.sql.in.c @@ -0,0 +1,63 @@ +-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +-- +-- PostGIS - Spatial Types for PostgreSQL +-- http://postgis.refractions.net +-- +-- Copyright (C) 2012 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. +-- +-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +--{ +-- +-- Return a list of edges (sequence, id) incident to the given node. +-- +-- Edge ids are signed, they are negative if the node is their endpoint. +-- Sequence numbers start with 1 ordering edges by azimuth (clockwise). +-- +-- GetNodeEdges(atopology, anode) +-- +CREATE OR REPLACE FUNCTION topology.GetNodeEdges(atopology varchar, anode int) + RETURNS SETOF topology.GetFaceEdges_ReturnType +AS +$$ +DECLARE + curedge int; + nextedge int; + rec RECORD; + retrec topology.GetFaceEdges_ReturnType; + n int; + sql text; +BEGIN + + n := 0; + sql := + 'WITH incident_edges AS ( SELECT edge_id, start_node, end_node, ST_RemoveRepeatedPoints(geom) as geom FROM ' + || quote_ident(atopology) + || '.edge_data WHERE start_node = ' || anode + || ' or end_node = ' || anode + || ') SELECT edge_id, ST_Azimuth(ST_StartPoint(geom), ST_PointN(geom, 2)) as az FROM incident_edges WHERE start_node = ' || anode + || ' UNION ALL SELECT -edge_id, ST_Azimuth(ST_EndPoint(geom), ST_PointN(geom, ST_NumPoints(geom)-1)) FROM incident_edges WHERE end_node = ' || anode + || ' ORDER BY az'; +#ifdef POSTGIS_TOPOLOGY_DEBUG + RAISE DEBUG 'sql: %', sql; +#endif + + FOR rec IN EXECUTE sql + LOOP -- incident edges { + +#ifdef POSTGIS_TOPOLOGY_DEBUG + RAISE DEBUG 'Edge:% az:%', rec.edge_id, rec.az; +#endif + n := n + 1; + retrec.sequence := n; + retrec.edge := rec.edge_id; + RETURN NEXT retrec; + END LOOP; -- incident edges } + +END +$$ +LANGUAGE 'plpgsql' STABLE; +--} GetRingEdges diff --git a/topology/test/regress/getnodeedges.sql b/topology/test/regress/getnodeedges.sql new file mode 100644 index 000000000..e42ed2d3a --- /dev/null +++ b/topology/test/regress/getnodeedges.sql @@ -0,0 +1,8 @@ +set client_min_messages to ERROR; + +\i load_topology.sql + +SELECT 'N'||node_id, (topology.GetNodeEdges('city_data', node_id)).* + FROM city_data.node ORDER BY node_id, sequence; + +SELECT topology.DropTopology('city_data'); diff --git a/topology/test/regress/getnodeedges_expected b/topology/test/regress/getnodeedges_expected new file mode 100644 index 000000000..3bd2a10c3 --- /dev/null +++ b/topology/test/regress/getnodeedges_expected @@ -0,0 +1,55 @@ +BEGIN +t +9 +22 +26 +COMMIT +N1|1|1 +N1|2|-1 +N2|1|3 +N2|2|2 +N2|3|-2 +N3|1|-3 +N5|1|4 +N6|1|-5 +N6|2|-4 +N7|1|5 +N8|1|22 +N8|2|12 +N9|1|20 +N9|2|13 +N9|3|-12 +N10|1|18 +N10|2|14 +N10|3|-13 +N11|1|16 +N11|2|-14 +N12|1|15 +N12|2|-16 +N12|3|-11 +N13|1|17 +N13|2|11 +N13|3|-18 +N13|4|10 +N14|1|19 +N14|2|-10 +N14|3|-20 +N14|4|-9 +N15|1|21 +N15|2|9 +N15|3|-22 +N16|1|6 +N16|2|-21 +N17|1|7 +N17|2|-19 +N17|3|-6 +N18|1|8 +N18|2|-17 +N18|3|-7 +N19|1|-15 +N19|2|-8 +N20|1|-26 +N20|2|26 +N21|1|25 +N22|1|-25 +Topology 'city_data' dropped diff --git a/topology/topology.sql.in.c b/topology/topology.sql.in.c index 5c36b99af..fcd8ec1b9 100644 --- a/topology/topology.sql.in.c +++ b/topology/topology.sql.in.c @@ -1954,8 +1954,9 @@ LANGUAGE 'plpgsql' VOLATILE STRICT; -- SQL/MM block #include "sql/sqlmm.sql.in.c" --- The following file needs getfaceedges_returntype, defined in sqlmm.sql +-- The following files needs getfaceedges_returntype, defined in sqlmm.sql #include "sql/query/GetRingEdges.sql.in.c" +#include "sql/query/GetNodeEdges.sql.in.c" --general management -- #include "sql/manage/ManageHelper.sql.in.c"