[SCM] PostGIS branch stable-3.5 updated. 3.5.0-18-ge36225e6c

git at osgeo.org git at osgeo.org
Tue Oct 29 08:51:31 PDT 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, stable-3.5 has been updated
       via  e36225e6cf84ba7e63c1da82ce79de94c695f57d (commit)
       via  158efb88c1ecc59c3dc195eed6a68bfe87fd9aaf (commit)
      from  c78843768d1075c642f1d4ab4886def3fdc0723a (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 e36225e6cf84ba7e63c1da82ce79de94c695f57d
Author: Björn Harrtell <bjorn at septima.dk>
Date:   Mon Oct 14 13:39:00 2024 +0200

    Short circuit contains check with shellbox check
    
    Optimizes _lwt_AddFaceSplit contains test by using bbox
    
    See https://github.com/postgis/postgis/pull/781

diff --git a/NEWS b/NEWS
index 97455de9c..49b861726 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,8 @@ PostgreSQL 12-17 required. GEOS 3.8+ required. Proj 6.1+ required.
 * Enhancements *
 
   - #5782, Improve robustness of min distance calculation (Sandro Santilli)
+  - Speedup topology building when closing large rings with many
+    hooles (Björn Harrtell)
 
 * Breaking Changes *
 
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index e79b2a961..e439dc7c0 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -2141,9 +2141,8 @@ _lwt_AddFaceSplit( LWT_TOPOLOGY* topo,
         return -2;
       }
 
-      /* IDEA: check that bounding box shortcut is taken, or use
-       *       shellbox to do it here */
-      contains = ptarray_contains_point(pa, &ep);
+      contains = gbox_contains_point2d(shellbox, &ep) == LW_TRUE ? LW_INSIDE : LW_OUTSIDE;
+      contains = contains == LW_INSIDE ? ptarray_contains_point(pa, &ep) : contains;
 
       LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " first point %s new ring",
           e->edge_id, (contains == LW_INSIDE ? "inside" :

commit 158efb88c1ecc59c3dc195eed6a68bfe87fd9aaf
Author: Sandro Santilli <strk at kbt.io>
Date:   Wed Oct 9 17:48:51 2024 +0200

    Check motion range upon snap/splitting edge to existing node
    
    Fixes #5792 in 3.5 branch (3.5.1dev)
    References #5786 (not resolving the problem)
    Includes regress test

diff --git a/NEWS b/NEWS
index 11ed157d0..97455de9c 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,8 @@ PostgreSQL 12-17 required. GEOS 3.8+ required. Proj 6.1+ required.
 
 * Bug fixes *
 
+- #5792, Prevent topology corruption with TopoGeo_addPoint near almost
+         collinear edges (Sandro Santilli)
 - #5795, Fix ST_NewEdgesSplit can cause invalid topology
          (Björn Harrtell)
 - #5794, Fix crash in TopoGeo_addPoint (Sandro Santilli)
@@ -17,7 +19,7 @@ PostgreSQL 12-17 required. GEOS 3.8+ required. Proj 6.1+ required.
          to allow pg_upgrade (Regina Obe)
 - #5800, PROJ compiled version reading the wrong minor and micro
          (Regina Obe)
-- #5790, Non-schema qualified calls causing issue with 
+- #5790, Non-schema qualified calls causing issue with
          materialized views (Regina Obe)
 
 * Enhancements *
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index c5accb28c..e79b2a961 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -5288,7 +5288,7 @@ _lwt_SnapEdgeToExistingNode(
   for ( n=0; n<2; ++n)
   {
     int forward;
-    /* TODO: directly get full existing edge rather than just id * */
+    /* TODO: directly get full existing edge rather than just id */
     LWT_ELEMID existingEdgeId = _lwt_GetEqualEdge( topo, lwgeom_as_lwline(splitC->geoms[n]), &forward );
     if ( existingEdgeId == -1 )
     {
@@ -5409,8 +5409,74 @@ _lwt_SnapEdgeToExistingNode(
       splitNodeNewEdgeOutgoing = 0;
     }
 
-    /* TODO: check that newSplitEdgeLine part does not crosses any other edge ? */
+    /* TODO: check that newSplitEdgeLine part does not cross any other edge ? */
     /* TODO: check that newSplitEdgeLine retains its position in the edge end star (see ticket #5786) */
+    /* TODO: check that the motion range does not contain any node
+
+    {{
+      // build the motion range shape: splitC->geoms[0] + splitC->geoms[1] - edge->geom
+      POINTARRAY *motionRange = ptarray_clone_deep(lwgeom_as_lwline(splitC->geoms[0])->points);
+      ptarray_append_ptarray(motionRange, lwgeom_as_lwline(splitC->geoms[1])->points, 0);
+      POINTARRAY *reverseNewLine = ptarray_clone_deep(edge->geom->points);
+      ptarray_reverse_in_place(reverseNewLine);
+      ptarray_append_ptarray(motionRange, reverseNewLine, 0);
+      ptarray_free(reverseNewLine);
+
+      // motionBounds takes ownership of motionRange
+      LWLINE *motionBounds = lwline_construct(topo->srid, NULL, motionRange);
+
+      // motionPoly takes ownership of motionBounds
+      LWGEOM *motionPoly = (LWGEOM *)lwpoly_from_lwlines(motionBounds, 0, NULL);
+
+      LWDEBUGG(1, motionPoly, "Motion range");
+
+      // check the Motion range doesn't cover any of
+      // the edges incident to the split node other
+      // than the existing edge
+      GEOSGeometry *motionPolyG = NULL;
+      for ( uint64_t t=0; t<splitNodeEdges->numEdges; t++ )
+      {
+        LWT_ISO_EDGE *e = &(splitNodeEdges->edges[t]);
+        GEOSGeometry *eg;
+        if ( e == existingEdge ) continue;
+        if ( e == edge ) continue;
+        if ( ! motionPolyG ) {
+          motionPolyG = LWGEOM2GEOS( motionPoly, 0 );
+          if ( ! motionPolyG )
+          {
+            lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
+            return -1;
+          }
+        }
+        eg = LWGEOM2GEOS( lwline_as_lwgeom(e->geom), 0 );
+        if ( ! eg )
+        {
+          lwerror("Could not convert edge geometry to GEOS: %s", lwgeom_geos_errmsg);
+          return -1;
+        }
+
+        int covers = GEOSCovers( motionPolyG, eg );
+        // TODO: use preparedCovers ?
+        GEOSGeom_destroy(eg);
+        if (covers == 2)
+        {
+          lwerror("Covers error: %s", lwgeom_geos_errmsg);
+          return -1;
+        }
+        if ( covers )
+        {
+          lwgeom_free(motionPoly);
+          lwerror("snapping edge %" LWTFMT_ELEMID
+            " to new node moves it past edge %" LWTFMT_ELEMID,
+            edge->edge_id, e->edge_id
+          );
+          return -1;
+        }
+      }
+      if ( motionPolyG ) GEOSGeom_destroy(motionPolyG);
+
+      lwgeom_free(motionPoly);
+    }}
 
     LWDEBUGF(1, "Existing edge %"
         LWTFMT_ELEMID " (post-modEdgeSplit) next_right:%"
diff --git a/topology/test/regress/topogeo_addpoint_merge_edges.sql b/topology/test/regress/topogeo_addpoint_merge_edges.sql
index fc0fff28d..1cc0d59bf 100644
--- a/topology/test/regress/topogeo_addpoint_merge_edges.sql
+++ b/topology/test/regress/topogeo_addpoint_merge_edges.sql
@@ -425,4 +425,20 @@ SELECT * FROM runTest('multi-merge-closest-not-containing-projected',
   ], 'POINT(12.472410859513998 70.77020397757477)', 0
 ) WHERE true ;
 
+
+SELECT * FROM runTest('#5792.0',
+  ARRAY[
+    'LINESTRING(11.812075769533624 59.77938755222866,11.811862389533625 59.77938237222866)',
+    'LINESTRING(11.811862389533625 59.77938237222866,11.811969079533624 59.77938496222866,11.812075769533624 59.77938755222866)'
+  ], 'POINT(11.812029186127067 59.7793864213727)', 0
+) WHERE true ;
+
+SELECT * FROM runTest('#5792.1',
+  ARRAY[
+    'LINESTRING(11.812075769533624 59.77938755222866,11.811862389533625 59.77938237222866)',
+    'LINESTRING(11.811862389533625 59.77938237222866,11.811969079533624 59.77938496222866,11.812075769533624 59.77938755222866)',
+    'LINESTRING(11.811862389533625 59.77938237222866,11.811969079533624 59.77938,11.812075769533624 59.77938755222866)'
+  ], 'POINT(11.812029186127067 59.7793864213727)', 0
+) WHERE true ;
+
 DROP FUNCTION runTest(text, geometry[], geometry, float8, bool);
diff --git a/topology/test/regress/topogeo_addpoint_merge_edges_expected b/topology/test/regress/topogeo_addpoint_merge_edges_expected
index 90b2a3d21..994187546 100644
--- a/topology/test/regress/topogeo_addpoint_merge_edges_expected
+++ b/topology/test/regress/topogeo_addpoint_merge_edges_expected
@@ -29,3 +29,5 @@ full-merge-exterior-face|-checking-
 double-merge-forward-backward|-checking-
 multi-merge-forward-backward|-checking-
 multi-merge-closest-not-containing-projected|-checking-
+ERROR:  snapping edge 2 to new node moves it past edge 3
+ERROR:  snapping edge 2 to new node moves it past edge 3

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

Summary of changes:
 NEWS                                               |  6 +-
 liblwgeom/topo/lwgeom_topo.c                       | 75 ++++++++++++++++++++--
 .../test/regress/topogeo_addpoint_merge_edges.sql  | 16 +++++
 .../regress/topogeo_addpoint_merge_edges_expected  |  2 +
 4 files changed, 93 insertions(+), 6 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list