[SCM] PostGIS branch stable-3.3 updated. 3.3.6-13-g850982a19

git at osgeo.org git at osgeo.org
Fri Mar 22 10:38:55 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.3 has been updated
       via  850982a195fca5c08faddc1a4d929a3c6c3d378f (commit)
      from  96145b118098e1e4723438c4bafef11826c7ec87 (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 850982a195fca5c08faddc1a4d929a3c6c3d378f
Author: Sandro Santilli <strk at kbt.io>
Date:   Fri Mar 22 18:17:10 2024 +0100

    Fix lwline_split_by_point_to determination of boundary points
    
    Replaces tolerance-based p4d_same usage with the stricter
    P4D_SAME_STRICT macro, now exposed in liblwgeom_internal.h
    
    Closes #5698 in 3.3 branch (3.3.7dev)
    
    Includes unit test for lwline_split_by_point_to
    and regress test for TopoGeo_addPoint

diff --git a/NEWS b/NEWS
index 2ec6557bf..77ffb6495 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ xxxx/xx/xx
 
 * Bug Fixes and Enhancements *
 
+ - #5698, Fix robustness issue splitting line by vertex very close to endpoints,
+          affecting topology population functions (Sandro Santilli)
  - #5649, ST_Value should return NULL on missing band (Paul Ramsey)
  - #5677, ST_Union(geom[]) should unary union single entry arrays (Paul Ramsey)
  - #5679, Remove spurious COMMIT statements from sfcgal script
diff --git a/liblwgeom/cunit/cu_split.c b/liblwgeom/cunit/cu_split.c
index edbf00aa4..223fcd071 100644
--- a/liblwgeom/cunit/cu_split.c
+++ b/liblwgeom/cunit/cu_split.c
@@ -271,6 +271,18 @@ static void test_lwgeom_split(void)
 	lwgeom_free(ret);
 	lwgeom_free(geom);
 	lwgeom_free(blade);
+
+	/* See #5698 -- robustness issue */
+	geom = lwgeom_from_wkt("LINESTRING(15.796760167740288 69.05714853429149,15.796760167739626 69.05714853429157,15.795906966300288 69.05725770093837)", LW_PARSER_CHECK_NONE);
+	CU_ASSERT_FATAL(geom != NULL);
+	blade = lwpoint_as_lwgeom(lwline_get_lwpoint(lwgeom_as_lwline(geom), 1));
+	CU_ASSERT(blade != NULL);
+	ret = lwgeom_split(geom, blade);
+	CU_ASSERT_FATAL(ret != NULL);
+	ASSERT_INT_EQUAL( lwgeom_as_lwcollection(ret)->ngeoms, 2 );
+	lwgeom_free(ret);
+	lwgeom_free(geom);
+	lwgeom_free(blade);
 }
 
 static int
diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h
index 4fa50ddc3..8fae3a8e6 100644
--- a/liblwgeom/liblwgeom_internal.h
+++ b/liblwgeom/liblwgeom_internal.h
@@ -247,12 +247,21 @@ lwvarlena_t *geohash_point(double longitude, double latitude, int precision);
 void decode_geohash_bbox(char *geohash, double *lat, double *lon, int precision);
 
 /*
-* Point comparisons
+* Point comparisons (FP tolerance based)
 */
 int p4d_same(const POINT4D *p1, const POINT4D *p2);
 int p3d_same(const POINT3D *p1, const POINT3D *p2);
 int p2d_same(const POINT2D *p1, const POINT2D *p2);
 
+/*
+ * Non-tolerance based equality for points
+ * whereas the p#d_same function are tolerance based
+ */
+#define P2D_SAME_STRICT(a,b) ((a)->x == (b)->x && (a)->y == (b)->y)
+#define P3DZ_SAME_STRICT(a,b) ((a)->x == (b)->x && (a)->y == (b)->y && (a)->z == (b)->z )
+#define P3DM_SAME_STRICT(a,b) ((a)->x == (b)->x && (a)->y == (b)->y && (a)->m == (b)->m )
+#define P4D_SAME_STRICT(a,b) ((a)->x == (b)->x && (a)->y == (b)->y && (a)->z == (b)->z && (a)->m == (b)->m )
+
 /*
 * Area calculations
 */
