[SCM] PostGIS branch master updated. 3.4.0rc1-933-gd47bde26b

git at osgeo.org git at osgeo.org
Fri Feb 16 12:48:42 PST 2024


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, master has been updated
       via  d47bde26b885728ff281abe51c00701a4114d2c4 (commit)
       via  e73ac562025b9ee384cbc917aff34aeabdf164a7 (commit)
       via  d2c16dc4113c9ff0bb45c6c9f665cf2e0d04ff57 (commit)
      from  8779495f92373e7b88716186d75f59ff5106b6cb (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 d47bde26b885728ff281abe51c00701a4114d2c4
Author: Sandro Santilli <strk at kbt.io>
Date:   Wed Aug 5 10:19:50 2020 +0200

    Rewrite ST_CreateTopoGeo to postpone face detection
    
    This was found to be faster for building the topology
    in current topology/test/perf/ST_CreateTopoGeo.sql
    (x2 improvement)

diff --git a/NEWS b/NEWS
index 4ab25172d..552949919 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,7 @@ To take advantage of all SFCGAL featurs, SFCGAL 1.5.0+ is needed.
 
 * Enhancements *
 
+  - #5670, faster ST_CreateTopoGeo (Sandro Santilli)
   - #5531, documentation format upgraded to DocBook 5 (Sandro Santilli)
   - #5543, allow building without documentation (Sandro Santilli)
   - #5596, GH-749, Allow promoting column as an id
diff --git a/topology/sql/sqlmm.sql.in b/topology/sql/sqlmm.sql.in
index ec2d02c5e..6b95da8da 100644
--- a/topology/sql/sqlmm.sql.in
+++ b/topology/sql/sqlmm.sql.in
@@ -3,7 +3,7 @@
 -- PostGIS - Spatial Types for PostgreSQL
 -- http://postgis.net
 --
--- Copyright (C) 2010-2015 Sandro Santilli <strk at kbt.io>
+-- Copyright (C) 2010-2024 Sandro Santilli <strk at kbt.io>
 -- Copyright (C) 2005 Refractions Research Inc.
 --
 -- This is free software; you can redistribute and/or modify it under
@@ -401,14 +401,9 @@ RETURNS text
 AS
 $$
 DECLARE
-  typ char(4);
   rec RECORD;
-  ret int;
-  nodededges GEOMETRY;
   points GEOMETRY;
-  snode_id int;
-  enode_id int;
-  tolerance FLOAT8;
+  nodededges GEOMETRY;
   topoinfo RECORD;
 BEGIN
 
@@ -476,10 +471,10 @@ BEGIN
   WITH components AS ( SELECT geom FROM ST_Dump(acollection) )
   SELECT ST_UnaryUnion(ST_Collect(geom)) FROM (
     SELECT geom FROM components
-      WHERE ST_Dimension(geom) = 1
-    UNION ALL
+    WHERE ST_Dimension(geom) = 1
+      UNION ALL
     SELECT ST_Boundary(geom) FROM components
-      WHERE ST_Dimension(geom) = 2
+    WHERE ST_Dimension(geom) = 2
   ) as linework INTO STRICT nodededges;
 
 #ifdef POSTGIS_TOPOLOGY_DEBUG
@@ -524,44 +519,56 @@ BEGIN
 #endif
   END IF; -- points is not null
 
-  --
-  -- Collect all nodes (from points and noded linework endpoints)
-  --
-
-  WITH edges AS ( SELECT geom FROM ST_Dump(nodededges) )
-  SELECT ST_Union( -- TODO: ST_UnaryUnion ?
-          COALESCE(ST_UnaryUnion(ST_Collect(geom)),
-            ST_SetSRID('POINT EMPTY'::geometry, topoinfo.SRID)),
-          COALESCE(points,
-            ST_SetSRID('POINT EMPTY'::geometry, topoinfo.SRID))
-         )
-  FROM (
-    SELECT ST_StartPoint(geom) as geom FROM edges
-      UNION ALL
-    SELECT ST_EndPoint(geom) FROM edges
-  ) as endpoints INTO points;
-
-#ifdef POSTGIS_TOPOLOGY_DEBUG
-  RAISE DEBUG 'Total nodes count: %', ST_NumGeometries(points);
-#endif
 
   --
-  -- Add all nodes as isolated so that
-  -- later calls to AddEdgeModFace will tweak their being
-  -- isolated or not...
+  -- Add pivot face (-1 id)
   --
-  FOR rec IN SELECT geom FROM ST_Dump(points)
+  EXECUTE format('INSERT INTO %I.face(face_id) VALUES (-1)', atopology);
+
+  --
+  -- Collect possibly isolated points, to add later
+  --
+  WITH components AS ( SELECT geom FROM ST_Dump(acollection) )
+  SELECT ST_Union(geom) FROM components
+  WHERE ST_Dimension(geom) = 0
+  INTO STRICT points;
+
+  --
+  -- Add all linework
+  -- NOTE: we do this in an ordered way to be predictable
+  --
+  FOR rec IN
+    WITH linework AS ( SELECT geom FROM ST_Dump(nodededges) )
+    SELECT topology.TopoGeo_addLinestring(
+      atopology, geom, 0,
+      skipFaceSplitDetection => true
+    )
+    FROM linework
+    ORDER BY geom
   LOOP
-    PERFORM topology.ST_AddIsoNode(atopology, 0, rec.geom);
   END LOOP;
 
-  FOR rec IN SELECT geom FROM ST_Dump(nodededges)
+  --
+  -- Register all faces
+  --
+  PERFORM topology._RegisterMissingFaces(atopology);
+
+
+  --
+  -- Delete pivot face (-1 id)
+  --
+  EXECUTE format('DELETE FROM %I.face WHERE face_id = -1', atopology);
+
+  --
+  -- Add collected points so isolated ones get correctly
+  -- marked as being in their face
+  -- NOTE: we do this in an ordered way to be predictable
+  --
+  FOR rec IN SELECT geom FROM
+    ( SELECT * FROM ST_Dump(points) ) foo
+    ORDER BY geom
   LOOP
-    SELECT topology.GetNodeByPoint(atopology, st_startpoint(rec.geom), 0)
-      INTO STRICT snode_id;
-    SELECT topology.GetNodeByPoint(atopology, st_endpoint(rec.geom), 0)
-      INTO STRICT enode_id;
-    PERFORM topology.ST_AddEdgeModFace(atopology, snode_id, enode_id, rec.geom);
+    PERFORM topology.TopoGeo_addPoint(atopology, rec.geom);
   END LOOP;
 
   RETURN 'Topology ' || atopology || ' populated';
diff --git a/topology/test/regress/st_createtopogeo_expected b/topology/test/regress/st_createtopogeo_expected
index da3243ee1..c7ac08e75 100644
--- a/topology/test/regress/st_createtopogeo_expected
+++ b/topology/test/regress/st_createtopogeo_expected
@@ -33,7 +33,7 @@ T13|1 isolated nodes in face 0
 T13|1 isolated nodes in face 5
 T14|GEOMETRYCOLLECTION(LINESTRING(8 30,16 30,16 38,3 38,3 30,8 30),POINT(4 31),LINESTRING(4 31,7 31,7 34,4 34,4 31),POINT(8 30),POINT(9 6),LINESTRING(9 6,9 14),LINESTRING(9 6,21 6),POLYGON((9 14,21 14,21 6,9 6,9 14)),POINT(9 14),LINESTRING(9 14,9 22),LINESTRING(9 14,21 14),POLYGON((9 22,21 22,21 14,9 14,9 22)),POINT(9 22),LINESTRING(9 22,21 22),POINT(9 35),LINESTRING(9 35,13 35),POINT(13 35),POLYGON((25 30,17 30,17 40,31 40,31 30,25 30)),POINT(20 37),POINT(21 6),LINESTRING(21 6,21 14),LINESTRING(21 6,35 6),POLYGON((21 14,35 14,35 6,21 6,21 14)),POINT(21 14),LINESTRING(21 14,21 22),LINESTRING(35 14,21 14),POLYGON((21 22,35 22,35 14,21 14,21 22)),POINT(21 22),LINESTRING(21 22,35 22),POINT(25 30),LINESTRING(25 30,25 35),POINT(25 35),POINT(35 6),LINESTRING(35 6,35 14),LINESTRING(35 6,47 6),POLYGON((35 14,47 14,47 6,35 6,35 14)),POINT(35 14),LINESTRING(35 14,35 22),LINESTRING(35 14,47 14),POLYGON((35 22,47 22,47 14,35 14,35 22)),POINT(35 22),LINESTRING(35 22,47 22),LINESTRING(36 38,38 35
 ,41 34,42 33,45 32,47 28,50 28,52 32,57 33),POINT(36 38),LINESTRING(41 40,45 40,47 42,62 41,61 38,59 39,57 36,57 33),POINT(41 40),POINT(47 6),LINESTRING(47 6,47 14),POINT(47 14),LINESTRING(47 14,47 22),POINT(47 22),POINT(57 33))
 T14|22 nodes|24 edges|9 faces
-T14|1 isolated nodes in face 3
+T14|1 isolated nodes in face 7
 T15|GEOMETRYCOLLECTION(LINESTRING(-5 -2,0 0),LINESTRING(0 0,10 10),LINESTRING(0 0,5 2,10 10),LINESTRING(10 10,12 10))
 T15|4 nodes|4 edges|1 faces
 T16|GEOMETRYCOLLECTION(LINESTRING(0 0,10 0),LINESTRING(0 3,20 4),LINESTRING(10 0,20 4))

commit e73ac562025b9ee384cbc917aff34aeabdf164a7
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Jun 25 12:42:24 2021 +0200

    Add internal _RegisterMissingFaces SQL function

diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c
index 0d4872d48..cbf461f00 100644
--- a/topology/postgis_topology.c
+++ b/topology/postgis_topology.c
@@ -5509,3 +5509,44 @@ Datum GetFaceContainingPoint(PG_FUNCTION_ARGS)
   SPI_finish();
   PG_RETURN_INT32(face_id);
 }
