[SCM] PostGIS branch master updated. 3.4.0rc1-1099-ga1d879440
git at osgeo.org
git at osgeo.org
Mon Apr 29 09:41:32 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, master has been updated
via a1d87944045dcca9b26ccaeca176d69799fce7e3 (commit)
from 5ab778aef57b4373385f45bc5104e56a9fab8240 (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 a1d87944045dcca9b26ccaeca176d69799fce7e3
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.
References ticket #5722 in master branch (3.5.0dev)
Includes regression test
diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c
index 570f449a5..3db9a0819 100644
--- a/liblwgeom/topo/lwgeom_topo.c
+++ b/liblwgeom/topo/lwgeom_topo.c
@@ -5440,7 +5440,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 */
@@ -5456,7 +5456,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 );
lwpoint_free(end_point); /* too late if lwt_AddPoint calls lwerror */
if ( nid[1] == -1 ) return -1; /* lwerror should have been called */
@@ -5989,7 +5989,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 02edc26fc..528c79238 100644
--- a/topology/test/tests.mk
+++ b/topology/test/tests.mk
@@ -73,6 +73,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/topogeo_loadgeometry.sql \
-----------------------------------------------------------------------
Summary of changes:
liblwgeom/topo/lwgeom_topo.c | 12 +-
.../test/regress/topogeo_addlinestring_robust.sql | 178 +++++++++++++++++++++
.../regress/topogeo_addlinestring_robust_expected | 1 +
topology/test/tests.mk | 1 +
4 files changed, 189 insertions(+), 3 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