[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