]> granicus.if.org Git - postgis/commitdiff
topology.AddFace(): properly update left/right face for edges _contained_ in the...
authorSandro Santilli <strk@keybit.net>
Wed, 18 May 2011 13:59:03 +0000 (13:59 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 18 May 2011 13:59:03 +0000 (13:59 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7192 b70326c6-7e19-0410-871a-916f4a2858ee

doc/extras_topology.xml
topology/sql/populate.sql
topology/test/regress/addface.sql
topology/test/regress/addface_expected
topology/test/regress/getfacebypoint.sql
topology/test/regress/getfacebypoint_expected

index a5d2ab01e5eb1f12fc9bbddbad40f3d42b5a0a43..eeeaa8f418a2f51893b9e39e712a17986817c419 100644 (file)
@@ -689,7 +689,7 @@ edgeid
                        <refnamediv>
                                <refname>AddFace</refname>
                        
-                               <refpurpose>Adds a polygon to the faces table in the specified topology schema and returns the faceid of new face. 
+                               <refpurpose>Register a polygon as a topology face in the specified topology schema and returns the faceid of new face. 
                                    If face already exists the id of the existing face is returned. Edges of the polygon must already exist otherwise an error is thrown.</refpurpose>
                        </refnamediv>
                
@@ -706,7 +706,14 @@ edgeid
                        <refsection>
                 <title>Description</title>
             
-                <para>Add a face primitive to a topology and get it's identifier. For a newly added face, its edges will be appropriately linked (marked as left-face or right-face).</para>
+                <para>
+Registers a face primitive to a topology and get it's identifier.
+For a newly added face, the edges forming its boundaries and the ones 
+contained in the face will be updated to have correct values in the
+left_face and right_face fields.
+Isolated nodes contained in the face will also be updated to have a correct
+containing_face field value.
+               </para>
                 <para>The target topology is assumed to be valid (containing no self-intersecting edges). An exception is raised if: The polygon boundary is not fully defined by existing edges or the polygon overlaps an existing face.</para>
                 <note><para>If the <varname>apolygon</varname> geometry already exists as a face the face id of the existing face is returned.</para></note>
                 <note><para>The <varname>apolygon</varname> geometry must have the same <varname>srid</varname> as defined for the topology otherwise an invalid spatial reference sys error will be thrown.</para></note>
index 302c4f1f9cfc70fdb2435d5d4d11811bb7a00c29..731f8ffb36baa3dc7524b8f7a6cc64a16da256ae 100644 (file)
@@ -411,7 +411,6 @@ BEGIN
         END IF;
       END IF;
 
-
       p3 = ST_StartPoint(bounds);
       IF ST_DWithin(edgeseg, p3, 0) THEN
         -- Edge segment covers ring endpoint, See bug #874
@@ -480,19 +479,6 @@ BEGIN
     END IF;
   END IF;
 
---     EXECUTE 'SELECT ST_Collect(geom) FROM'
---             || quote_ident(atopology)
---             || '.edge_data '
---             || ' WHERE edge_id = ANY('
---             || quote_literal(array_append(left_edges, right_edges))
---             || ') ';
-
-  --
-  -- TODO:
-  -- Check that NO edge is contained in the face ?
-  --
-  RAISE WARNING 'Not checking if face contains any edge';
-
   IF faceid IS NOT NULL AND faceid != 0 THEN
     RAISE DEBUG 'Face already known as %', faceid;
     RETURN faceid;
@@ -547,11 +533,38 @@ BEGIN
     || ') ';
   END IF;
 
+
+  --
+  -- Set left_face/right_face of any contained edge 
+  --
+  EXECUTE 'UPDATE '
+    || quote_ident(atopology)
+    || '.edge_data SET right_face = '
+    || quote_literal(faceid)
+    || ', left_face = '
+    || quote_literal(faceid)
+    || ' WHERE ST_Contains('
+    || quote_literal(apoly::text)
+    || ', geom)';
+
+  -- 
+  -- Set containing_face of any contained node 
+  -- 
+  EXECUTE 'UPDATE '
+    || quote_ident(atopology)
+    || '.node SET containing_face = '
+    || quote_literal(faceid)
+    || ' WHERE containing_face IS NOT NULL AND ST_Contains('
+    || quote_literal(apoly::text)
+    || ', geom)';
+
   --
   -- TODO:
   -- Set next_left_face and next_right_face !
   -- These are required by the model, but not really used
   -- by this implementation...
+  -- NOTE: should probably be done when adding edges rather than
+  --       when registering faces
   --
   RAISE WARNING 'Not updating next_{left,right}_face fields of face boundary edges';
 
index 0099bdc75ff7890432caa47760aed48e1e9456bc..1566209b97ccf5ca995892a7b6f77032d0940ce7 100644 (file)
@@ -1,4 +1,4 @@
-set client_min_messages to WARNING;
+set client_min_messages to ERROR;
 
 -- Test with zero tolerance
 
@@ -17,7 +17,7 @@ SELECT 'e4',  topology.addEdge('tt', 'LINESTRING(0 0, 0 10)');
 -- Add one edge only incident on a vertex
 SELECT 'e5',  topology.addEdge('tt', 'LINESTRING(0 0, 0 -10)');
 
--- Add 3 more edges closing a squre to the right,
+-- Add 3 more edges closing a square to the right,
 -- all edges with same direction
 
 SELECT 'e6',  topology.addEdge('tt', 'LINESTRING(10 10, 20 10)');
@@ -147,3 +147,28 @@ SELECT face_id, Box2d(mbr) from t3.face ORDER by face_id;
 SELECT edge_id, left_face, right_face from t3.edge ORDER by edge_id;
 
 SELECT topology.DropTopology('t3');
+
+--
+-- Test proper updating of left/right face for contained edges
+-- and nodes
+--
+SELECT topology.CreateTopology('t4') > 0;
+
+SELECT 'N' || topology.addNode('t4', 'POINT(2 6)');
+UPDATE t4.node set containing_face = 0 WHERE node_id = 1;
+
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(0 0,10 0)');
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(10 0,10 10)');
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(10 10,0 10)');
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(0 0,0 10)');
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(0 0,5 5)');
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(5 5,6 5)');
+SELECT 'E' || topology.addEdge('t4', 'LINESTRING(0 10,8 8,10 0)');
+
+select 'F' || topology.addface('t4','POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+
+-- Check edges and nodes
+SELECT 'E'||edge_id, left_face, right_face from t4.edge ORDER by edge_id;
+SELECT 'N'||node_id, containing_face from t4.node ORDER by node_id;
+
+SELECT topology.DropTopology('t4');
index aa5445f206131b1979eeae04e0ad6c9b7b479d26..b6e370474af4bb0a1228093bfb96d6efdabf1136 100644 (file)
@@ -8,13 +8,8 @@ e5|5
 e6|6
 e7|7
 e8|8
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 f1|1
-WARNING:  Not checking if face contains any edge
 f1*|1
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 f2|2
 0|
 1|BOX(0 0,10 10)
@@ -33,8 +28,6 @@ MiX-e1|1
 MiX-e2|2
 MiX-e3|3
 MiX-e4|4
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 MiX-f1|1
 Topology 'Ul' dropped
 t
@@ -49,20 +42,10 @@ t2.e8|8
 t2.e9|9
 t2.e10|10
 t2.e11|11
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t2.f1|1
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t2.f2|2
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t2.f3|3
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t2.f4|4
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t2.f5|5
 ERROR:  Polygon boundary is not fully defined by existing edges at or near point POINT(12 5)
 0|
@@ -87,11 +70,7 @@ t
 t3.e1|1
 t3.e2|2
 t3.e3|3
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t3.f1|1
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 t3.f2|2
 0|
 1|BOX(0 0,10 10)
@@ -100,3 +79,28 @@ t3.f2|2
 2|1|2
 3|0|1
 Topology 't3' dropped
+t
+N1
+E1
+E2
+E3
+E4
+E5
+E6
+E7
+F1
+E1|1|0
+E2|1|0
+E3|1|0
+E4|0|1
+E5|1|1
+E6|1|1
+E7|1|1
+N1|1
+N2|
+N3|
+N4|
+N5|
+N6|
+N7|
+Topology 't4' dropped
index b9dd1237c37055d3d03d589f26d89e06d003d14f..04af5d958321abdcc690568daf8d054d37900423 100644 (file)
@@ -1,4 +1,4 @@
-set client_min_messages to WARNING;
+set client_min_messages to ERROR;
 
 SELECT topology.CreateTopology('schema_topo') > 0;
 
index fb4f66cd5052482225b46b58d615c0f8890b279b..98029487902c504346698905ca542193144e806d 100644 (file)
@@ -19,17 +19,9 @@ t
 18
 19
 20
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 1
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 2
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 3
-WARNING:  Not checking if face contains any edge
-WARNING:  Not updating next_{left,right}_face fields of face boundary edges
 4
 4
 4