+
+/*  RegisterMissingFaces(atopology) */
+Datum RegisterMissingFaces(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(RegisterMissingFaces);
+Datum RegisterMissingFaces(PG_FUNCTION_ARGS)
+{
+  text* toponame_text;
+  char* toponame;
+  LWT_TOPOLOGY *topo;
+
+  toponame_text = PG_GETARG_TEXT_P(0);
+  toponame = text_to_cstring(toponame_text);
+  PG_FREE_IF_COPY(toponame_text, 0);
+
+  if ( SPI_OK_CONNECT != SPI_connect() ) {
+    lwpgerror("Could not connect to SPI");
+    PG_RETURN_NULL();
+  }
+
+  {
+    int pre = be_data.topoLoadFailMessageFlavor;
+    be_data.topoLoadFailMessageFlavor = 1;
+    topo = lwt_LoadTopology(be_iface, toponame);
+    be_data.topoLoadFailMessageFlavor = pre;
+  }
+  pfree(toponame);
+  if ( ! topo ) {
+    /* should never reach this point, as lwerror would raise an exception */
+    SPI_finish();
+    PG_RETURN_NULL();
+  }
+
+  POSTGIS_DEBUG(1, "Calling lwt_Polygonize");
+  lwt_Polygonize(topo);
+  POSTGIS_DEBUG(1, "lwt_Polygonize returned");
+  lwt_FreeTopology(topo);
+
+  SPI_finish();
+
+  PG_RETURN_NULL();
+}
diff --git a/topology/sql/populate.sql.in b/topology/sql/populate.sql.in
index e024a9809..6788633c6 100644
--- a/topology/sql/populate.sql.in
+++ b/topology/sql/populate.sql.in
@@ -740,3 +740,8 @@ END
 $$
 LANGUAGE 'plpgsql';
 --} TopoGeo_AddGeometry
+
+CREATE OR REPLACE FUNCTION topology._RegisterMissingFaces(atopology varchar)
+	RETURNS void AS
+	'MODULE_PATHNAME', 'RegisterMissingFaces'
+  LANGUAGE 'c' VOLATILE;

commit d2c16dc4113c9ff0bb45c6c9f665cf2e0d04ff57
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Jun 25 12:37:01 2021 +0200

    Add optional skipFaceSplitDetection to TopoGeo_addLinestring SQL function
    
    Defaults to false, can be set to true to skip computing face splits
    to perform batch topology loading. Requires presence of a record
    with face_id = -1 in the face table as a pivot value.

diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c
index c47d9e4f6..0d4872d48 100644
--- a/topology/postgis_topology.c
+++ b/topology/postgis_topology.c
@@ -3,7 +3,7 @@
  * PostGIS - Spatial Types for PostgreSQL
  * http://postgis.net
  *
- * Copyright (C) 2015-2021 Sandro Santilli <strk at kbt.io>
+ * Copyright (C) 2015-2024 Sandro Santilli <strk at kbt.io>
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU General Public Licence. See the COPYING file.
@@ -5069,6 +5069,7 @@ Datum TopoGeo_AddLinestring(PG_FUNCTION_ARGS)
   FACEEDGESSTATE *state;
   Datum result;
   LWT_ELEMID id;
