]> granicus.if.org Git - postgis/commitdiff
ST_AddEdgeNewFaces: don't get fooled by empty segments when computing azimuts [RT...
authorSandro Santilli <strk@keybit.net>
Tue, 24 May 2011 13:15:01 +0000 (13:15 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 24 May 2011 13:15:01 +0000 (13:15 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@7232 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/sqlmm.sql
topology/test/regress/st_addedgenewfaces.sql
topology/test/regress/st_addedgenewfaces_expected

index bd022c9c85eba01ff843aff59cc8eb7eec0e7580..1c444ce103633a29a1e0209a23423ee4e7ec0aa0 100644 (file)
@@ -1877,6 +1877,7 @@ DECLARE
   sql TEXT;
   newfaces INTEGER[];
   newface INTEGER;
+  cleangeom GEOMETRY;
 BEGIN
 
   --
@@ -2045,25 +2046,29 @@ BEGIN
       quote_ident(atopology) || '.edge_data_edge_id_seq') || ')'
   INTO STRICT newedge.edge_id;
 
+  cleangeom := ST_RemoveRepeatedPoints(acurve);
+
   -- Compute azimut of first edge end on start node
   SELECT null::int AS nextCW, null::int AS nextCCW,
          null::float8 AS minaz, null::float8 AS maxaz,
          false AS was_isolated,
-         ST_Azimuth(ST_StartPoint(acurve),
-                    ST_PointN(acurve, 2)) AS myaz
-        -- TODO: second point might be equals to first point...
-        --       ... we should check that and find a better candidate
+         ST_Azimuth(ST_StartPoint(cleangeom),
+                    ST_PointN(cleangeom, 2)) AS myaz
   INTO span;
+  IF span.myaz IS NULL THEN
+    RAISE EXCEPTION 'Invalid edge (no two distinct nodes exist)';
+  END IF;
 
   -- Compute azimuth of last edge end on end node
   SELECT null::int AS nextCW, null::int AS nextCCW,
          null::float8 AS minaz, null::float8 AS maxaz,
          false AS was_isolated,
-         ST_Azimuth(ST_EndPoint(acurve),
-                    ST_PointN(acurve, ST_NumPoints(acurve)-1)) AS myaz
-        -- TODO: one-to-last point might be equals to last point...
-        --       ... we should check that and find a better candidate
+         ST_Azimuth(ST_EndPoint(cleangeom),
+                    ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1)) AS myaz
   INTO epan;
+  IF epan.myaz IS NULL THEN
+    RAISE EXCEPTION 'Invalid edge (no two distinct nodes exist)';
+  END IF;
 
 
   -- Find links on start node -- {
@@ -2090,24 +2095,31 @@ BEGIN
 
     i := i + 1;
 
+    cleangeom := ST_RemoveRepeatedPoints(rec.geom);
+
     IF rec.start_node = anode THEN
       --
       -- Edge starts at our node, we compute
       -- azimuth from node to its second point
       --
-      az := ST_Azimuth(ST_StartPoint(acurve), ST_PointN(rec.geom, 2));
+      az := ST_Azimuth(ST_StartPoint(cleangeom), ST_PointN(cleangeom, 2));
 
     ELSE
       --
       -- Edge ends at our node, we compute
       -- azimuth from node to its second-last point
       --
-      az := ST_Azimuth(ST_StartPoint(acurve),
-                       ST_PointN(rec.geom, ST_NumPoints(rec.geom)-1));
+      az := ST_Azimuth(ST_EndPoint(cleangeom),
+                       ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1));
       rec.edge_id := -rec.edge_id;
 
     END IF;
 
+    IF az IS NULL THEN
+      RAISE EXCEPTION 'Invalid edge % found (no two distinct nodes exist)',
+        rec.edge_id;
+    END IF;
+
     RAISE DEBUG 'Edge % - az % (%) - fl:% fr:%',
       rec.edge_id, az, az - span.myaz, rec.left_face, rec.right_face;
 
@@ -2200,20 +2212,22 @@ BEGIN
 
     i := i + 1;
 
