[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