mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-24 09:02:37 +00:00
Error handling refinements in topology.ST_AddEdgeNewFaces (#988)
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
This commit is contained in:
parent
43f42cd6b8
commit
fe9e336ea9
|
@ -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;
|
||||
|
|
|
@ -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)');
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue