]> granicus.if.org Git - postgis/commitdiff
Error handling refinements in topology.ST_AddEdgeNewFaces (#988)
authorSandro Santilli <strk@keybit.net>
Thu, 26 May 2011 07:26:56 +0000 (07:26 +0000)
committerSandro Santilli <strk@keybit.net>
Thu, 26 May 2011 07:26:56 +0000 (07:26 +0000)
Check for given edge having two distinct vertices before getting a new
edge id from sequence, and before testing it for crossing nodes (or it'd
give a confusing error message). Refine error message about no-segment
edges to not talk about nodes. [RT-SIGTA]

git-svn-id: http://svn.osgeo.org/postgis/trunk@7253 b70326c6-7e19-0410-871a-916f4a2858ee

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

index d00b31767cda0d3ded9ca06d583fcabc6e8b40aa..cb83709db8fd742b270357fc2770d00eb658b57a 100644 (file)
@@ -1905,7 +1905,6 @@ DECLARE
   sql TEXT;
   newfaces INTEGER[];
   newface INTEGER;
-  cleangeom GEOMETRY;
 BEGIN
 
   --
@@ -1952,9 +1951,34 @@ BEGIN
     NULL::int as prev_left_edge, NULL::int as prev_right_edge, -- convenience
     anode = anothernode as isclosed, -- convenience
     false as start_node_isolated, -- convenience
-    false as end_node_isolated -- convenience
+    false as end_node_isolated, -- convenience
+    ST_RemoveRepeatedPoints(acurve) as cleangeom -- convenience
   INTO newedge;
 
+  -- 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(newedge.cleangeom),
+                    ST_PointN(newedge.cleangeom, 2)) AS myaz
+  INTO span;
+  IF span.myaz IS NULL THEN
+    RAISE EXCEPTION 'Invalid edge (no two distinct vertices 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(newedge.cleangeom),
+                    ST_PointN(newedge.cleangeom,
+                              ST_NumPoints(newedge.cleangeom)-1)) AS myaz
+  INTO epan;
+  IF epan.myaz IS NULL THEN
+    RAISE EXCEPTION 'Invalid edge (no two distinct vertices exist)';
+  END IF;
+
+
   -- 
   -- Check endpoints existance, match with Curve geometry
   -- and get face information (if any)
@@ -2074,48 +2098,25 @@ 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(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(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 -- {
 
   RAISE DEBUG 'My start-segment azimuth: %', span.myaz;
 
   sql :=
-    'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, geom'
-    || ' FROM '
+    'SELECT edge_id, -1 AS end_node, start_node, left_face, right_face, '
+    || 'ST_RemoveRepeatedPoints(geom) as geom FROM '
     || quote_ident(atopology)
     || '.edge_data WHERE start_node = ' || anode
-    || ' UNION SELECT edge_id, end_node, -1, left_face, right_face, geom FROM '
+    || ' UNION SELECT edge_id, end_node, -1, left_face, right_face, '
+    || 'ST_RemoveRepeatedPoints(geom) FROM '
     || quote_ident(atopology)
     || '.edge_data WHERE end_node = ' || anode;
   IF newedge.isclosed THEN
     sql := sql || ' UNION SELECT '
       || newedge.edge_id || ',' || newedge.end_node
       || ',-1,0,0,' -- pretend we start elsewhere
-      || quote_literal(newedge.geom::text);
+      || quote_literal(newedge.cleangeom::text);
   END IF;
   i := 0;
   FOR rec IN EXECUTE sql
@@ -2123,22 +2124,20 @@ 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(cleangeom), ST_PointN(cleangeom, 2));
+      az := ST_Azimuth(ST_StartPoint(rec.geom), ST_PointN(rec.geom, 2));
 
     ELSE
       --
       -- Edge ends at our node, we compute
       -- azimuth from node to its second-last point
       --
-      az := ST_Azimuth(ST_EndPoint(cleangeom),
-                       ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1));
+      az := ST_Azimuth(ST_EndPoint(rec.geom),
+                       ST_PointN(rec.geom, ST_NumPoints(rec.geom)-1));
       rec.edge_id := -rec.edge_id;
 
     END IF;
@@ -2220,19 +2219,19 @@ BEGIN
   RAISE DEBUG 'My end-segment azimuth: %', epan.myaz;
 
   sql :=
-    'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, geom'
-    || ' FROM '
+    'SELECT edge_id, -1 as end_node, start_node, left_face, right_face, '
+    || 'ST_RemoveRepeatedPoints(geom) as geom FROM '
     || quote_ident(atopology)
     || '.edge_data WHERE start_node = ' || anothernode
-    || 'UNION SELECT edge_id, end_node, -1, left_face, right_face, geom'
-    || ' FROM '
+    || 'UNION SELECT edge_id, end_node, -1, left_face, right_face, '
+    || 'ST_RemoveRepeatedPoints(geom) FROM '
     || quote_ident(atopology)
     || '.edge_data WHERE end_node = ' || anothernode;
   IF newedge.isclosed THEN
     sql := sql || ' UNION SELECT '
       || newedge.edge_id || ',' || -1 -- pretend we end elsewhere
       || ',' || newedge.start_node || ',0,0,'
-      || quote_literal(newedge.geom::text);
+      || quote_literal(newedge.cleangeom::text);
   END IF;
   i := 0;
   FOR rec IN EXECUTE sql
@@ -2240,22 +2239,21 @@ 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_StartPoint(cleangeom), ST_PointN(cleangeom, 2));
+      az := ST_Azimuth(ST_StartPoint(rec.geom),
+                       ST_PointN(rec.geom, 2));
 
     ELSE
       --
       -- Edge ends at our node, we compute
       -- azimuth from node to its second-last point
       --
-      az := ST_Azimuth(ST_EndPoint(cleangeom),
-        ST_PointN(cleangeom, ST_NumPoints(cleangeom)-1));
+      az := ST_Azimuth(ST_EndPoint(rec.geom),
+        ST_PointN(rec.geom, ST_NumPoints(rec.geom)-1));
       rec.edge_id := -rec.edge_id;
 
     END IF;
index 0cc0d49084b4a8d6d3a3961ac44d3abdd1787317..9270eeaf835ac47fb67b59437cdfa907b7b8d0d5 100644 (file)
@@ -22,6 +22,14 @@ SELECT topology.ST_AddEdgeNewFaces('city_data', 60000, 6,
 SELECT topology.ST_AddEdgeNewFaces('city_data', 5, 5,
  'LINESTRING(36 38, 40 50, 36 38)');
 
+-- Collapsed curve
+SELECT topology.ST_AddEdgeNewFaces('city_data', 5, 5,
+ 'LINESTRING(36 38, 36 38, 36 38)');
+
+-- Empty curve
+SELECT topology.ST_AddEdgeNewFaces('city_data', 5, 5,
+ 'LINESTRING EMPTY');
+
 -- Coincident edge
 SELECT topology.ST_AddEdgeNewFaces('city_data', 18, 19,
  'LINESTRING(35 22,47 22)');
index d91a5a70d604a174ad4da9d97737f8d57c977aeb..f27d54c9d6a915cd9ea175ae2ed26b26ac84f9eb 100644 (file)
@@ -10,6 +10,8 @@ ERROR:  SQL/MM Spatial exception - geometry crosses a node
 ERROR:  SQL/MM Spatial exception - non-existent node
 ERROR:  SQL/MM Spatial exception - non-existent node
 ERROR:  SQL/MM Spatial exception - curve not simple
+ERROR:  Invalid edge (no two distinct vertices exist)
+ERROR:  Invalid edge (no two distinct vertices exist)
 ERROR:  SQL/MM Spatial exception - coincident edge
 ERROR:  SQL/MM Spatial exception - geometry crosses an edge
 ERROR:  SQL/MM Spatial exception - geometry crosses an edge