[postgis-tickets] [SCM] PostGIS branch master updated. 3.3.0rc2-958-g4c776d418

git at osgeo.org git at osgeo.org
Thu Jun 1 09:07:11 PDT 2023


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  4c776d4180768aa12354c26a50dd8cee09a81f98 (commit)
       via  6a175c5413ba0376b9c22045850c5cab8e2b4dce (commit)
      from  57cbcb9424065edaf070c65ccc4377824dd94271 (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 4c776d4180768aa12354c26a50dd8cee09a81f98
Author: Sandro Santilli <strk at kbt.io>
Date:   Thu Jun 1 18:00:36 2023 +0200

    Never rely on tolerance-based point equality for topology code
    
    It sounds pretty dangerous and unwanted

diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c
index f83c4a9f9..df573fdde 100644
--- a/liblwgeom/lwgeom_topo.c
+++ b/liblwgeom/lwgeom_topo.c
@@ -864,7 +864,7 @@ lwt_AddIsoEdge( LWT_TOPOLOGY* topo, LWT_ELEMID startNode,
         /* l) Check that start point of acurve match start node geoms. */
         getPoint2d_p(geom->points, 0, &p1);
         getPoint2d_p(n->geom->point, 0, &p2);
-        if ( ! p2d_same(&p1, &p2) )
+        if ( ! P2D_SAME_STRICT(&p1, &p2) )
         {
           _lwt_release_nodes(endpoints, num_nodes);
           lwerror("SQL/MM Spatial exception - "
@@ -877,7 +877,7 @@ lwt_AddIsoEdge( LWT_TOPOLOGY* topo, LWT_ELEMID startNode,
         /* m) Check that end point of acurve match end node geoms. */
         getPoint2d_p(geom->points, geom->points->npoints-1, &p1);
         getPoint2d_p(n->geom->point, 0, &p2);
-        if ( ! p2d_same(&p1, &p2) )
+        if ( ! P2D_SAME_STRICT(&p1, &p2) )
         {
           _lwt_release_nodes(endpoints, num_nodes);
           lwerror("SQL/MM Spatial exception - "
@@ -1738,8 +1738,8 @@ _lwt_GetInteriorEdgePoint(const LWLINE* edge, POINT2D* ip)
   for (i=1; i<pa->npoints-1; ++i)
   {
     getPoint2d_p(pa, i, &tp); /* pick next point */
-    if ( p2d_same(&tp, &fp) ) continue; /* equal to startpoint */
-    if ( p2d_same(&tp, &lp) ) continue; /* equal to endpoint */
+    if ( P2D_SAME_STRICT(&tp, &fp) ) continue; /* equal to startpoint */
+    if ( P2D_SAME_STRICT(&tp, &lp) ) continue; /* equal to endpoint */
     /* this is a good one, neither same of start nor of end point */
     *ip = tp;
     return 1; /* found */
@@ -1749,7 +1749,7 @@ _lwt_GetInteriorEdgePoint(const LWLINE* edge, POINT2D* ip)
 
   /* interpolate if start point != end point */
 
-  if ( p2d_same(&fp, &lp) ) return 0; /* no distinct points in edge */
+  if ( P2D_SAME_STRICT(&fp, &lp) ) return 0; /* no distinct points in edge */
 
   ip->x = fp.x + ( (lp.x - fp.x) * 0.5 );
   ip->y = fp.y + ( (lp.y - fp.y) * 0.5 );
@@ -2424,7 +2424,7 @@ _lwt_AddEdge( LWT_TOPOLOGY* topo,
     {
       pa = start_node_geom->point;
       getPoint2d_p(pa, 0, &pn);
-      if ( ! p2d_same(&pn, &p1) )
+      if ( ! P2D_SAME_STRICT(&pn, &p1) )
       {
         if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
         lwerror("SQL/MM Spatial exception"
@@ -2445,7 +2445,7 @@ _lwt_AddEdge( LWT_TOPOLOGY* topo,
     {
       pa = end_node_geom->point;
       getPoint2d_p(pa, 0, &pn);
-      if ( ! p2d_same(&pn, &p2) )
+      if ( ! P2D_SAME_STRICT(&pn, &p2) )
       {
         if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
         lwerror("SQL/MM Spatial exception"
@@ -2962,9 +2962,9 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
     LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'first' point is %g,%g",
                 isoe->edge_id, p2.x, p2.y);
     LWDEBUGF(1, "Rings's 'from' point is still %g,%g", p1.x, p1.y);
-    if ( p2d_same(&p1, &p2) )
+    if ( P2D_SAME_STRICT(&p1, &p2) )
     {
-      LWDEBUG(1, "p2d_same(p1,p2) returned true");
+      LWDEBUG(1, "P2D_SAME_STRICT(p1,p2) returned true");
       LWDEBUGF(1, "First point of edge %" LWTFMT_ELEMID
                   " matches ring vertex %d", isoe->edge_id, from);
       /* first point matches, let's check next non-equal one */
@@ -2974,12 +2974,12 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
         LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'next' point %d is %g,%g",
                     isoe->edge_id, j, p2.x, p2.y);
         /* we won't check duplicated edge points */
-        if ( p2d_same(&p1, &p2) ) continue;
+        if ( P2D_SAME_STRICT(&p1, &p2) ) continue;
         /* we assume there are no duplicated points in ring */
         getPoint2d_p(ring, from+1, &pt);
         LWDEBUGF(1, "Ring's point %d is %g,%g",
                     from+1, pt.x, pt.y);
-        match = p2d_same(&pt, &p2);
+        match = P2D_SAME_STRICT(&pt, &p2);
         break; /* we want to check a single non-equal next vertex */
       }
 #if POSTGIS_DEBUG_LEVEL > 0
@@ -3000,7 +3000,7 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
       getPoint2d_p(epa, epa->npoints-1, &p2);
       LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'last' point is %g,%g",
                   isoe->edge_id, p2.x, p2.y);
-      if ( p2d_same(&p1, &p2) )
+      if ( P2D_SAME_STRICT(&p1, &p2) )
       {
         LWDEBUGF(1, "Last point of edge %" LWTFMT_ELEMID
                     " matches ring vertex %d", isoe->edge_id, from);
@@ -3011,12 +3011,12 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
           LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'prev' point %d is %g,%g",
                       isoe->edge_id, epa->npoints - j, p2.x, p2.y);
           /* we won't check duplicated edge points */
-          if ( p2d_same(&p1, &p2) ) continue;
+          if ( P2D_SAME_STRICT(&p1, &p2) ) continue;
           /* we assume there are no duplicated points in ring */
           getPoint2d_p(ring, from+1, &pt);
           LWDEBUGF(1, "Ring's point %d is %g,%g",
                       from+1, pt.x, pt.y);
-          match = p2d_same(&pt, &p2);
+          match = P2D_SAME_STRICT(&pt, &p2);
           break; /* we want to check a single non-equal next vertex */
         }
       }
@@ -3281,7 +3281,7 @@ lwt_ChangeEdgeGeom(LWT_TOPOLOGY* topo, LWT_ELEMID edge_id, LWLINE *geom)
    */
   getPoint2d_p(oldedge->geom->points, 0, &p1);
   getPoint2d_p(geom->points, 0, &pt);
-  if ( ! p2d_same(&p1, &pt) )
+  if ( ! P2D_SAME_STRICT(&p1, &pt) )
   {
     _lwt_release_edges(oldedge, 1);
     lwerror("SQL/MM Spatial exception - "
@@ -3307,7 +3307,7 @@ lwt_ChangeEdgeGeom(LWT_TOPOLOGY* topo, LWT_ELEMID edge_id, LWLINE *geom)
     return -1;
   }
   getPoint2d_p(geom->points, geom->points->npoints-1, &pt);
-  if ( ! p2d_same(&pt, &p2) )
+  if ( ! P2D_SAME_STRICT(&pt, &p2) )
   {
     _lwt_release_edges(oldedge, 1);
     lwerror("SQL/MM Spatial exception - "

commit 6a175c5413ba0376b9c22045850c5cab8e2b4dce
Author: Sandro Santilli <strk at kbt.io>
Date:   Thu Jun 1 17:15:08 2023 +0200

    Improve robustness of finding distinct vertices in topology edges
    
    Fixes #5394
    
    Includes regression test.
    Also augments precision in debug messages.

diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c
index d85ed6847..f83c4a9f9 100644
--- a/liblwgeom/lwgeom_topo.c
+++ b/liblwgeom/lwgeom_topo.c
@@ -43,6 +43,12 @@
 # define LWTFMT_ELEMID PRId64
 #endif
 
+/* This is a non-tolerance based 2d equality for points
+ * whereas the p2d_same function is tolerance based
+ * TODO: move in higher headers ?
+ */
+#define P2D_SAME_STRICT(a,b) ((a)->x == (b)->x && (a)->y == (b)->y)
+
 /*********************************************************************
  *
  * Backend iface
@@ -1425,7 +1431,7 @@ _lwt_FirstDistinctVertex2D(const POINTARRAY* pa, POINT2D *ref, int from, int dir
   {
     LWDEBUGF(1, "testing point %d", i);
     getPoint2d_p(pa, i, op); /* pick next point */
-    if ( p2d_same(op, &fp) ) continue; /* equal to startpoint */
+    if ( P2D_SAME_STRICT(op,&fp) ) continue; /* equal to startpoint */
     /* this is a good one, neither same of start nor of end point */
     return 1; /* found */
   }
@@ -1575,7 +1581,7 @@ _lwt_FindAdjacentEdges( LWT_TOPOLOGY* topo, LWT_ELEMID node, edgeend *data,
       }
       LWDEBUGF(1, "edge %" LWTFMT_ELEMID
                   " starts on node %" LWTFMT_ELEMID
-                  ", edgeend is %g,%g-%g,%g",
+                  ", edgeend is [%.15g %.15g,%.15g %.15g]",
                   edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
       if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
         LWT_ELEMID id = edge->edge_id;
@@ -1587,7 +1593,7 @@ _lwt_FindAdjacentEdges( LWT_TOPOLOGY* topo, LWT_ELEMID node, edgeend *data,
       }}
       azdif = az - data->myaz;
       LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
-                  ": %g (diff: %g)", edge->edge_id, az, azdif);
+                  ": %.15g (diff: %.15g)", edge->edge_id, az, azdif);
 
       if ( azdif < 0 ) azdif += 2 * M_PI;
       if ( minaz == -1 ) {
@@ -1636,7 +1642,7 @@ _lwt_FindAdjacentEdges( LWT_TOPOLOGY* topo, LWT_ELEMID node, edgeend *data,
         return -1;
       }
       LWDEBUGF(1, "edge %" LWTFMT_ELEMID " ends on node %" LWTFMT_ELEMID
-                  ", edgeend is %g,%g-%g,%g",
+                  ", edgeend is [%.15g %.15g,%.15g %.15g]",
                   edge->edge_id, node, p1.x, p1.y, p2.x, p2.y);
       if ( ! azimuth_pt_pt(&p1, &p2, &az) ) {{
         LWT_ELEMID id = edge->edge_id;
@@ -1648,7 +1654,7 @@ _lwt_FindAdjacentEdges( LWT_TOPOLOGY* topo, LWT_ELEMID node, edgeend *data,
       }}
       azdif = az - data->myaz;
       LWDEBUGF(1, "azimuth of edge %" LWTFMT_ELEMID
-                  ": %g (diff: %g)", edge->edge_id, az, azdif);
+                  ": %.15g (diff: %.15g)", edge->edge_id, az, azdif);
       if ( azdif < 0 ) azdif += 2 * M_PI;
       if ( minaz == -1 ) {
         minaz = maxaz = azdif;
diff --git a/topology/test/regress/topogeo_addpoint.sql b/topology/test/regress/topogeo_addpoint.sql
index 155db91af..da3d60add 100644
--- a/topology/test/regress/topogeo_addpoint.sql
+++ b/topology/test/regress/topogeo_addpoint.sql
@@ -64,3 +64,10 @@ SELECT 'tt2033', 'N' || topogeo_addpoint('t', 'POINT(0.2 1 1)', 0.5);
 SELECT 'tt2033', 'NC', node_id, ST_AsText(geom) FROM t.node ORDER BY node_id;
 SELECT 'tt2033.end' || DropTopology('t');
 
+-- See https://trac.osgeo.org/postgis/ticket/5394
+SELECT NULL FROM CreateTopology ('t');
+SELECT 'tt5394', 'E1', TopoGeo_addLinestring('t', 'LINESTRING(5.803580945500557 59.26346622,5.8035802635 59.263465501)' );
+SELECT 'tt5394', 'E2', TopoGeo_addLinestring('t', 'LINESTRING(5.8035802635 59.263465501,5.8035809455 59.26346622,5.803580945500557 59.26346622)' );
+SELECT 'tt5394', 'V', * FROM ValidateTopology('t');
+SELECT 'tt5394', 'N', TopoGeo_addPoint( 't', 'POINT(5.803646305 59.263416658000004)' );
+SELECT NULL FROM DropTopology('t');
diff --git a/topology/test/regress/topogeo_addpoint_expected b/topology/test/regress/topogeo_addpoint_expected
index fdc50c387..28dfbd31e 100644
--- a/topology/test/regress/topogeo_addpoint_expected
+++ b/topology/test/regress/topogeo_addpoint_expected
@@ -27,3 +27,6 @@ tt2033|NC|1|POINT Z (0 0 0)
 tt2033|NC|2|POINT Z (0 2 1)
 tt2033|NC|3|POINT Z (0 1 1)
 tt2033.endTopology 't' dropped
+tt5394|E1|1
+tt5394|E2|2
+tt5394|N|3

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

Summary of changes:
 liblwgeom/lwgeom_topo.c                         | 48 ++++++++++++++-----------
 topology/test/regress/topogeo_addpoint.sql      |  7 ++++
 topology/test/regress/topogeo_addpoint_expected |  3 ++
 3 files changed, 37 insertions(+), 21 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list