[SCM] PostGIS branch stable-3.3 updated. 3.3.6-22-gbe6e939cd
git at osgeo.org
git at osgeo.org
Mon Apr 29 09:44:27 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 be6e939cd023ceeba833b8b0aef1df7534ddcb40 (commit)
from 3d3421a8717e46581f0cde12e30db03f7f77ca97 (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 be6e939cd023ceeba833b8b0aef1df7534ddcb40
Author: Sandro Santilli <strk at kbt.io>
Date: Mon Apr 29 17:03:44 2024 +0200
Compute tolerance by edge, when adding intersection points
Increases noding robustness.
Closes ticket #5722 in 3.3 branch (3.3.7dev)
Includes regression test
diff --git a/NEWS b/NEWS
index 9f7808021..dc0844251 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ xxxx/xx/xx
* Bug Fixes and Enhancements *
+ - #5722, Improve robustness of adding lines to topology (Sandro Santilli)
- #5709, Fix loose mbr in topology.face on ST_ChangeEdgeGeom (Sandro Santilli)
- #5698, Fix robustness issue splitting line by vertex very close to endpoints,
affecting topology population functions (Sandro Santilli)
@@ -17,7 +18,6 @@ xxxx/xx/xx
- #5671, Bug in ST_Area function with use_spheroid=false
(Paul Ramsey, Regina Obe)
-
PostGIS 3.3.6
2024/02/07
diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c
index 317eabfe6..303624ed1 100644
--- a/liblwgeom/lwgeom_topo.c
+++ b/liblwgeom/lwgeom_topo.c
@@ -5448,7 +5448,7 @@ _lwt_AddLineEdge( LWT_TOPOLOGY* topo, LWLINE* edge, double tol,
return 0; /* must be empty */
}
nid[0] = _lwt_AddPoint( topo, start_point,
- _lwt_minTolerance(lwpoint_as_lwgeom(start_point)),
+ tol,
handleFaceSplit, &mm );
lwpoint_free(start_point); /* too late if lwt_AddPoint calls lwerror */
if ( nid[0] == -1 ) return -1; /* lwerror should have been called */
@@ -5463,7 +5463,7 @@ _lwt_AddLineEdge( LWT_TOPOLOGY* topo, LWLINE* edge, double tol,
return -1;
}
nid[1] = _lwt_AddPoint( topo, end_point,
- _lwt_minTolerance(lwpoint_as_lwgeom(end_point)),
+ tol,
handleFaceSplit, &mm );
moved += mm;
lwpoint_free(end_point); /* too late if lwt_AddPoint calls lwerror */
@@ -5977,7 +5977,13 @@ _lwt_AddLine(LWT_TOPOLOGY* topo, LWLINE* line, double tol, int* nedges,
}
#endif
- id = _lwt_AddLineEdge( topo, lwgeom_as_lwline(g), tol, handleFaceSplit, &forward );
+ id = _lwt_AddLineEdge(
+ topo,
+ lwgeom_as_lwline(g),
+ _lwt_minTolerance(g), /* TODO: compute actual drift introduced by GEOS ? */
+ handleFaceSplit,
+ &forward
+ );
LWDEBUGF(1, "_lwt_AddLineEdge returned %" LWTFMT_ELEMID, id);
if ( id < 0 )
{
diff --git a/topology/test/regress/topogeo_addlinestring_robust.sql b/topology/test/regress/topogeo_addlinestring_robust.sql
new file mode 100644
index 000000000..27d30a196
--- /dev/null
+++ b/topology/test/regress/topogeo_addlinestring_robust.sql
@@ -0,0 +1,178 @@
+
+--{
+CREATE FUNCTION runTest( lbl text, lines geometry[], newline geometry, prec float8, debug bool default false )
+RETURNS SETOF text AS
+$BODY$
+DECLARE
+ g geometry;
+ n int := 0;
+ rec record;
+BEGIN
+ IF EXISTS ( SELECT * FROM topology.topology WHERE name = 'topo' )
+ THEN
+ PERFORM topology.DropTopology ('topo');
+ END IF;
+
+ PERFORM topology.CreateTopology ('topo');
+ CREATE TABLE topo.fl(lbl text, g geometry);
+ PERFORM topology.AddTopoGeometryColumn('topo','topo','fl','tg','LINESTRING');
+ CREATE TABLE topo.fa(lbl text, g geometry);
+ PERFORM topology.AddTopoGeometryColumn('topo','topo','fa','tg','POLYGON');
+
+ -- Add a polygon containing all lines
+ PERFORM topology.TopoGeo_addPolygon('topo', ST_Expand(ST_Extent(geom), 100))
+ FROM unnest(lines) geom;
+
+ -- Add all lines
+ FOR g IN SELECT unnest(lines)
+ LOOP
+ INSERT INTO topo.fl(lbl, tg) VALUES
+ ( 'l'||n, topology.toTopoGeom(g, 'topo', 1) );
+ n = n+1;
+ END LOOP;
+
+ FOR n IN SELECT face_id FROM topo.face WHERE face_id > 0
+ LOOP
+ INSERT INTO topo.fa(lbl, tg) VALUES
+ ( 'a'||n, topology.CreateTopoGeom('topo', 3, 2, ARRAY[ARRAY[n,3]]) );
+ n = n+1;
+ END LOOP;
+
+ UPDATE topo.fl SET g = tg::geometry;
+ UPDATE topo.fa SET g = tg::geometry;
+
+ RETURN QUERY SELECT array_to_string(ARRAY[
+ lbl,
+ '-checking-'
+ ], '|');
+
+ IF debug THEN
+ RETURN QUERY SELECT array_to_string(ARRAY[
+ lbl, -- 'topo',
+ 'bfr',
+ 'E' || edge_id,
+ 'next_left:'||next_left_edge,
+ 'next_right:'||next_right_edge,
+ 'face_left:'||left_face,
+ 'face_right:'||right_face
+ ], '|')
+ FROM topo.edge
+ ORDER BY edge_id;
+ END IF;
+
+ IF debug THEN
+ set client_min_messages to DEBUG;
+ END IF;
+
+ BEGIN
+ PERFORM topology.TopoGeo_addLinestring('topo', newline, prec);
+ EXCEPTION WHEN OTHERS THEN
+ RETURN QUERY SELECT format('%s|addline exception|%s (%s)', lbl, SQLERRM, SQLSTATE);
+ END;
+
+ IF debug THEN
+ set client_min_messages to WARNING;
+ END IF;
+
+ IF debug THEN
+ RETURN QUERY SELECT array_to_string(ARRAY[
+ lbl, --'topo',
+ 'aft',
+ 'E' || edge_id,
+ 'next_left:'||next_left_edge,
+ 'next_right:'||next_right_edge,
+ 'face_left:'||left_face,
+ 'face_right:'||right_face
+ ], '|')
+ FROM topo.edge
+ ORDER BY edge_id;
+ END IF;
+
+ RETURN QUERY
+ WITH j AS (
+ SELECT
+ row_number() over () as rn,
+ to_json(s) as o
+ FROM ValidateTopology('topo') s
+ )
+ SELECT
+ array_to_string(
+ ARRAY[lbl,'unexpected','validity issue'] ||
+ array_agg(x.value order by x.ordinality),
+ '|'
+ )
+ FROM j, json_each_text(j.o)
+ WITH ordinality AS x
+ GROUP by j.rn;
+
+
+ RETURN QUERY SELECT array_to_string(ARRAY[
+ lbl,
+ 'unexpected',
+ 'lineal drift',
+ l,
+ dist::text
+ ], '|')
+ FROM (
+ SELECT t.lbl l, ST_HausdorffDistance(t.g, tg::geometry) dist
+ FROM topo.fl t
+ ) foo WHERE dist >= COALESCE(
+ NULLIF(prec,0),
+ topology._st_mintolerance(newline)
+ )
+ ORDER BY foo.l;
+
+ SELECT sum(ST_Area(t.g)) as before, sum(ST_Area(tg::geometry)) as after
+ FROM topo.fa t
+ INTO rec;
+
+ IF rec.before != rec.after THEN
+ RETURN QUERY SELECT array_to_string(ARRAY[
+ lbl,
+ 'unexpected total area change',
+ rec.before::text,
+ rec.after::text
+ ], '|')
+ ;
+
+ RETURN QUERY SELECT array_to_string(ARRAY[
+ lbl,
+ 'area change',
+ l,
+ rec.bfr::text,
+ rec.aft::text
+ ], '|')
+ FROM (
+ SELECT t.lbl l, ST_Area(t.g) bfr, ST_Area(tg::geometry) aft
+ FROM topo.fa t
+ ) foo WHERE bfr != aft
+ ORDER BY foo.l;
+
+ END IF;
+
+ IF NOT debug THEN
+ PERFORM topology.DropTopology ('topo');
+ END IF;
+
+END;
+$BODY$
+LANGUAGE 'plpgsql';
+--}
+
+SET client_min_messages to WARNING;
+
+-- See https://trac.osgeo.org/postgis/ticket/5722
+SELECT * FROM runTest('#5722',
+ ARRAY[
+ 'LINESTRING(
+ -11.968112622212203 0.651457829865329,
+ 8.13909499443551 0.334122751124234,
+ -11.964143711257549 0.31568377154268)'
+ ],
+ 'LINESTRING(
+ -0.65145782986533 -11.968112622212203,
+ -0.159231454672685 8.13973141470126)',
+ 0
+) WHERE true ;
+
+DROP FUNCTION runTest(text, geometry[], geometry, float8, bool);
diff --git a/topology/test/regress/topogeo_addlinestring_robust_expected b/topology/test/regress/topogeo_addlinestring_robust_expected
new file mode 100644
index 000000000..2e4e863b5
--- /dev/null
+++ b/topology/test/regress/topogeo_addlinestring_robust_expected
@@ -0,0 +1 @@
+#5722|-checking-
diff --git a/topology/test/tests.mk b/topology/test/tests.mk
index 937e3e3cd..2aac942ff 100644
--- a/topology/test/tests.mk
+++ b/topology/test/tests.mk
@@ -71,6 +71,7 @@ TESTS += \
$(top_srcdir)/topology/test/regress/topoelementarray_agg.sql \
$(top_srcdir)/topology/test/regress/topoelement.sql \
$(top_srcdir)/topology/test/regress/topogeo_addlinestring.sql \
+ $(top_srcdir)/topology/test/regress/topogeo_addlinestring_robust.sql \
$(top_srcdir)/topology/test/regress/topogeo_addpoint.sql \
$(top_srcdir)/topology/test/regress/topogeo_addpolygon.sql \
$(top_srcdir)/topology/test/regress/topogeom_addtopogeom.sql \
-----------------------------------------------------------------------
Summary of changes:
NEWS | 2 +-
liblwgeom/lwgeom_topo.c | 12 +-
.../test/regress/topogeo_addlinestring_robust.sql | 178 +++++++++++++++++++++
.../regress/topogeo_addlinestring_robust_expected | 1 +
topology/test/tests.mk | 1 +
5 files changed, 190 insertions(+), 4 deletions(-)
create mode 100644 topology/test/regress/topogeo_addlinestring_robust.sql
create mode 100644 topology/test/regress/topogeo_addlinestring_robust_expected
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list