]> granicus.if.org Git - postgis/commitdiff
Add a topology.GetNodeEdges function
authorSandro Santilli <strk@keybit.net>
Thu, 16 Feb 2012 10:25:50 +0000 (10:25 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 16 Feb 2012 10:25:50 +0000 (10:25 +0000)
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

doc/extras_topology.xml
topology/Makefile.in
topology/sql/query/GetNodeEdges.sql.in.c [new file with mode: 0644]
topology/test/regress/getnodeedges.sql [new file with mode: 0644]
topology/test/regress/getnodeedges_expected [new file with mode: 0644]
topology/topology.sql.in.c

index 0f6246eb012da2b71fd8ade6494c5c97a98865e3..229b2ff2b96aeda888292fcc14c494d60de13b63 100644 (file)
@@ -1869,7 +1869,63 @@ when dealing with possibly invalid topologies.
                        <!-- Optionally add a "See Also" section -->
                        <refsection>
                                <title>See Also</title>
-                               <para><xref linkend="ST_GetFaceEdges"/></para>
+                               <para>
+<xref linkend="ST_GetFaceEdges"/>,
+<xref linkend="GetNodeEdges"/>
+                               </para>
+                       </refsection>
+               </refentry>
+
+               <refentry id="GetNodeEdges">
+                       <refnamediv>
+                               <refname>GetNodeEdges</refname>
+                       
+                               <refpurpose>
+Returns an ordered set of edges incident to the given node.
+                               </refpurpose>
+                       </refnamediv>
+               
+                       <refsynopsisdiv>
+                               <funcsynopsis>
+                                       <funcprototype>
+                                       <funcdef>getfaceedges_returntype <function>GetNodeEdges</function></funcdef>
+                                       <paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
+                                       <paramdef><type>integer </type> <parameter>anode</parameter></paramdef>
+                                       </funcprototype>
+                               </funcsynopsis>
+                       </refsynopsisdiv>
+               
+                       <refsection>
+                <title>Description</title>
+            
+                <para>
+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.
+               </para>
+
+            <note>
+               <para>
+This function computes ordering rather than deriving from metadata
+and is thus usable to build edge ring linking.
+               </para>
+            </note>
+
+                <!-- use this format if new function -->
+                <para>Availability: 2.0 </para>
+                       </refsection>
+               
+                       <!-- Optionally add a "See Also" section -->
+                       <refsection>
+                               <title>See Also</title>
+                               <para>
+<xref linkend="GetRingEdges"/>,
+<xref linkend="ST_Azimuth"/>
+                               </para>
                        </refsection>
                </refentry>
                
index 2a114005d1af47d63faf40ca0fbbbc451db14cf4..6be2a3ef604adbadba697d6b9c5cba5465ef71c6 100644 (file)
@@ -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 (file)
index 0000000..424d83e
--- /dev/null
@@ -0,0 +1,63 @@
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+-- 
+-- PostGIS - Spatial Types for PostgreSQL
+-- http://postgis.refractions.net
+--
+-- Copyright (C) 2012 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.
+--
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+--{
+--
+-- 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 (file)
index 0000000..e42ed2d
--- /dev/null
@@ -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 (file)
index 0000000..3bd2a10
--- /dev/null
@@ -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
index 5c36b99af163f5ff0b5560045fdf66afe200f4ad..fcd8ec1b963c5ef31265854d1a9b0d99c64357aa 100644 (file)
@@ -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"