[postgis-tickets] [SCM] PostGIS branch stable-3.1 updated. 3.1.1-24-gcdd2818

git at osgeo.org git at osgeo.org
Fri Mar 5 03:33:04 PST 2021


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, stable-3.1 has been updated
       via  cdd2818d0c3de6b2fde9b38552a0ca94e765141e (commit)
      from  fc2a3ab94ab5552cfefdf45ce7ca25a6b899eed0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit cdd2818d0c3de6b2fde9b38552a0ca94e765141e
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Mar 5 12:04:39 2021 +0100

    Fix SRID in Geometry(TopoGeometry) for empty TopoGeometry objects
    
    Includes testcase and NEWS item
    References #4871 in 3.1 branch (3.1.2dev)

diff --git a/NEWS b/NEWS
index 2dbee5b..50dc7b6 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PostGIS 3.1.2
 
  * Bug Fixes
 
+  - #4871, TopoGeometry::geometry cast returns NULL for empty
+           TopoGeometry objects (Sandro Santilli)
   - #4826, postgis_tiger_geocoder Better answers when no zip is provided
            (Regina Obe)
   - #4817, handle more complex compound coordinate dystems (Paul Ramsey)
diff --git a/topology/test/regress/geometry_cast.sql b/topology/test/regress/geometry_cast.sql
new file mode 100644
index 0000000..5e65870
--- /dev/null
+++ b/topology/test/regress/geometry_cast.sql
@@ -0,0 +1,51 @@
+\set VERBOSITY terse
+set client_min_messages to WARNING;
+
+select NULL FROM createtopology('tt', 4326);
+
+-- layer 1 is PUNTUAL
+CREATE TABLE tt.f_point(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_point', 'g', 'POINT');
+
+-- layer 2 is LINEAL
+CREATE TABLE tt.f_line(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_line', 'g', 'LINE');
+
+-- layer 3 is AREAL
+CREATE TABLE tt.f_area(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_area', 'g', 'POLYGON');
+
+-- layer 4 is MIXED
+CREATE TABLE tt.f_coll(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_coll', 'g', 'COLLECTION');
+
+-- layer 5 is HIERARCHICAL PUNTUAL
+CREATE TABLE tt.f_hier_point(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_hier_point', 'g', 'POINT', 1);
+
+-- layer 6 is HIERARCHICAL LINEAL
+CREATE TABLE tt.f_hier_line(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_hier_line', 'g', 'LINE', 2);
+
+-- layer 7 is HIERARCHICAL AREAL
+CREATE TABLE tt.f_hier_area(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_hier_area', 'g', 'POLYGON', 3);
+
+-- layer 8 is HIERARCHICAL MIXED
+CREATE TABLE tt.f_hier_coll(id serial);
+SELECT NULL FROM AddTopoGeometryColumn('tt', 'tt', 'f_hier_coll', 'g', 'COLLECTION', 4);
+
+
+-- Cast empties
+SELECT 'empty', 'puntal', ST_AsEWKT(CreateTopoGeom('tt', 1, 1)::geometry);
+SELECT 'empty', 'lineal', ST_AsEWKT(CreateTopoGeom('tt', 2, 2)::geometry);
+SELECT 'empty', 'areal', ST_AsEWKT(CreateTopoGeom('tt', 3, 3)::geometry);
+SELECT 'empty', 'mixed', ST_AsEWKT(CreateTopoGeom('tt', 4, 4)::geometry);
+
+SELECT 'empty', 'hier', 'puntal', ST_AsEWKT(CreateTopoGeom('tt', 1, 5)::geometry);
+SELECT 'empty', 'hier', 'lineal', ST_AsEWKT(CreateTopoGeom('tt', 2, 6)::geometry);
+SELECT 'empty', 'hier', 'areal', ST_AsEWKT(CreateTopoGeom('tt', 3, 7)::geometry);
+SELECT 'empty', 'hier', 'mixed', ST_AsEWKT(CreateTopoGeom('tt', 4, 8)::geometry);
+
+-- Cleanup
+SELECT NULL FROM DropTopology('tt');
diff --git a/topology/test/regress/geometry_cast_expected b/topology/test/regress/geometry_cast_expected
new file mode 100644
index 0000000..b692443
--- /dev/null
+++ b/topology/test/regress/geometry_cast_expected
@@ -0,0 +1,8 @@
+empty|puntal|SRID=4326;MULTIPOINT EMPTY
+empty|lineal|SRID=4326;MULTILINESTRING EMPTY
+empty|areal|SRID=4326;MULTIPOLYGON EMPTY
+empty|mixed|SRID=4326;GEOMETRYCOLLECTION EMPTY
+empty|hier|puntal|SRID=4326;MULTIPOINT EMPTY
+empty|hier|lineal|SRID=4326;MULTILINESTRING EMPTY
+empty|hier|areal|SRID=4326;MULTIPOLYGON EMPTY
+empty|hier|mixed|SRID=4326;GEOMETRYCOLLECTION EMPTY
diff --git a/topology/test/tests.mk b/topology/test/tests.mk
index f46097a..eb8b4b5 100644
--- a/topology/test/tests.mk
+++ b/topology/test/tests.mk
@@ -21,6 +21,7 @@ TESTS += \
 	$(topsrcdir)/topology/test/regress/createtopology.sql \
 	$(topsrcdir)/topology/test/regress/droptopogeometrycolumn.sql \
 	$(topsrcdir)/topology/test/regress/droptopology.sql \
+	$(topsrcdir)/topology/test/regress/geometry_cast.sql \
 	$(topsrcdir)/topology/test/regress/getedgebypoint.sql \
 	$(topsrcdir)/topology/test/regress/getfacebypoint.sql \
 	$(topsrcdir)/topology/test/regress/getnodebypoint.sql \
diff --git a/topology/topology.sql.in b/topology/topology.sql.in
index c08f1be..3c80866 100644
--- a/topology/topology.sql.in
+++ b/topology/topology.sql.in
@@ -1240,10 +1240,12 @@ LANGUAGE 'plpgsql' STABLE STRICT;
 -- }{
 CREATE OR REPLACE FUNCTION topology.Geometry(topogeom topology.TopoGeometry)
   RETURNS Geometry
-AS $$
+AS $BODY$
 DECLARE
   toponame varchar;
+  toposrid INT;
   geom geometry;
+  elements_count INT;
   rec RECORD;
   plyr RECORD;
   clyr RECORD;
@@ -1251,9 +1253,9 @@ DECLARE
 BEGIN
 
   -- Get topology name
-  SELECT name FROM topology.topology
+  SELECT name, srid FROM topology.topology
   WHERE id = topogeom.topology_id
-  INTO toponame;
+  INTO toponame, toposrid;
   IF toponame IS NULL THEN
     RAISE EXCEPTION 'Invalid TopoGeometry (unexistent topology id %)', topogeom.topology_id;
   END IF;
@@ -1303,15 +1305,41 @@ BEGIN
 
   ELSIF topogeom.type = 3 THEN -- [multi]polygon -- }{
 
-    sql := 'SELECT st_multi(st_union('
-         'topology.ST_GetFaceGeometry('
-      || quote_literal(toponame) || ','
-      || 'element_id))) as g FROM '
-      || quote_ident(toponame)
-      || '.relation WHERE topogeo_id = '
-      || topogeom.id || ' AND layer_id = '
-      || topogeom.layer_id || ' AND element_type = 3 ';
-    EXECUTE sql INTO geom;
+    sql := format(
+      $$
+SELECT
+  count(element_id),
+  ST_Multi(
+    ST_Union(
+      topology.ST_GetFaceGeometry(
+        %1$L,
+        element_id
+      )
+    )
+  ) as g
+FROM %1$I.relation
+WHERE topogeo_id = %2$L
+AND layer_id = %3$L
+AND element_type = 3
+      $$,
+      toponame,
+      topogeom.id,
+      topogeom.layer_id
+    );
+#ifdef POSTGIS_TOPOLOGY_DEBUG
+    RAISE DEBUG 'Query: %', sql;
+#endif
+    EXECUTE sql INTO elements_count, geom;
+
+#ifdef POSTGIS_TOPOLOGY_DEBUG
+    RAISE DEBUG 'TopoGeometry of type 3 (areal)'
+                ' in topo with srid % defined by % face elements'
+                ' casted to geometry with srid %',
+                toposrid,
+                elements_count,
+                ST_Srid(geom)
+    ;
+#endif
 
   ELSIF topogeom.type = 2 THEN -- [multi]line -- }{
 
@@ -1382,11 +1410,12 @@ BEGIN
     ELSE
       geom := 'GEOMETRYCOLLECTION EMPTY';
     END IF;
+    geom := ST_SetSRID(geom, toposrid);
   END IF;
 
   RETURN geom;
 END
-$$
+$BODY$
 LANGUAGE 'plpgsql' VOLATILE STRICT;
 --} Geometry(TopoGeometry)
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                         |  2 +
 topology/test/regress/geometry_cast.sql      | 51 ++++++++++++++++++++++++++
 topology/test/regress/geometry_cast_expected |  8 ++++
 topology/test/tests.mk                       |  1 +
 topology/topology.sql.in                     | 55 +++++++++++++++++++++-------
 5 files changed, 104 insertions(+), 13 deletions(-)
 create mode 100644 topology/test/regress/geometry_cast.sql
 create mode 100644 topology/test/regress/geometry_cast_expected


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list