diff --git a/liblwgeom/lwgeom_geos_split.c b/liblwgeom/lwgeom_geos_split.c
index 83038a485..58f7f2725 100644
--- a/liblwgeom/lwgeom_geos_split.c
+++ b/liblwgeom/lwgeom_geos_split.c
@@ -240,7 +240,7 @@ lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in,
 	{
 		getPoint4d_p(ipa, i+1, &p2);
 		double dist_sqr = distance2d_sqr_pt_seg((POINT2D *)&pt, (POINT2D *)&p1, (POINT2D *)&p2);
-		LWDEBUGF(4, "Distance (squared) of point %g %g to segment %g %g, %g %g: %g",
+		LWDEBUGF(4, "Distance (squared) of point %.15g %.15g to segment %.15g %.15g, %.15g %.15g: %.15g",
 				 pt.x, pt.y,
 				 p1.x, p1.y,
 				 p2.x, p2.y,
@@ -256,7 +256,7 @@ lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in,
 	}
 
 	LWDEBUGF(3, "Closest segment: %d", seg);
-	LWDEBUGF(3, "mindist: %g", mindist_sqr);
+	LWDEBUGF(3, "mindist: %.15g", mindist_sqr);
 
 	/* No intersection */
 	if (mindist_sqr > 0)
@@ -280,11 +280,11 @@ lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in,
 	pt_projected.x = pt.x;
 	pt_projected.y = pt.y;
 
-	LWDEBUGF(3, "Projected point:(%g %g), seg:%d, p1:(%g %g), p2:(%g %g)", pt_projected.x, pt_projected.y, seg, p1.x, p1.y, p2.x, p2.y);
+	LWDEBUGF(3, "Projected point:(%.15g %.15g), seg:%d, p1:(%.15g %.15g), p2:(%.15g %.15g)", pt_projected.x, pt_projected.y, seg, p1.x, p1.y, p2.x, p2.y);
 
 	/* When closest point == an endpoint, this is a boundary intersection */
-	if ( ( (seg == nsegs-1) && p4d_same(&pt_projected, &p2) ) ||
-	     ( (seg == 0)       && p4d_same(&pt_projected, &p1) ) )
+	if ( ( (seg == nsegs-1) && P4D_SAME_STRICT(&pt_projected, &p2) ) ||
+	     ( (seg == 0)       && P4D_SAME_STRICT(&pt_projected, &p1) ) )
 	{
 		return 1;
 	}
diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c
index a8b0a2e50..8ed0deff2 100644
--- a/liblwgeom/lwgeom_topo.c
+++ b/liblwgeom/lwgeom_topo.c
@@ -43,12 +43,6 @@
 # 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
diff --git a/topology/test/regress/topogeo_addpoint.sql b/topology/test/regress/topogeo_addpoint.sql
index da3d60add..1d5ad1894 100644
--- a/topology/test/regress/topogeo_addpoint.sql
+++ b/topology/test/regress/topogeo_addpoint.sql
@@ -71,3 +71,10 @@ SELECT 'tt5394', 'E2', TopoGeo_addLinestring('t', 'LINESTRING(5.8035802635 59.26
 SELECT 'tt5394', 'V', * FROM ValidateTopology('t');
 SELECT 'tt5394', 'N', TopoGeo_addPoint( 't', 'POINT(5.803646305 59.263416658000004)' );
 SELECT NULL FROM DropTopology('t');
+
+-- See https://trac.osgeo.org/postgis/ticket/5698
+SELECT NULL FROM CreateTopology ('t');
+SELECT 't5698', 'E', TopoGeo_addLinestring('t', 'LINESTRING( 15.796760167740288 69.05714853429149, 15.795906966300288 69.05725770093837)' );
+SELECT 't5698', 'N', TopoGeo_addPoint( 't', 'POINT(15.796760167739626 69.05714853429157)');
+SELECT 't5698', 'V', * FROM ValidateTopology('t');
+SELECT NULL FROM DropTopology('t');
diff --git a/topology/test/regress/topogeo_addpoint_expected b/topology/test/regress/topogeo_addpoint_expected
index 28dfbd31e..bf28121eb 100644
--- a/topology/test/regress/topogeo_addpoint_expected
+++ b/topology/test/regress/topogeo_addpoint_expected
@@ -30,3 +30,5 @@ tt2033.endTopology 't' dropped
 tt5394|E1|1
 tt5394|E2|2
 tt5394|N|3
+t5698|E|1
+t5698|N|3

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

Summary of changes:
 NEWS                                            |  2 ++
 liblwgeom/cunit/cu_split.c                      | 12 ++++++++++++
 liblwgeom/liblwgeom_internal.h                  | 11 ++++++++++-
 liblwgeom/lwgeom_geos_split.c                   | 10 +++++-----
 liblwgeom/lwgeom_topo.c                         |  6 ------
 topology/test/regress/topogeo_addpoint.sql      |  7 +++++++
 topology/test/regress/topogeo_addpoint_expected |  2 ++
 7 files changed, 38 insertions(+), 12 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list