[postgis-tickets] [SCM] PostGIS branch master updated. 3.1.0rc1-45-gac60803

git at osgeo.org git at osgeo.org
Tue Jan 12 12:55:27 PST 2021


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  ac608039632085c370999a252034b1d32d68e252 (commit)
      from  d138985015bd56a21bc6d9f5b5c301528e7155a6 (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 ac608039632085c370999a252034b1d32d68e252
Author: Sandro Santilli <strk at kbt.io>
Date:   Tue Jan 12 21:34:43 2021 +0100

    Enhance test for topology edge side faces
    
    - Also check non-isolated ones
    - Catch universal face containment (only in non-boundary case)
    
    Closes #4830 again
    
    Includes more testcases and updates pre-existing one expectance.
    
    The only missing check now is for dangling edges advertising
    the universal face on only ONE side. We cannot easily check
    this becase we'd expect such edge to be only contaied by a face
    and it will be, even if both sides are in the _same_ face.
    This case can only be determined by edge-linking checking
    (references #3042)

diff --git a/topology/test/regress/legacy_invalid_expected b/topology/test/regress/legacy_invalid_expected
index a01114e..bc2cd65 100644
--- a/topology/test/regress/legacy_invalid_expected
+++ b/topology/test/regress/legacy_invalid_expected
@@ -19,6 +19,7 @@ face has no rings|10|
 face within face|11|2
 face overlaps face|2|12
 not-isolated node has not-null containing_face|4|
+edge not covered by both its side faces|27|
 edge not covered by both its side faces|28|
 edge not covered by both its side faces|30|
 Topology 'invalid_topology' dropped
diff --git a/topology/test/regress/validatetopology.sql b/topology/test/regress/validatetopology.sql
index b528aa4..e869a1f 100644
--- a/topology/test/regress/validatetopology.sql
+++ b/topology/test/regress/validatetopology.sql
@@ -44,3 +44,82 @@ UPDATE t.node SET containing_face = 0 WHERE NOT ST_Equals(geom, 'POINT(5 5)');
 SELECT '#3233.3', (ValidateTopology('t')).* UNION
 SELECT '#3233.3', '---', null, null ORDER BY 1,2,3,4;
 SELECT null from ( select topology.DropTopology('t') ) as dt;
+
+-- Test edges containment in their side faces
+-- See https://trac.osgeo.org/postgis/ticket/4684
+
+SELECT null from ( select topology.CreateTopology('t') ) as ct;
+SELECT null from ( select TopoGeo_addPolygon('t',
+  'POLYGON((0 0,10 0,10 10,0 10,0 0))' -- face 1
+) ) af;
+SELECT null from ( select TopoGeo_addPolygon('t',
+  'POLYGON((20 0,30 0,30 10,20 10,20 0))' -- face 2
+) ) af;
+SELECT null from ( select TopoGeo_addLineString('t',
+  'LINESTRING(5 5, 10 5)') -- edge inside faces, touching on endpoint
+) al;
+SELECT null from ( select TopoGeo_addLineString('t',
+  'LINESTRING(10 6, 5 6)') -- edge inside faces, touching on startpoint
+) al;
+SELECT null from ( select TopoGeo_addLineString('t',
+  'LINESTRING(10 5, 15 5)') -- edge outside faces, touching on startpoint
+) al;
+SELECT null from ( select TopoGeo_addLineString('t',
+  'LINESTRING(15 6, 10 6)') -- edge outside faces, touching on endpoint
+) al;
+SELECT null from ( select TopoGeo_addLineString('t',
+  'LINESTRING(5 8, 6 8)') -- edge inside face1, isolated
+) al;
+SELECT '#4830.0', (ValidateTopology('t')).* UNION
+SELECT '#4830.0', '---', null, null ORDER BY 1,2,3,4;
+-- 0. Set edge 1 self-linking to avoid "face with no rings"
+--    invalidity.
+UPDATE t.edge_data SET
+  next_left_edge = 1,
+  next_right_edge = -1
+  WHERE edge_id = 1;
+-- 1. Set wrong left_face for dangling inside edges
+BEGIN;
+UPDATE t.edge_data SET left_face = 2
+  WHERE
+    ST_Equals(geom, 'LINESTRING(5 5, 10 5)') OR
+    ST_Equals(geom, 'LINESTRING(10 6, 5 6)');
+SELECT '#4830.1', (ValidateTopology('t')).* UNION
+SELECT '#4830.1', '---', null, null ORDER BY 1,2,3,4;
+ROLLBACK;
+-- 2. Set wrong right_face for dangling inside edges
+BEGIN;
+UPDATE t.edge_data SET right_face = 2
+  WHERE
+    ST_Equals(geom, 'LINESTRING(5 5, 10 5)') OR
+    ST_Equals(geom, 'LINESTRING(10 6, 5 6)');
+SELECT '#4830.2', (ValidateTopology('t')).* UNION
+SELECT '#4830.2', '---', null, null ORDER BY 1,2,3,4;
+ROLLBACK;
+-- 3. Set wrong left_face for dangling outside edges
+BEGIN;
+UPDATE t.edge_data SET left_face = 2
+  WHERE
+    ST_Equals(geom, 'LINESTRING(10 5, 15 5)') OR
+    ST_Equals(geom, 'LINESTRING(15 6, 10 6)');
+SELECT '#4830.3', (ValidateTopology('t')).* UNION
+SELECT '#4830.3', '---', null, null ORDER BY 1,2,3,4;
+ROLLBACK;
+-- 4. Set wrong right_face for dangling outside edges
+BEGIN;
+UPDATE t.edge_data SET right_face = 2
+  WHERE
+    ST_Equals(geom, 'LINESTRING(10 5, 15 5)') OR
+    ST_Equals(geom, 'LINESTRING(15 6, 10 6)');
+SELECT '#4830.4', (ValidateTopology('t')).* UNION
+SELECT '#4830.4', '---', null, null ORDER BY 1,2,3,4;
+ROLLBACK;
+-- 5. Set universal face on both sides of internal edge
+BEGIN;
+UPDATE t.edge_data SET left_face = 0, right_face = 0
+  WHERE
+    ST_Equals(geom, 'LINESTRING(5 8, 6 8)');
+SELECT '#4830.5', (ValidateTopology('t')).* UNION
+SELECT '#4830.5', '---', null, null ORDER BY 1,2,3,4;
+ROLLBACK;
+SELECT null from ( select topology.DropTopology('t') ) as dt;
diff --git a/topology/test/regress/validatetopology_expected b/topology/test/regress/validatetopology_expected
index 2a97b04..c5254ab 100644
--- a/topology/test/regress/validatetopology_expected
+++ b/topology/test/regress/validatetopology_expected
@@ -7,3 +7,18 @@
 #3233.2|isolated node has wrong containing_face|2|
 #3233.3|---||
 #3233.3|not-isolated node has not-null containing_face|1|
+#4830.0|---||
+#4830.1|---||
+#4830.1|edge not covered by both its side faces|4|
+#4830.1|edge not covered by both its side faces|6|
+#4830.2|---||
+#4830.2|edge not covered by both its side faces|4|
+#4830.2|edge not covered by both its side faces|6|
+#4830.3|---||
+#4830.3|edge not covered by both its side faces|7|
+#4830.3|edge not covered by both its side faces|8|
+#4830.4|---||
+#4830.4|edge not covered by both its side faces|7|
+#4830.4|edge not covered by both its side faces|8|
+#4830.5|---||
+#4830.5|edge covered by some face has universal face on both sides|9|
diff --git a/topology/topology.sql.in b/topology/topology.sql.in
index d6710f8..bf93774 100644
--- a/topology/topology.sql.in
+++ b/topology/topology.sql.in
@@ -1716,32 +1716,47 @@ BEGIN
         SELECT
           e.edge_id,
           e.left_face,
-          ST_Covers(fl.geom, e.geom) covered_left,
           e.right_face,
-          ST_Covers(fr.geom, e.geom) covered_right
+          array_agg(COALESCE(f.face_id, 0)) covered_by
         FROM
           %1$I.edge_data e
-          LEFT JOIN face_check fl ON ( fl.face_id = e.left_face )
-          LEFT JOIN face_check fr ON ( fr.face_id = e.right_face )
-        WHERE
-          -- isolated only
-          e.next_left_edge = e.edge_id
-          AND
-          e.next_right_edge = e.edge_id
-          -- skip invalid edges (will be already reported previously)
-          AND NOT e.edge_id = ANY(%2$L)
+          LEFT JOIN face_check f ON ( ST_Covers(f.geom, e.geom) )
+          -- skip invalid edges (toxic, and will be already reported previously)
+          WHERE %2$L IS NULL OR NOT e.edge_id = ANY(%2$L)
+        GROUP BY
+          e.edge_id, e.left_face, e.right_face
       )
-      SELECT * from edge_coverage
+      SELECT
+         *,
+         left_face = ANY(covered_by) left_face_covered,
+         right_face = ANY(covered_by) right_face_covered
+         from edge_coverage
       WHERE
-        NOT covered_left
-        OR NOT covered_right
+        ( left_face != 0 AND NOT left_face = ANY(covered_by) )
+        OR
+        ( right_face != 0 AND NOT right_face = ANY(covered_by) )
+        OR
+        ( right_face = 0 AND left_face = 0 AND covered_by[1] != 0 )
       ORDER BY edge_id
     $SQL$, toponame, invalid_edges)
   LOOP
