[postgis-tickets] [SCM] PostGIS branch stable-3.0 updated. 3.0.9-8-g95810c248
git at osgeo.org
git at osgeo.org
Tue Oct 10 03:11:46 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, stable-3.0 has been updated
via 95810c248bd9c6dbee55031d6712614e5a273673 (commit)
via bae93ad34b1c6b4c4895ad6684a05aac5be2209f (commit)
from d261a811810575f7aab12dc5e397a4a42f93dabf (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 95810c248bd9c6dbee55031d6712614e5a273673
Author: Sandro Santilli <strk at kbt.io>
Date: Thu Sep 7 16:57:53 2023 +0200
Normalize results from ST_DelaunayTriangles
GEOS recent commit changed starting point of polygon rings
ref: https://debbie.postgis.net/view/GEOS/job/GEOS_Master/1793/
diff --git a/regress/core/delaunaytriangles.sql b/regress/core/delaunaytriangles.sql
index 18589e05d..efc561029 100644
--- a/regress/core/delaunaytriangles.sql
+++ b/regress/core/delaunaytriangles.sql
@@ -1,12 +1,11 @@
--- TODO: normalize !
-SELECT 1, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9)'::geometry));
-SELECT 2, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry));
-SELECT 3, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 2));
-SELECT 4, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 2, 1));
-SELECT 5, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9)'::geometry, 0.0, 2));
-SELECT 6, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 0.0, 2));
-SELECT 7, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 2.0, 2));
+SELECT 1, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9)'::geometry)));
+SELECT 2, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry)));
+SELECT 3, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 2)));
+SELECT 4, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 2, 1)));
+SELECT 5, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9)'::geometry, 0.0, 2)));
+SELECT 6, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 0.0, 2)));
+SELECT 7, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5, 6 0, 7 9, 8 9)'::geometry, 2.0, 2)));
-- 3DZ
-SELECT 10, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5 3, 6 0 2, 7 9 1)'::geometry));
-SELECT 11, ST_AsText(ST_DelaunayTriangles('MULTIPOINT(5 5 1, 6 0 2, 7 9 3)'::geometry, 0.0, 2));
+SELECT 10, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5 3, 6 0 2, 7 9 1)'::geometry)));
+SELECT 11, ST_AsText(ST_Normalize(ST_DelaunayTriangles('MULTIPOINT(5 5 1, 6 0 2, 7 9 3)'::geometry, 0.0, 2)));
diff --git a/regress/core/delaunaytriangles_expected b/regress/core/delaunaytriangles_expected
index d3ab102bc..5b61b195c 100644
--- a/regress/core/delaunaytriangles_expected
+++ b/regress/core/delaunaytriangles_expected
@@ -1,9 +1,9 @@
-1|GEOMETRYCOLLECTION(POLYGON((5 5,6 0,7 9,5 5)))
-2|GEOMETRYCOLLECTION(POLYGON((5 5,6 0,8 9,5 5)),POLYGON((5 5,8 9,7 9,5 5)))
-3|GEOMETRYCOLLECTION(POLYGON((5 5,6 0,7 9,5 5)))
-4|MULTILINESTRING((5 5,7 9),(5 5,6 0),(6 0,7 9))
-5|TIN(((5 5,6 0,7 9,5 5)))
-6|TIN(((5 5,6 0,8 9,5 5)),((5 5,8 9,7 9,5 5)))
-7|TIN(((5 5,6 0,7 9,5 5)))
-10|GEOMETRYCOLLECTION Z (POLYGON Z ((5 5 3,6 0 2,7 9 1,5 5 3)))
-11|TIN Z (((5 5 1,6 0 2,7 9 3,5 5 1)))
+1|GEOMETRYCOLLECTION(POLYGON((5 5,7 9,6 0,5 5)))
+2|GEOMETRYCOLLECTION(POLYGON((5 5,8 9,6 0,5 5)),POLYGON((5 5,7 9,8 9,5 5)))
+3|GEOMETRYCOLLECTION(POLYGON((5 5,7 9,6 0,5 5)))
+4|MULTILINESTRING((6 0,7 9),(5 5,7 9),(5 5,6 0))
+5|GEOMETRYCOLLECTION(POLYGON((5 5,7 9,6 0,5 5)))
+6|GEOMETRYCOLLECTION(POLYGON((5 5,8 9,6 0,5 5)),POLYGON((5 5,7 9,8 9,5 5)))
+7|GEOMETRYCOLLECTION(POLYGON((5 5,7 9,6 0,5 5)))
+10|GEOMETRYCOLLECTION Z (POLYGON Z ((5 5 3,7 9 1,6 0 2,5 5 3)))
+11|GEOMETRYCOLLECTION Z (POLYGON Z ((5 5 1,7 9 3,6 0 2,5 5 1)))
commit bae93ad34b1c6b4c4895ad6684a05aac5be2209f
Author: Sandro Santilli <strk at kbt.io>
Date: Mon Oct 9 12:09:38 2023 +0200
Fix robustness issue in topology face split handling
Stop using interpolation to find edges to update in _lwt_AddFaceSplit.
Includes regress test.
Closes #5568 in stable-3.0 branch (3.0.10dev)
diff --git a/NEWS b/NEWS
index 4dd62ea87..9b77ab5fe 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,11 @@
-PostGIS 3.0.10
+PostGIS 3.0.10dev
xxxx/xx/xx
* Bug Fixes *
- #5450, Fix macro expansion recursion on powerpc architectures.
(Bas Couwenberg)
+ - #5568, Improve robustness of topology face split handling (Sandro Santilli)
PostGIS 3.0.9
2023/05/29
diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c
index d586dd6ca..1b2d9a984 100644
--- a/liblwgeom/lwgeom_topo.c
+++ b/liblwgeom/lwgeom_topo.c
@@ -1888,7 +1888,12 @@ _lwt_AddFaceSplit( LWT_TOPOLOGY* topo,
LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " split face %" LWTFMT_ELEMID " (mbr_only:%d)",
sedge, face, mbr_only);
- /* Construct a polygon using edges of the ring */
+ /*
+ * Construct a polygon using edges of the ring
+ *
+ * NOTE: this possibily includes dangling edges
+ *
+ */
LWPOLY *shell = _lwt_MakeRingShell(topo, signed_edge_ids,
num_signed_edge_ids);
if ( ! shell ) {
@@ -2035,7 +2040,7 @@ _lwt_AddFaceSplit( LWT_TOPOLOGY* topo,
lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
return -2;
}
- LWDEBUGF(1, "lwt_be_getEdgeByFace returned %d edges", numfaceedges);
+ LWDEBUGF(1, "_lwt_AddFaceSplit: lwt_be_getEdgeByFace(%d) returned %d edges", face, numfaceedges);
if ( numfaceedges )
{
@@ -2052,70 +2057,68 @@ _lwt_AddFaceSplit( LWT_TOPOLOGY* topo,
int contains;
POINT2D ep;
- /* (2.1) skip edges whose ID is in the list of boundary edges ? */
+ /* (2.1) skip edges whose ID is in the list of boundary edges */
for ( j=0; j<num_signed_edge_ids; ++j )
{
- int seid = signed_edge_ids[j];
+ int seid = signed_edge_ids[j]; /* signed ring edge id */
if ( seid == e->edge_id )
{
- /* IDEA: remove entry from signed_edge_ids ? */
- LWDEBUGF(1, "Edge %d is a forward edge of the new ring", e->edge_id);
+ /* IDEA: remove entry from signed_edge_ids, to speed next loop ? */
+ LWDEBUGF(1, "Edge %d is a known forward edge of the new ring", e->edge_id);
forward_edges[forward_edges_count].edge_id = e->edge_id;
forward_edges[forward_edges_count++].face_left = newface.face_id;
found++;
- if ( found == 2 ) break;
+ if ( found == 2 ) break; /* both edge sides are found on the ring */
}
else if ( -seid == e->edge_id )
{
- /* IDEA: remove entry from signed_edge_ids ? */
- LWDEBUGF(1, "Edge %d is a backward edge of the new ring", e->edge_id);
+ /* IDEA: remove entry from signed_edge_ids, to speed next loop ? */
+ LWDEBUGF(1, "Edge %d is a known backward edge of the new ring", e->edge_id);
backward_edges[backward_edges_count].edge_id = e->edge_id;
backward_edges[backward_edges_count++].face_right = newface.face_id;
found++;
- if ( found == 2 ) break;
+ if ( found == 2 ) break; /* both edge sides are found on the ring */
}
}
if ( found ) continue;
+ LWDEBUGF(1, "Edge %d is not a known edge of the new ring", e->edge_id);
- /* We need to check only a single point
- * (to avoid collapsed elements of the shell polygon
- * giving false positive).
- * The point but must not be an endpoint.
- */
- if ( ! _lwt_GetInteriorEdgePoint(e->geom, &ep) )
+ /* Check if the edge is now binding a different face */
+
+ if ( ! getPoint2d_p(e->geom->points, 0, &ep) )
{
lwfree(signed_edge_ids);
lwpoly_free(shell);
lwfree(forward_edges); /* contents owned by edges */
lwfree(backward_edges); /* contents owned by edges */
_lwt_release_edges(edges, numfaceedges);
- lwerror("Could not find interior point for edge %d: %s",
- e->edge_id, lwgeom_geos_errmsg);
+ lwerror("Edge %d is empty", e->edge_id);
return -2;
}
/* IDEA: check that bounding box shortcut is taken, or use
* shellbox to do it here */
- contains = ptarray_contains_point(pa, &ep) == LW_INSIDE;
- if ( contains == 2 )
- LWDEBUGF(1, "Edge %d %scontained in new ring", e->edge_id,
- (contains?"":"not "));
+ contains = ptarray_contains_point(pa, &ep);
- /* (2.2) skip edges (NOT, if newface_outside) contained in shell */
+ LWDEBUGF(1, "Edge %d first point %s new ring",
+ e->edge_id, (contains == LW_INSIDE ? "inside" :
+ contains == LW_OUTSIDE ? "outside" : "on boundary of"));
+
+ /* (2.2) skip edges (NOT, if newface_outside) contained in ring */
if ( newface_outside )
{
- if ( contains )
+ if ( contains != LW_OUTSIDE )
{
- LWDEBUGF(1, "Edge %d contained in an hole of the new face",
+ LWDEBUGF(1, "Edge %d not outside of the new ring, not updating it",
e->edge_id);
continue;
}
}
else
{
- if ( ! contains )
+ if ( contains != LW_INSIDE )
{
- LWDEBUGF(1, "Edge %d not contained in the face shell",
+ LWDEBUGF(1, "Edge %d not inside the new ring, not updating it",
e->edge_id);
continue;
}
diff --git a/topology/test/regress/topogeo_addlinestring.sql b/topology/test/regress/topogeo_addlinestring.sql
index 8e9f995fa..a6f2caeba 100644
--- a/topology/test/regress/topogeo_addlinestring.sql
+++ b/topology/test/regress/topogeo_addlinestring.sql
@@ -471,3 +471,15 @@ SELECT 'b5234.1', count(*) FROM
TopoGeo_addLinestring('b5234',
'LINESTRING(10 10 3, 5 0 0.8)', 0);
ROLLBACK;
+
+-- See https://trac.osgeo.org/postgis/ticket/5568
+BEGIN;
+SELECT NULL FROM topology.CreateTopology ('t5568');
+SELECT NULL FROM topology.TopoGeo_addLinestring('t5568','0102000000030000007A6873CA73782440DE38B01D9CEE4D40438AD46B73782440FEAF5D499CEE4D40588FC2F528782440106D5B2FB5EE4D40');
+SELECT NULL FROM topology.TopoGeo_addLinestring('t5568','010200000002000000588FC2F528782440106D5B2FB5EE4D4089058AA63E7824401D9FCAB6B0EE4D40');
+SELECT NULL FROM topology.TopoGeo_addLinestring('t5568','01020000000300000089058AA63E7824401D9FCAB6B0EE4D4040A8CCBF35782440B80E7F8CB2EE4D40588FC2F528782440106D5B2FB5EE4D40');
+SELECT NULL FROM topology.TopoGeo_addLinestring('t5568','01020000000200000089058AA63E7824401D9FCAB6B0EE4D4084CBFA5C7A7824405CC705259CEE4D40');
+SELECT 't5568', 'invalidities at start', array_agg((v)) FROM validatetopology('t5568') v;
+SELECT NULL FROM topology.TopoGeo_addLinestring('t5568','01020000000200000084CBFA5C7A7824405CC705259CEE4D407A6873CA73782440DE38B01D9CEE4D40');
+SELECT 't5568', 'invalidities at end', array_agg(error) FROM validatetopology('t5568') v;
+ROLLBACK;
diff --git a/topology/test/regress/topogeo_addlinestring_expected b/topology/test/regress/topogeo_addlinestring_expected
index b94425280..11f9e50cd 100644
--- a/topology/test/regress/topogeo_addlinestring_expected
+++ b/topology/test/regress/topogeo_addlinestring_expected
@@ -222,3 +222,5 @@ b4941|inner_ring|1
b4941|crossing_line|5
b5234.0|1
b5234.1|1
+t5568|invalidities at start|
+t5568|invalidities at end|
-----------------------------------------------------------------------
Summary of changes:
NEWS | 3 +-
liblwgeom/lwgeom_topo.c | 57 ++++++++++++----------
regress/core/delaunaytriangles.sql | 19 ++++----
regress/core/delaunaytriangles_expected | 18 +++----
topology/test/regress/topogeo_addlinestring.sql | 12 +++++
.../test/regress/topogeo_addlinestring_expected | 2 +
6 files changed, 64 insertions(+), 47 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list