]> granicus.if.org Git - postgis/commitdiff
Add TopoGeom_{add,rem}Element functions
authorSandro Santilli <strk@keybit.net>
Wed, 25 Nov 2015 18:20:47 +0000 (18:20 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 25 Nov 2015 18:20:47 +0000 (18:20 +0000)
Includes regression tests and documentation

git-svn-id: http://svn.osgeo.org/postgis/trunk@14423 b70326c6-7e19-0410-871a-916f4a2858ee

NEWS
doc/extras_topology.xml
topology/Makefile.in
topology/sql/topogeometry/topogeom_edit.sql.in [new file with mode: 0644]
topology/test/Makefile.in
topology/test/regress/topogeom_edit.sql [new file with mode: 0644]
topology/test/regress/topogeom_edit_expected [new file with mode: 0644]
topology/topology.sql.in

diff --git a/NEWS b/NEWS
index 8dcc3e2debd35337eae84334fcf7c50293ed1ef6..9324d6047323d0a81351852796c7e5b7d2bbc811 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PostGIS 2.3.0
  * Deprecated signatures *
  * New Features *
 
+  - TopoGeom_addElement, TopoGeom_remElement (Sando Santilli)
+
 PostGIS 2.2.0
 2015/10/07
 
index 1524701a41a3fae6fdf93f22cdb8f142bb15c716..b81ea353c801de02768a5c3f384c623efcadfa63 100644 (file)
@@ -185,7 +185,9 @@ ERROR:  value for domain topology.topoelement violates check constraint "dimensi
                 <para>
                   <xref linkend="GetTopoGeomElements"/>,
                   <xref linkend="topoelementarray" />,
-                  <xref linkend="topogeometry" />
+                  <xref linkend="topogeometry" />,
+                  <xref linkend="TopoGeom_addElement" />,
+                  <xref linkend="TopoGeom_remElement" />
                 </para>
             </refsection>
                </refentry>
@@ -2939,6 +2941,97 @@ UPDATE nei_topo SET topo = ST_Buffer(clearTopoGeom(topo), -10);
                        </refsection>
                </refentry>
 
+    <refentry id="TopoGeom_addElement">
+                       <refnamediv>
+                               <refname>TopoGeom_addElement</refname>
+                               <refpurpose>Add an element to the definition of a TopoGeometry</refpurpose>
+                       </refnamediv>
+                       <refsynopsisdiv>
+                               <funcsynopsis>
+                                       <funcprototype>
+                                       <funcdef>topogeometry <function>TopoGeom_addElement</function></funcdef>
+                                       <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
+          <paramdef><type>topoelement </type> <parameter>el</parameter></paramdef>
+                                       </funcprototype>
+                               </funcsynopsis>
+                       </refsynopsisdiv>
+
+                       <refsection>
+                <title>Description</title>
+
+                <para>
+Adds a <xref linkend="topoelement" /> to the definition of a
+TopoGeometry object. Does not error out if the element is already
+part of the definition.
+                </para>
+
+                <!-- use this format if new function -->
+                <para>Availability: 2.3</para>
+                       </refsection>
+                       <refsection>
+                               <title>Examples</title>
+        <programlisting>
+-- Add edge 5 to TopoGeometry tg
+UPDATE mylayer SET tg = TopoGeom_addElement(tg, '{5,2}');
+                               </programlisting>
+                       </refsection>
+
+                       <!-- Optionally add a "See Also" section -->
+                       <refsection>
+                               <title>See Also</title>
+        <para>
+<xref linkend="TopoGeom_remElement" />,
+<xref linkend="CreateTopoGeom" />
+        </para>
+                       </refsection>
+               </refentry>
+
+    <refentry id="TopoGeom_remElement">
+                       <refnamediv>
+                               <refname>TopoGeom_remElement</refname>
+
+                               <refpurpose>Remove an element from the definition of a TopoGeometry</refpurpose>
+                       </refnamediv>
+
+                       <refsynopsisdiv>
+                               <funcsynopsis>
+                                       <funcprototype>
+                                       <funcdef>topogeometry <function>TopoGeom_remElement</function></funcdef>
+                                       <paramdef><type>topogeometry </type> <parameter>tg</parameter></paramdef>
+          <paramdef><type>topoelement </type> <parameter>el</parameter></paramdef>
+                                       </funcprototype>
+                               </funcsynopsis>
+                       </refsynopsisdiv>
+
+                       <refsection>
+                <title>Description</title>
+
+                <para>
+Removes a <xref linkend="topoelement" /> from the definition of a
+TopoGeometry object.
+                </para>
+
+                <!-- use this format if new function -->
+                <para>Availability: 2.3</para>
+                       </refsection>
+                       <refsection>
+                               <title>Examples</title>
+        <programlisting>
+-- Remove face 43 from TopoGeometry tg
+UPDATE mylayer SET tg = TopoGeom_remElement(tg, '{43,3}');
+                               </programlisting>
+                       </refsection>
+
+                       <!-- Optionally add a "See Also" section -->
+                       <refsection>
+                               <title>See Also</title>
+        <para>
+<xref linkend="TopoGeom_addElement" />,
+<xref linkend="CreateTopoGeom" />
+        </para>
+                       </refsection>
+               </refentry>
+
     <refentry id="toTopoGeom_editor_proxy">
                        <refnamediv>
         <refname>toTopoGeom</refname>
@@ -3037,7 +3130,7 @@ Refer to <xref linkend="toTopoGeom" />
                 <para>tg_id is the topogeometry id of the topogeometry object in the topology in the layer denoted by <varname>layer_id</varname> in the topology.layer table.</para>
         
                 <!-- use this format if new function -->
-                <para>Availability: 1.?</para>
+                <para>Availability: 2.0.0</para>
                        </refsection>
                
                
@@ -3050,7 +3143,12 @@ Refer to <xref linkend="toTopoGeom" />
                        <!-- Optionally add a "See Also" section -->
                        <refsection>
                                <title>See Also</title>
-                               <para><xref linkend="GetTopoGeomElementArray"/>, <xref linkend="topoelement"/></para>
+                               <para>
+          <xref linkend="GetTopoGeomElementArray"/>,
+          <xref linkend="topoelement"/>,
+          <xref linkend="TopoGeom_addElement" />,
+          <xref linkend="TopoGeom_remElement" />
+        </para>
                        </refsection>
                </refentry>
 
index 8b5f1d7b335e370cb4585c136dfbdb3a0812fd97..8dcfe64fbca186a5d0eba2bae3614461ff78848b 100644 (file)
@@ -100,7 +100,29 @@ topology_upgrade.sql.in:  topology.sql
 topology_upgrade.sql: topology_drop_before.sql topology_upgrade.sql.in topology_drop_after.sql
        cat $^ > $@
 
-topology.sql: sql/sqlmm.sql.in sql/populate.sql.in sql/polygonize.sql.in sql/export/gml.sql.in sql/export/TopoJSON.sql.in sql/query/getnodebypoint.sql.in sql/query/getedgebypoint.sql.in sql/query/getfacebypoint.sql.in sql/query/GetRingEdges.sql.in sql/query/GetNodeEdges.sql.in sql/manage/TopologySummary.sql.in sql/manage/CopyTopology.sql.in sql/manage/ManageHelper.sql.in sql/topoelement/topoelement_agg.sql.in sql/topogeometry/type.sql.in sql/topogeometry/totopogeom.sql.in sql/topogeometry/cleartopogeom.sql.in sql/topogeometry/simplify.sql.in sql/predicates.sql.in ../postgis/sqldefines.h ../postgis_svn_revision.h
+topology.sql: \
+       sql/sqlmm.sql.in \
+       sql/populate.sql.in \
+       sql/polygonize.sql.in \
+       sql/export/gml.sql.in \
+       sql/export/TopoJSON.sql.in \
+       sql/query/getnodebypoint.sql.in \
+       sql/query/getedgebypoint.sql.in \
+       sql/query/getfacebypoint.sql.in \
+       sql/query/GetRingEdges.sql.in \
+       sql/query/GetNodeEdges.sql.in \
+       sql/manage/TopologySummary.sql.in \
+       sql/manage/CopyTopology.sql.in \
+       sql/manage/ManageHelper.sql.in \
+       sql/topoelement/topoelement_agg.sql.in \
+       sql/topogeometry/type.sql.in \
+       sql/topogeometry/totopogeom.sql.in \
+       sql/topogeometry/cleartopogeom.sql.in \
+       sql/topogeometry/topogeom_edit.sql.in \
+       sql/topogeometry/simplify.sql.in \
+       sql/predicates.sql.in \
+       ../postgis/sqldefines.h \
+       ../postgis_svn_revision.h
 
 uninstall_topology.sql: topology.sql ../utils/create_undef.pl 
        $(PERL) ../utils/create_undef.pl $< $(POSTGIS_PGSQL_VERSION) > $@
diff --git a/topology/sql/topogeometry/topogeom_edit.sql.in b/topology/sql/topogeometry/topogeom_edit.sql.in
new file mode 100644 (file)
index 0000000..4fd0d0e
--- /dev/null
@@ -0,0 +1,95 @@
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+--
+-- PostGIS - Spatial Types for PostgreSQL
+-- http://postgis.net
+--
+-- Copyright (C) 2015 Sandro Santilli <strk@keybit.net>
+--
+-- This is free software; you can redistribute and/or modify it under
+-- the terms of the GNU General Public Licence. See the COPYING file.
+--
+-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/* #define POSTGIS_TOPOLOGY_DEBUG 1 */
+
+-- {
+--  Add an element to a TopoGeometry definition
+--
+-- }{
+CREATE OR REPLACE FUNCTION topology.TopoGeom_addElement(tg topology.TopoGeometry, el topology.TopoElement)
+  RETURNS topology.TopoGeometry
+AS
+$$
+DECLARE
+  toponame TEXT;
+  sql TEXT;
+BEGIN
+
+  -- Get topology name
+  BEGIN
+    SELECT name
+    FROM topology.topology
+      INTO STRICT toponame WHERE id = topology_id(tg);
+  EXCEPTION
+    WHEN NO_DATA_FOUND THEN
+      RAISE EXCEPTION 'No topology with name "%" in topology.topology',
+        atopology;
+  END;
+
+  -- Insert new element
+  sql := format('INSERT INTO %s.relation'
+         '(topogeo_id,layer_id,element_id,element_type)'
+         ' VALUES($1,$2,$3,$4)', quote_ident(toponame));
+  BEGIN
+    EXECUTE sql USING id(tg), layer_id(tg), el[1], el[2];
+  EXCEPTION
+    WHEN unique_violation THEN
+      -- already present, let go
+    WHEN OTHERS THEN
+      RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
+  END;
+
+  RETURN tg;
+
+END
+$$
+LANGUAGE 'plpgsql' VOLATILE STRICT;
+-- }
+
+-- {
+--  Remove an element from a TopoGeometry definition
+--
+-- }{
+CREATE OR REPLACE FUNCTION topology.TopoGeom_remElement(tg topology.TopoGeometry, el topology.TopoElement)
+  RETURNS topology.TopoGeometry
+AS
+$$
+DECLARE
+  toponame TEXT;
+  sql TEXT;
+BEGIN
+
+  -- Get topology name
+  BEGIN
+    SELECT name
+    FROM topology.topology
+      INTO STRICT toponame WHERE id = topology_id(tg);
+  EXCEPTION
+    WHEN NO_DATA_FOUND THEN
+      RAISE EXCEPTION 'No topology with name "%" in topology.topology',
+        atopology;
+  END;
+
+  -- Delete the element
+  sql := format('DELETE FROM %s.relation WHERE '
+         'topogeo_id = $1 AND layer_id = $2 AND '
+         'element_id = $3 AND element_type = $4',
+         quote_ident(toponame));
+  EXECUTE sql USING id(tg), layer_id(tg), el[1], el[2];
+
+  RETURN tg;
+
+END
+$$
+LANGUAGE 'plpgsql' VOLATILE STRICT;
+-- }
index 7274ec9e7a7278ec6621363d1c2dfd12866465a4..604f94a8ba7dc0b4c26bcbcd26a4d3a1c5122453 100644 (file)
@@ -51,6 +51,7 @@ TESTS = regress/legacy_validate.sql regress/legacy_predicate.sql \
        regress/topogeo_addlinestring.sql \
        regress/topogeo_addpoint.sql \
        regress/topogeo_addpolygon.sql \
+  regress/topogeom_edit.sql \
        regress/topogeometry_type.sql \
        regress/topojson.sql \
   regress/topologysummary.sql \
diff --git a/topology/test/regress/topogeom_edit.sql b/topology/test/regress/topogeom_edit.sql
new file mode 100644 (file)
index 0000000..fa83ef2
--- /dev/null
@@ -0,0 +1,24 @@
+\set VERBOSITY terse
+set client_min_messages to ERROR;
+
+select 'create', createtopology('tt') > 0;
+
+-- Create a line layer (will be layer 1)
+CREATE TABLE tt.f_line(id serial);
+SELECT 'simple_line_layer', AddTopoGeometryColumn('tt', 'tt', 'f_line','g','LINE');
+
+INSERT INTO tt.f_line (g) VALUES
+ ( toTopoGeom('LINESTRING(0 0, 10 0)'::geometry, 'tt', 1) );
+INSERT INTO tt.f_line (g) VALUES
+ ( toTopoGeom('LINESTRING(10 0, 30 0)'::geometry, 'tt', 1) );
+
+-- Sane calls
+SELECT id, 'start', id, ST_Length(g) FROM tt.f_line WHERE id = 1;
+SELECT id, 'add',  id, ST_Length(TopoGeom_addElement(g, '{2,2}')) FROM tt.f_line WHERE id = 1;
+SELECT id, 'rem',  id, ST_Length(TopoGeom_remElement(g, '{1,2}')) FROM tt.f_line WHERE id = 1;
+SELECT id, 'dup',  id, ST_Length(TopoGeom_addElement(g, '{2,2}')) FROM tt.f_line WHERE id = 1;
+SELECT id, 'mis',  id, ST_Length(TopoGeom_remElement(g, '{1,2}')) FROM tt.f_line WHERE id = 1;
+
+
+DROP TABLE tt.f_line;
+select droptopology('tt');
diff --git a/topology/test/regress/topogeom_edit_expected b/topology/test/regress/topogeom_edit_expected
new file mode 100644 (file)
index 0000000..36c873a
--- /dev/null
@@ -0,0 +1,8 @@
+create|t
+simple_line_layer|1
+1|start|1|10
+1|add|1|30
+1|rem|1|20
+1|dup|1|20
+1|mis|1|20
+Topology 'tt' dropped
index a0979abbb47997a1892fff8eaad8aae0b1d95493..92af06f34e2962c4d6576e50988604f3dc186880 100644 (file)
@@ -1993,6 +1993,7 @@ LANGUAGE 'plpgsql' VOLATILE STRICT;
 #include "sql/topogeometry/cleartopogeom.sql.in"
 #include "sql/topogeometry/simplify.sql.in"
 #include "sql/topogeometry/totopogeom.sql.in"
+#include "sql/topogeometry/topogeom_edit.sql.in"
 
 --  Exports
 #include "sql/export/gml.sql.in"