From: Sandro Santilli Date: Fri, 23 Mar 2012 22:54:10 +0000 (+0000) Subject: Do not abuse ST_Snap for tweaking edge endpoints (#1706) X-Git-Tag: 2.0.0rc1~31 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72d9f2d9387e23a3116ba40184ef97295d5da48d;p=postgis Do not abuse ST_Snap for tweaking edge endpoints (#1706) git-svn-id: http://svn.osgeo.org/postgis/trunk@9540 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/topology/sql/populate.sql.in.c b/topology/sql/populate.sql.in.c index 4cdfb8b8f..cdae2ed27 100644 --- a/topology/sql/populate.sql.in.c +++ b/topology/sql/populate.sql.in.c @@ -792,6 +792,7 @@ CREATE OR REPLACE FUNCTION topology.TopoGeo_addLinestring(atopology varchar, ali $$ DECLARE rec RECORD; + rec2 RECORD; sql TEXT; set1 GEOMETRY; set2 GEOMETRY; @@ -926,26 +927,29 @@ BEGIN RAISE DEBUG ' End Node: %', end_node; #endif - -- Added endpoints may have drifted due to tol, so + -- Added endpoints may have drifted due to tolerance, so -- we need to re-snap the edge to the new nodes before adding it - sql := 'SELECT ST_Collect(geom) FROM ' || quote_ident(atopology) - || '.node WHERE node_id IN (' || start_node || ',' || end_node || ')'; + sql := 'SELECT n1.geom as sn, n2.geom as en FROM ' || quote_ident(atopology) + || '.node n1, ' || quote_ident(atopology) + || '.node n2 WHERE n1.node_id = ' + || start_node || ' AND n2.node_id = ' || end_node; #ifdef POSTGIS_TOPOLOGY_DEBUG RAISE DEBUG '%', sql; #endif - EXECUTE sql INTO STRICT set2; -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Endnodes: %', ST_AsText(set2); -#endif - snapped := ST_Snap(rec.geom, set2, tol); -#ifdef POSTGIS_TOPOLOGY_DEBUG - RAISE DEBUG 'Snapped edge: %', ST_AsText(snapped); -#endif + + EXECUTE sql INTO STRICT rec2; + + snapped := ST_SetPoint( + ST_SetPoint(rec.geom, ST_NPoints(rec.geom)-1, rec2.en), + 0, rec2.sn); + + /* We might have introduced an invalidity (TODO: check this out) */ snapped := ST_CollectionExtract(ST_MakeValid(snapped), 2); #ifdef POSTGIS_TOPOLOGY_DEBUG RAISE DEBUG 'Cleaned edge: %', ST_AsText(snapped); #endif + -- Check if the so-snapped edge collapsed (see #1650) IF ST_IsEmpty(snapped) THEN #ifdef POSTGIS_TOPOLOGY_DEBUG diff --git a/topology/test/regress/topogeo_addlinestring.sql b/topology/test/regress/topogeo_addlinestring.sql index 6b35949e8..5162ac81c 100644 --- a/topology/test/regress/topogeo_addlinestring.sql +++ b/topology/test/regress/topogeo_addlinestring.sql @@ -198,7 +198,21 @@ SELECT '#1654.1', 'N', ST_AddIsoNode('city_data', 0, 'POINT(0 0)'); SELECT check_changes(); SELECT '#1654.2', TopoGeo_addLineString('city_data', 'LINESTRING(-10 1, 10 1)' -, 2); +, 2) ORDER BY 2; +SELECT check_changes(); + +-- Test snapping of new edge endpoints ( http://trac.osgeo.org/postgis/ticket/1706 ) + +DELETE FROM city_data.edge_data; DELETE FROM city_data.node; +DELETE FROM city_data.face where face_id > 0; + +SELECT '#1706.1', 'E', TopoGeo_AddLineString('city_data', + 'LINESTRING(20 10, 10 10, 9 12, 10 20)'); +SELECT check_changes(); + +SELECT '#1706.2', 'E*', TopoGeo_addLineString('city_data', + 'LINESTRING(10 0, 10 10, 15 10, 20 10)' +, 4) ORDER BY 3; SELECT check_changes(); diff --git a/topology/test/regress/topogeo_addlinestring_expected b/topology/test/regress/topogeo_addlinestring_expected index 1dae3b809..90ced32c6 100644 --- a/topology/test/regress/topogeo_addlinestring_expected +++ b/topology/test/regress/topogeo_addlinestring_expected @@ -42,9 +42,9 @@ E|15|sn12|en32 E|33|sn32|en19 E|34|sn31|en32 E|35|sn32|en33 -snap|7 snap|36 -snap|39 +snap|38 +snap|40 N|34||POINT(18 22) N|35||POINT(22.4 22) N|36||POINT(21 20.4) @@ -53,15 +53,16 @@ E|7|sn17|en35 E|19|sn14|en36 E|36|sn34|en17 E|37|sn35|en18 -E|38|sn36|en17 -E|39|sn35|en36 +E|38|sn17|en35 +E|39|sn36|en17 +E|40|sn35|en36 snap_again|7 snap_again|36 -snap_again|39 -crossover|42 -crossover|44 +snap_again|40 +crossover|43 crossover|45 crossover|46 +crossover|47 N|37||POINT(9 20) N|38||POINT(16.2 14) N|39||POINT(21 10) @@ -70,91 +71,102 @@ N|41||POINT(21 7) E|9|sn15|en38 E|20|sn9|en41 E|21|sn15|en40 -E|40|sn37|en16 -E|41|sn38|en14 -E|42|sn37|en38 -E|43|sn39|en14 -E|44|sn38|en39 -E|45|sn40|en37 -E|46|sn41|en39 -crossover_again|42 -crossover_again|44 +E|41|sn37|en16 +E|42|sn38|en14 +E|43|sn37|en38 +E|44|sn39|en14 +E|45|sn38|en39 +E|46|sn40|en37 +E|47|sn41|en39 +crossover_again|43 crossover_again|45 crossover_again|46 +crossover_again|47 contains|25 -contains|47 contains|48 +contains|49 N|42||POINT(14 34) N|43||POINT(7 36) -E|47|sn42|en22 -E|48|sn21|en43 -nodecross|49 +E|48|sn42|en22 +E|49|sn21|en43 nodecross|50 +nodecross|51 N|44||POINT(18 37) N|45||POINT(22 37) -E|49|sn44|en4 -E|50|sn4|en45 +E|50|sn44|en4 +E|51|sn4|en45 iso_ex_2segs|28 -#1613.1|51 +#1613.1|52 N|46||POINT(556267.6 144887) N|47||POINT(556267 144887.4) -E|51|sn46|en47 -#1613.2|53 +E|52|sn46|en47 #1613.2|54 +#1613.2|55 N|48||POINT(556250 144887) N|49||POINT(556267.6 144887) N|50||POINT(556310 144887) -E|51|sn46|en49 -E|52|sn49|en47 -E|53|sn48|en49 -E|54|sn49|en50 -#1631.1|55 +E|52|sn46|en49 +E|53|sn49|en47 +E|54|sn48|en49 +E|55|sn49|en50 +#1631.1|56 N|51||POINT(556267.6 144887) N|52||POINT(556267.6 144888) -E|55|sn51|en52 -#1631.2|56 +E|56|sn51|en52 #1631.2|57 +#1631.2|58 N|53||POINT(556254.6 144886.6) N|54||POINT(556267.6 144887) -E|56|sn53|en51 -E|57|sn51|en54 -#1641.1|58 +E|57|sn53|en51 +E|58|sn51|en54 +#1641.1|59 N|55||POINT(-0.2 0.4) N|56||POINT(0.2 0.4) -E|58|sn55|en56 -#1641.2|60 +E|59|sn55|en56 #1641.2|61 +#1641.2|62 N|57||POINT(0 0.2) N|58||POINT(0 0.4) N|59||POINT(0 0.4) -E|58|sn55|en58 -E|59|sn58|en56 -E|60|sn57|en58 -E|61|sn58|en59 -#1641.3|62 +E|59|sn55|en58 +E|60|sn58|en56 +E|61|sn57|en58 +E|62|sn58|en59 +#1641.3|63 N|60||POINT(-0.2 0.4) N|61||POINT(0.2 0.4) -E|62|sn60|en61 -#1641.4|64 +E|63|sn60|en61 #1641.4|65 +#1641.4|66 N|62||POINT(0 0.2) N|63||POINT(0 0.4) N|64||POINT(0 0.4) -E|62|sn60|en63 -E|63|sn63|en61 -E|64|sn62|en63 -E|65|sn63|en64 +E|63|sn60|en63 +E|64|sn63|en61 +E|65|sn62|en63 +E|66|sn63|en64 #1650.1 N|65|0|POINT(0 0) -#1650.3|66 +#1650.3|67 N|66||POINT(10 0) -E|66|sn65|en66 +E|67|sn65|en66 #1654.1|N|67 N|67|0|POINT(0 0) -#1654.2|67 #1654.2|68 +#1654.2|69 N|68||POINT(-10 1) N|69||POINT(10 1) -E|67|sn68|en67 -E|68|sn67|en69 +E|68|sn68|en67 +E|69|sn67|en69 +#1706.1|E|70 +N|70||POINT(20 10) +N|71||POINT(10 20) +E|70|sn70|en71 +#1706.2|E*|70 +#1706.2|E*|72 +N|72||POINT(10 0) +N|73||POINT(9 12) +E|70|sn70|en73 +E|71|sn73|en71 +E|72|sn72|en73 Topology 'city_data' dropped