-      retrec.error := 'edge not covered by both its side faces';
       retrec.id1 := rec.edge_id;
       retrec.id2 := NULL; -- TODO: write expected containing_face here ?
-      RETURN NEXT retrec;
+      IF rec.left_face = 0 AND rec.right_face = 0 THEN
+        retrec.error := 'edge covered by some face has universal face on both sides';
+        RETURN NEXT retrec;
+      ELSE
+        retrec.error := 'edge not covered by both its side faces';
+        RETURN NEXT retrec;
+--        IF rec.left_face != 0 AND NOT rec.left_face_covered THEN
+--          retrec.error := 'edge not covered by its left face';
+--          RETURN NEXT retrec;
+--        END IF;
+--        IF rec.right_face != 0 AND NOT rec.right_face_covered THEN
+--          retrec.error := 'edge not covered by its right face';
+--          RETURN NEXT retrec;
+--        END IF;
+      END IF;
   END LOOP;
 
   DROP TABLE face_check;

-----------------------------------------------------------------------

Summary of changes:
 topology/test/regress/legacy_invalid_expected   |  1 +
 topology/test/regress/validatetopology.sql      | 79 +++++++++++++++++++++++++
 topology/test/regress/validatetopology_expected | 15 +++++
 topology/topology.sql.in                        | 47 ++++++++++-----
 4 files changed, 126 insertions(+), 16 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list