mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-24 09:02:37 +00:00
Fix edge-linking in ST_ModEdgeSplit (#1496)
Includes regression test. ST_NewEdgesSplit still needs testing. git-svn-id: http://svn.osgeo.org/postgis/trunk@8911 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
88c557fc6c
commit
90bb0776df
|
@ -2116,6 +2116,10 @@ BEGIN
|
|||
'SQL/MM Spatial exception - null argument';
|
||||
END IF;
|
||||
|
||||
-- Get topology id
|
||||
SELECT id FROM topology.topology into topoid
|
||||
WHERE name = atopology;
|
||||
|
||||
--
|
||||
-- Check node existance
|
||||
--
|
||||
|
@ -2200,13 +2204,20 @@ BEGIN
|
|||
|| 'next_left_edge, next_right_edge,'
|
||||
|| 'left_face, right_face, geom) '
|
||||
|| 'VALUES('
|
||||
||newedgeid||','||nodeid
|
||||
||','||oldedge.end_node
|
||||
||','||oldedge.next_left_edge
|
||||
||',-'||anedge
|
||||
||','||oldedge.left_face
|
||||
||','||oldedge.right_face
|
||||
||','||quote_literal(newedge2::text)
|
||||
|| newedgeid
|
||||
|| ',' || nodeid
|
||||
|| ',' || oldedge.end_node
|
||||
|| ',' || COALESCE( -- next_left_edge
|
||||
NULLIF(
|
||||
oldedge.next_left_edge,
|
||||
-anedge
|
||||
),
|
||||
-newedgeid
|
||||
)
|
||||
|| ',' || -anedge -- next_right_edge
|
||||
|| ',' || oldedge.left_face -- left_face
|
||||
|| ',' || oldedge.right_face -- right_face
|
||||
|| ',' || quote_literal(newedge2::text) -- geom
|
||||
||')';
|
||||
|
||||
--
|
||||
|
@ -2216,6 +2227,7 @@ BEGIN
|
|||
|| ' SET geom = ' || quote_literal(newedge1::text)
|
||||
|| ','
|
||||
|| ' next_left_edge = ' || newedgeid
|
||||
|| ', abs_next_left_edge = ' || newedgeid
|
||||
|| ','
|
||||
|| ' end_node = ' || nodeid
|
||||
|| ' WHERE edge_id = ' || anedge;
|
||||
|
@ -2230,18 +2242,16 @@ BEGIN
|
|||
|| -newedgeid
|
||||
|| ','
|
||||
|| ' abs_next_right_edge = ' || newedgeid
|
||||
|| ' WHERE next_right_edge = ' || -anedge;
|
||||
|| ' WHERE edge_id != ' || newedgeid
|
||||
|| ' AND next_right_edge = ' || -anedge;
|
||||
|
||||
EXECUTE 'UPDATE ' || quote_ident(atopology)
|
||||
|| '.edge_data SET '
|
||||
|| ' next_left_edge = ' || -newedgeid
|
||||
|| ','
|
||||
|| ' abs_next_left_edge = ' || newedgeid
|
||||
|| ' WHERE next_left_edge = ' || -anedge;
|
||||
|
||||
-- Get topology id
|
||||
SELECT id FROM topology.topology into topoid
|
||||
WHERE name = atopology;
|
||||
|| ' WHERE edge_id != ' || newedgeid
|
||||
|| ' AND next_left_edge = ' || -anedge;
|
||||
|
||||
--
|
||||
-- Update references in the Relation table.
|
||||
|
|
|
@ -38,6 +38,7 @@ TESTS = regress/legacy_validate.sql regress/legacy_predicate.sql \
|
|||
regress/st_getfacegeometry.sql \
|
||||
regress/st_getfaceedges.sql \
|
||||
regress/st_modedgeheal.sql \
|
||||
regress/st_modedgesplit.sql \
|
||||
regress/st_newedgeheal.sql \
|
||||
regress/st_remedgenewface.sql \
|
||||
regress/st_remedgemodface.sql \
|
||||
|
|
96
topology/test/regress/st_modedgesplit.sql
Normal file
96
topology/test/regress/st_modedgesplit.sql
Normal file
|
@ -0,0 +1,96 @@
|
|||
|
||||
\set VERBOSITY terse
|
||||
set client_min_messages to ERROR;
|
||||
|
||||
-- Import city_data
|
||||
\i load_topology.sql
|
||||
|
||||
-- Save max node id
|
||||
select 'node'::text as what, max(node_id) INTO city_data.limits FROM city_data.node;
|
||||
INSERT INTO city_data.limits select 'edge'::text as what, max(edge_id) FROM city_data.edge;
|
||||
SELECT 'max',* from city_data.limits;
|
||||
|
||||
-- Check changes since last saving, save more
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION check_changes()
|
||||
RETURNS TABLE (o text)
|
||||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
sql text;
|
||||
BEGIN
|
||||
-- Check effect on nodes
|
||||
sql := 'SELECT n.node_id, ''N|'' || n.node_id || ''|'' ||
|
||||
COALESCE(n.containing_face::text,'''') || ''|'' ||
|
||||
ST_AsText(ST_SnapToGrid(n.geom, 0.2))::text as xx
|
||||
FROM city_data.node n WHERE n.node_id > (
|
||||
SELECT max FROM city_data.limits WHERE what = ''node''::text )
|
||||
ORDER BY n.node_id';
|
||||
|
||||
FOR rec IN EXECUTE sql LOOP
|
||||
o := rec.xx;
|
||||
RETURN NEXT;
|
||||
END LOOP;
|
||||
|
||||
-- Check effect on edges (there should be one split)
|
||||
sql := '
|
||||
WITH node_limits AS ( SELECT max FROM city_data.limits WHERE what = ''node''::text ),
|
||||
edge_limits AS ( SELECT max FROM city_data.limits WHERE what = ''edge''::text )
|
||||
SELECT ''E|'' || e.edge_id || ''|sn'' || e.start_node || ''|en'' || e.end_node
|
||||
|| ''|nl'' || e.next_left_edge
|
||||
|| ''|nr'' || e.next_right_edge
|
||||
|| ''|lf'' || e.left_face
|
||||
|| ''|rf'' || e.right_face
|
||||
:: text as xx
|
||||
FROM city_data.edge e, node_limits nl, edge_limits el
|
||||
WHERE e.start_node > nl.max
|
||||
OR e.end_node > nl.max
|
||||
OR e.edge_id > el.max
|
||||
ORDER BY e.edge_id;
|
||||
';
|
||||
|
||||
FOR rec IN EXECUTE sql LOOP
|
||||
o := rec.xx;
|
||||
RETURN NEXT;
|
||||
END LOOP;
|
||||
|
||||
UPDATE city_data.limits SET max = (SELECT max(n.node_id) FROM city_data.node n) WHERE what = 'node';
|
||||
UPDATE city_data.limits SET max = (SELECT max(e.edge_id) FROM city_data.edge e) WHERE what = 'edge';
|
||||
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql';
|
||||
-- }
|
||||
|
||||
-- Invalid calls
|
||||
SELECT 'invalid', ST_ModEdgeSplit('city_data', 999, 'POINT(36 26, 38 30)');
|
||||
SELECT 'invalid', ST_ModEdgeSplit('city_data', 10, 'POINT(28 15)');
|
||||
SELECT 'invalid', ST_ModEdgeSplit('', 10, 'POINT(28 14)');
|
||||
SELECT 'invalid', ST_ModEdgeSplit(NULL, 10, 'POINT(28 14)');
|
||||
SELECT 'invalid', ST_ModEdgeSplit('city_data', NULL, 'POINT(28 14)');
|
||||
SELECT 'invalid', ST_ModEdgeSplit('city_data', 10, NULL);
|
||||
SELECT 'invalid', ST_ModEdgeSplit('fake', 10, 'POINT(28 14)');
|
||||
|
||||
-- Non-isolated edge
|
||||
SELECT 'noniso', ST_ModEdgeSplit('city_data', 10, 'POINT(28 14)');
|
||||
SELECT check_changes();
|
||||
|
||||
-- Isolated edge
|
||||
SELECT 'iso', ST_ModEdgeSplit('city_data', 25, 'POINT(11 35)');
|
||||
SELECT check_changes();
|
||||
|
||||
-- Dangling on end point
|
||||
SELECT 'dangling_end', ST_ModEdgeSplit('city_data', 3, 'POINT(25 32)');
|
||||
SELECT check_changes();
|
||||
|
||||
-- Dangling on start point
|
||||
SELECT 'dangling_start', ST_ModEdgeSplit('city_data', 4, 'POINT(45 32)');
|
||||
SELECT check_changes();
|
||||
|
||||
-- Splitting closed edge
|
||||
SELECT 'closed', ST_ModEdgeSplit('city_data', 1, 'POINT(3 38)');
|
||||
SELECT check_changes();
|
||||
|
||||
|
||||
|
||||
DROP FUNCTION check_changes();
|
||||
SELECT DropTopology('city_data');
|
36
topology/test/regress/st_modedgesplit_expected
Normal file
36
topology/test/regress/st_modedgesplit_expected
Normal file
|
@ -0,0 +1,36 @@
|
|||
BEGIN
|
||||
t
|
||||
9
|
||||
22
|
||||
26
|
||||
COMMIT
|
||||
max|node|22
|
||||
max|edge|26
|
||||
ERROR: geometry has too many points at character 53
|
||||
ERROR: SQL/MM Spatial exception - point not on edge
|
||||
ERROR: zero-length delimited identifier at or near """" at character 15
|
||||
ERROR: SQL/MM Spatial exception - null argument
|
||||
ERROR: SQL/MM Spatial exception - null argument
|
||||
ERROR: SQL/MM Spatial exception - null argument
|
||||
ERROR: schema "fake" does not exist at character 15
|
||||
noniso|23
|
||||
N|23||POINT(28 14)
|
||||
E|10|sn13|en23|nl27|nr17|lf7|rf4
|
||||
E|27|sn23|en14|nl-20|nr-10|lf7|rf4
|
||||
iso|24
|
||||
N|24||POINT(11 35)
|
||||
E|25|sn21|en24|nl28|nr25|lf1|rf1
|
||||
E|28|sn24|en22|nl-28|nr-25|lf1|rf1
|
||||
dangling_end|25
|
||||
N|25||POINT(25 32)
|
||||
E|3|sn2|en25|nl29|nr2|lf2|rf2
|
||||
E|29|sn25|en3|nl-29|nr-3|lf2|rf2
|
||||
dangling_start|26
|
||||
N|26||POINT(45 32)
|
||||
E|4|sn5|en26|nl30|nr4|lf0|rf0
|
||||
E|30|sn26|en6|nl-5|nr-4|lf0|rf0
|
||||
closed|27
|
||||
N|27||POINT(3 38)
|
||||
E|1|sn1|en27|nl31|nr-31|lf1|rf0
|
||||
E|31|sn27|en1|nl1|nr-1|lf1|rf0
|
||||
Topology 'city_data' dropped
|
Loading…
Reference in a new issue