+    cleangeom := ST_RemoveRepeatedPoints(rec.geom);
+
     IF rec.start_node = anothernode THEN
       --
       -- Edge starts at our node, we compute
       -- azimuth from node to its second point
       --
-      az := ST_Azimuth(ST_EndPoint(acurve), ST_PointN(rec.geom, 2));
+      az := ST_Azimuth(ST_StartPoint(cleangeom), ST_PointN(cleangeom, 2));
 
     ELSE
       --
       -- Edge ends at our node, we compute
       -- azimuth from node to its second-last point
       --
-      az := ST_Azimuth(ST_EndPoint(acurve),
-        ST_PointN(rec.geom, ST_NumPoints(rec.geom)-1));
+      az := ST_Azimuth(ST_EndPoint(cleangeom),
+        ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1));
       rec.edge_id := -rec.edge_id;
 
     END IF;
index a1672acb7c5451293a472a5854291273ae4bb12d..0cc0d49084b4a8d6d3a3961ac44d3abdd1787317 100644 (file)
@@ -307,6 +307,32 @@ SELECT 'T19', 'E'||edge_id, next_left_edge, next_right_edge,
   ( SELECT edge_id FROM newedge WHERE id = 19 ) )
   ORDER BY edge_id;
 
+--
+-- New face in universal face, with both endpoints on same existing edge
+-- and endpoints duplicated
+--
+INSERT INTO newedge SELECT 20, topology.st_addedgenewfaces('city_data',
+  10, 11,  'LINESTRING(35 6, 35 6, 44 0, 47 6, 47 6)');
+SELECT 'T20', 'E'||edge_id, next_left_edge, next_right_edge,
+  left_face, right_face FROM
+  city_data.edge WHERE edge_id IN ( 36,  14, 16, 
+  ( SELECT edge_id FROM newedge WHERE id = 20 ) )
+  ORDER BY edge_id;
+
+--
+-- Another face in universal face, with both endpoints on same existing edge
+-- and both edges' endpoints duplicated
+--
+INSERT INTO newedge SELECT 21, topology.st_addedgenewfaces('city_data',
+  10, 11,  'LINESTRING(35 6, 35 6, 44 -4, 47 6, 47 6)');
+SELECT 'T21', 'E'||edge_id, next_left_edge, next_right_edge,
+  left_face, right_face FROM
+  city_data.edge WHERE edge_id IN (
+    SELECT edge_id FROM newedge WHERE id IN (20,  21)
+    UNION VALUES (36),(16) )
+  ORDER BY edge_id;
+
+
 ---------------------------------------------------------------------
 -- Check new relations and faces status
 ---------------------------------------------------------------------
index fb955b882edcc2e7a46c229443f59fb21e69801c..d91a5a70d604a174ad4da9d97737f8d57c977aeb 100644 (file)
@@ -87,6 +87,14 @@ T19|E12|-31|-45|20|34
 T19|E22|37|32|0|21
 T19|E35|35|45|26|0
 T19|E45|22|-12|0|34
+T20|E14|16|46|14|35
+T20|E16|29|-46|14|0
+T20|E36|-13|-36|0|27
+T20|E46|-14|36|35|0
+T21|E16|29|-47|14|0
+T21|E36|-13|-36|0|27
+T21|E46|-14|47|35|36
+T21|E47|-46|36|36|0
 F3,F4|{3:10,3:11,3:23,3:24,3:25}
 F5,N4|{1:4,3:12,3:13}
 F0|
@@ -115,4 +123,6 @@ F31|POLYGON((17 30,17 40,31 40,31 30,17 30))
 F32|POLYGON((20 34,20 37,23 37,23 34,20 34))
 F33|POLYGON((35 25,35 45,63 45,63 25,35 25))
 F34|POLYGON((9 0,9 6,21 6,21 0,9 0))
+F35|POLYGON((35 0,35 6,47 6,47 0,35 0))
+F36|POLYGON((35 -4,35 6,47 6,47 -4,35 -4))
 Topology 'city_data' dropped