From: Sandro Santilli Date: Fri, 27 May 2011 08:34:23 +0000 (+0000) Subject: Add an optional force_new parameter to topology.ST_AddFace to force creation of a... X-Git-Tag: 2.0.0alpha1~1546 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84dc153361630015a73eb6dddc594750bc72dfda;p=postgis Add an optional force_new parameter to topology.ST_AddFace to force creation of a new face when one already exists. Regress test and document. [RT-SIGTA] git-svn-id: http://svn.osgeo.org/postgis/trunk@7268 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml index 0a2ae2d6b..209cc0f07 100644 --- a/doc/extras_topology.xml +++ b/doc/extras_topology.xml @@ -689,8 +689,9 @@ edgeid AddFace - 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. + +Registers a face primitive to a topology and get it's identifier. + @@ -699,6 +700,7 @@ edgeid integer AddFace varchar toponame geometry apolygon + boolean force_new=false @@ -708,14 +710,33 @@ edgeid 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. + + +If the apolygon geometry already exists as a face, then: +if force_new is false (the default) the +face id of the existing face is returned; +if force_new is true a new id will be assigned to +the newly registered face. + + + +When a new registration of an existing face is performed (force_new=true), +no action will be taken to resolve dangling references to the existing +face in the edge, node an relation tables, nor will the MBR field of the +existing face record be updated. It is up to the caller to deal with that. + + 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 1f1abc26d..f861843f7 100644 --- a/topology/sql/populate.sql +++ b/topology/sql/populate.sql @@ -300,13 +300,22 @@ LANGUAGE 'plpgsql' VOLATILE; --{ -- --- AddFace(atopology, poly) +-- AddFace(atopology, poly, [=true]) -- -- Add a face primitive to a topology and get it's identifier. --- Returns an existing face at the same location, if any. +-- Returns an existing face at the same location, if any, unless +-- true is passed as the force_new argument -- -- For a newly added face, its edges will be appropriately --- linked (marked as left-face or right-face). +-- linked (marked as left-face or right-face), and any contained +-- edges and nodes would also be marked as such. +-- +-- When forcing re-registration of an existing face, no action will be +-- taken to deal with the face being substituted. Which means +-- a record about the old face and any record in the relation table +-- referencing the existing face will remain untouched, effectively +-- leaving the topology in a possibly invalid state. +-- It is up to the caller to deal with that. -- -- The target topology is assumed to be valid (containing no -- self-intersecting edges). @@ -316,7 +325,7 @@ LANGUAGE 'plpgsql' VOLATILE; -- o The polygon overlaps an existing face. -- -- -CREATE OR REPLACE FUNCTION topology.AddFace(atopology varchar, apoly geometry) +CREATE OR REPLACE FUNCTION topology.AddFace(atopology varchar, apoly geometry, force_new boolean DEFAULT FALSE) RETURNS int AS $$ @@ -480,8 +489,12 @@ BEGIN END IF; IF faceid IS NOT NULL AND faceid != 0 THEN - RAISE DEBUG 'Face already known as %', faceid; - RETURN faceid; + IF NOT force_new THEN + RAISE DEBUG 'Face already known as %, not forcing a new face', faceid; + RETURN faceid; + ELSE + RAISE DEBUG 'Face already known as %, forcing a new face', faceid; + END IF; END IF; -- diff --git a/topology/test/regress/addface.sql b/topology/test/regress/addface.sql index 1566209b9..5369d946d 100644 --- a/topology/test/regress/addface.sql +++ b/topology/test/regress/addface.sql @@ -40,6 +40,13 @@ SELECT face_id, Box2d(mbr) from tt.face ORDER by face_id; -- Check linking SELECT edge_id, left_face, right_face from tt.edge ORDER by edge_id; +-- Force re-registration of an existing face +SELECT 'f1-force', topology.addFace('tt', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', true); + +-- re-check added faces and linking +SELECT face_id, Box2d(mbr) from tt.face ORDER by face_id; +SELECT edge_id, left_face, right_face from tt.edge ORDER by edge_id; + SELECT topology.DropTopology('tt'); -- Test topology with MixedCase diff --git a/topology/test/regress/addface_expected b/topology/test/regress/addface_expected index b6e370474..bf506ef10 100644 --- a/topology/test/regress/addface_expected +++ b/topology/test/regress/addface_expected @@ -22,6 +22,19 @@ f2|2 6|0|2 7|0|2 8|0|2 +f1-force|3 +0| +1|BOX(0 0,10 10) +2|BOX(10 0,20 10) +3|BOX(0 0,10 10) +1|3|0 +2|3|2 +3|0|3 +4|0|3 +5|0|0 +6|0|2 +7|0|2 +8|0|2 Topology 'tt' dropped t MiX-e1|1