]> granicus.if.org Git - postgis/commitdiff
Allow dumping universal face edges with ST_GetFaceEdges. Do it in the correct order...
authorSandro Santilli <strk@keybit.net>
Tue, 24 May 2011 14:47:00 +0000 (14:47 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 24 May 2011 14:47:00 +0000 (14:47 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7236 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/sqlmm.sql
topology/test/regress/st_getfaceedges.sql
topology/test/regress/st_getfaceedges_expected

index 23f4908a63c37aebcec09b670cf26a46ea0c6665..d00b31767cda0d3ded9ca06d583fcabc6e8b40aa 100644 (file)
@@ -46,6 +46,7 @@ DECLARE
   bounds geometry;
   retrec topology.GetFaceEdges_ReturnType;
   n int;
+  sql TEXT;
 BEGIN
   --
   -- toponame and face_id are required
@@ -61,16 +62,18 @@ BEGIN
   n := 1;
 
   -- Construct the face geometry, then for each polygon:
-  FOR rec IN SELECT (ST_DumpRings((ST_Dump(ST_ForceRHR(
-    topology.ST_GetFaceGeometry(toponame, face_id)))).geom)).*
+  sql := 'SELECT (ST_DumpRings((ST_Dump(ST_ForceRHR('
+    || 'ST_BuildArea(ST_Collect(geom))))).geom)).* FROM '
+    || quote_ident(toponame) || '.edge_data WHERE left_face = '
+    || face_id || ' OR right_face = ' || face_id;
+  FOR rec IN EXECUTE sql 
   LOOP -- {
 
     -- Contents of a directed face are the list of edges
     -- that cover the specific ring
     bounds = ST_Boundary(rec.geom);
 
-    FOR rec IN EXECUTE
-      'SELECT e.*, ST_Line_Locate_Point('
+    sql := 'SELECT e.*, ST_Line_Locate_Point('
       || quote_literal(bounds::text)
       || ', ST_Line_Interpolate_Point(e.geom, 0.2)) as pos'
       || ', ST_Line_Locate_Point('
@@ -81,16 +84,31 @@ BEGIN
       || ' OR e.right_face = ' || face_id
       || ') AND ST_Covers('
       || quote_literal(bounds::text)
-      || ', e.geom) ORDER BY pos DESC'
+      || ', e.geom)';
+    IF face_id = 0 THEN
+      sql := sql || ' ORDER BY pos ASC';
+    ELSE
+      sql := sql || ' ORDER BY POS DESC';
+    END IF;
+
+    FOR rec IN EXECUTE sql
     LOOP
 
       retrec.sequence = n;
       retrec.edge = rec.edge_id;
 
-      -- if this edge goes in same direction to the
-      --       ring bounds, make it with negative orientation
-      IF rec.pos2 > rec.pos THEN -- edge goes in same direction
-        retrec.edge = -retrec.edge;
+      IF face_id = 0 THEN
+        -- if this edge goes in opposite direction to the
+        --       ring bounds, make it with negative orientation
+        IF rec.pos2 < rec.pos THEN -- edge goes in opposite direction
+          retrec.edge = -retrec.edge;
+        END IF;
+      ELSE
+        -- if this edge goes in same direction to the
+        --       ring bounds, make it with negative orientation
+        IF rec.pos2 > rec.pos THEN -- edge goes in same direction
+          retrec.edge = -retrec.edge;
+        END IF;
       END IF;
 
       RETURN NEXT retrec;
@@ -101,6 +119,9 @@ BEGIN
   END LOOP; -- }
 
   RETURN;
+EXCEPTION
+  WHEN INVALID_SCHEMA_NAME THEN
+    RAISE EXCEPTION 'SQL/MM Spatial exception - invalid topology name';
 END
 $$
 LANGUAGE 'plpgsql' VOLATILE;
index 6398bcd12792585c616da4d8062f990460478951..2927d79c3a88b15df473eecec4994a74085374e4 100644 (file)
@@ -26,5 +26,7 @@ SELECT 'F' ||
 SELECT 'F1', (topology.ST_GetFaceEdges('tt', 1)).*;
 SELECT 'F2', (topology.ST_GetFaceEdges('tt', 2)).*;
 
+SELECT 'F0', (topology.ST_GetFaceEdges('tt', 0)).*;
+
 
 SELECT topology.DropTopology('tt');
index f95751d8dbf6c13a61bc21ff1a48038e2634cdee..e91b40b4f7e64a3a2f5c1a0a5a4207d340dc4ce4 100644 (file)
@@ -23,4 +23,8 @@ F1|7|3
 F2|1|-3
 F2|2|-2
 F2|3|-1
+F0|1|-5
+F0|2|4
+F0|3|6
+F0|4|-7
 Topology 'tt' dropped