From: Sandro Santilli Date: Wed, 18 May 2011 13:59:03 +0000 (+0000) Subject: topology.AddFace(): properly update left/right face for edges _contained_ in the... X-Git-Tag: 2.0.0alpha1~1619 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7f9b8fa596df485f59e84eac1805303550f9aab;p=postgis topology.AddFace(): properly update left/right face for edges _contained_ in the newly registered face and containing_face for isolated nodes in it, refine documentation about it [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7192 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml index a5d2ab01e..eeeaa8f41 100644 --- a/doc/extras_topology.xml +++ b/doc/extras_topology.xml @@ -689,7 +689,7 @@ edgeid AddFace - Adds a polygon to the faces table in the specified topology schema and returns the faceid of new face. + 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. @@ -706,7 +706,14 @@ edgeid Description - 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). + +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. + 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. If the apolygon geometry already exists as a face the face id of the existing face is returned. The apolygon geometry must have the same srid as defined for the topology otherwise an invalid spatial reference sys error will be thrown. diff --git a/topology/sql/populate.sql b/topology/sql/populate.sql index 302c4f1f9..731f8ffb3 100644 --- a/topology/sql/populate.sql +++ b/topology/sql/populate.sql @@ -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'; diff --git a/topology/test/regress/addface.sql b/topology/test/regress/addface.sql index 0099bdc75..1566209b9 100644 --- a/topology/test/regress/addface.sql +++ b/topology/test/regress/addface.sql @@ -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'); diff --git a/topology/test/regress/addface_expected b/topology/test/regress/addface_expected index aa5445f20..b6e370474 100644 --- a/topology/test/regress/addface_expected +++ b/topology/test/regress/addface_expected @@ -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 diff --git a/topology/test/regress/getfacebypoint.sql b/topology/test/regress/getfacebypoint.sql index b9dd1237c..04af5d958 100644 --- a/topology/test/regress/getfacebypoint.sql +++ b/topology/test/regress/getfacebypoint.sql @@ -1,4 +1,4 @@ -set client_min_messages to WARNING; +set client_min_messages to ERROR; SELECT topology.CreateTopology('schema_topo') > 0; diff --git a/topology/test/regress/getfacebypoint_expected b/topology/test/regress/getfacebypoint_expected index fb4f66cd5..980294879 100644 --- a/topology/test/regress/getfacebypoint_expected +++ b/topology/test/regress/getfacebypoint_expected @@ -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