+  bool skipFace = false;
 
   if (SRF_IS_FIRSTCALL())
   {
@@ -5131,9 +5132,18 @@ Datum TopoGeo_AddLinestring(PG_FUNCTION_ARGS)
       PG_RETURN_NULL();
     }
 
-    POSTGIS_DEBUG(1, "Calling lwt_AddLine");
-    elems = lwt_AddLine(topo, ln, tol, &nelems);
-    POSTGIS_DEBUG(1, "lwt_AddLine returned");
+    if ( PG_NARGS() > 3 ) {
+      skipFace = PG_GETARG_BOOL(3);
+    }
+
+    if ( skipFace ) {
+      POSTGIS_DEBUG(1, "Calling lwt_AddLineNoFace");
+      elems = lwt_AddLineNoFace(topo, ln, tol, &nelems);
+    } else {
+      POSTGIS_DEBUG(1, "Calling lwt_AddLine");
+      elems = lwt_AddLine(topo, ln, tol, &nelems);
+    }
+    POSTGIS_DEBUG(1, "lwt_AddLine* returned");
     lwgeom_free(lwgeom);
     PG_FREE_IF_COPY(geom, 1);
     lwt_FreeTopology(topo);
diff --git a/topology/sql/populate.sql.in b/topology/sql/populate.sql.in
index 361f13a71..e024a9809 100644
--- a/topology/sql/populate.sql.in
+++ b/topology/sql/populate.sql.in
@@ -3,7 +3,7 @@
 -- PostGIS - Spatial Types for PostgreSQL
 -- http://postgis.net
 --
--- Copyright (C) 2010-2012 Sandro Santilli <strk at kbt.io>
+-- Copyright (C) 2010-2024 Sandro Santilli <strk at kbt.io>
 --
 -- This is free software; you can redistribute and/or modify it under
 -- the terms of the GNU General Public Licence. See the COPYING file.
@@ -698,12 +698,16 @@ CREATE OR REPLACE FUNCTION topology.TopoGeo_AddPoint(atopology varchar, apoint g
 --} TopoGeo_AddPoint
 
 --{
---  TopoGeo_addLinestring(toponame, linegeom, tolerance)
+-- TopoGeo_addLinestring(toponame, linegeom, tolerance=0, skipFaceSplitDetection=false)
 --
---  Add a LineString into a topology
+-- Add a LineString into a topology
+--
+-- Availability: 2.0.0
+-- Changed: 3.5.0 - add skipFaceSplitDetection optional parameter
+-- Replaces TopoGeo_addLinestring(varchar, geometry, float8) deprecated in 3.5.0
 --
 -- }{
-CREATE OR REPLACE FUNCTION topology.TopoGeo_addLinestring(atopology varchar, aline geometry, tolerance float8 DEFAULT 0)
+CREATE OR REPLACE FUNCTION topology.TopoGeo_addLinestring(atopology varchar, aline geometry, tolerance float8 DEFAULT 0, skipFaceSplitDetection bool DEFAULT false)
 	RETURNS SETOF int AS
 	'MODULE_PATHNAME', 'TopoGeo_AddLinestring'
   LANGUAGE 'c' VOLATILE;

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

Summary of changes:
 NEWS                                            |  1 +
 topology/postgis_topology.c                     | 59 ++++++++++++++++--
 topology/sql/populate.sql.in                    | 17 +++--
 topology/sql/sqlmm.sql.in                       | 83 ++++++++++++++-----------
 topology/test/regress/st_createtopogeo_expected |  2 +-
 5 files changed, 115 insertions(+), 47 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list