<refnamediv>
<refname>AddFace</refname>
- <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>
+ <refpurpose>
+Registers a face primitive to a topology and get it's identifier.
+ </refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcdef>integer <function>AddFace</function></funcdef>
<paramdef><type>varchar </type> <parameter>toponame</parameter></paramdef>
<paramdef><type>geometry </type> <parameter>apolygon</parameter></paramdef>
+ <paramdef choice="opt"><type>boolean </type> <parameter>force_new=false</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<para>
Registers a face primitive to a topology and get it's identifier.
+ </para>
+
+ <para>
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>
+
<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>
+
+ <para>
+If the <varname>apolygon</varname> geometry already exists as a face, then:
+if <varname>force_new</varname> is false (the default) the
+face id of the existing face is returned;
+if <varname>force_new</varname> is true a new id will be assigned to
+the newly registered face.
+ </para>
+
+ <note><para>
+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.
+ </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>
<!-- use this format if new function -->
--{
--
--- AddFace(atopology, poly)
+-- AddFace(atopology, poly, [<force_new>=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).
-- 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
$$
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;
--
-- 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
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