[postgis-tickets] r14542 - Decimate lines on topology load
Sandro Santilli
strk at keybit.net
Mon Jan 4 06:45:01 PST 2016
Author: strk
Date: 2016-01-04 06:45:01 -0800 (Mon, 04 Jan 2016)
New Revision: 14542
Modified:
branches/2.2/NEWS
branches/2.2/liblwgeom/lwgeom_topo.c
branches/2.2/topology/test/regress/topogeo_addlinestring.sql
branches/2.2/topology/test/regress/topogeo_addlinestring_expected_newsnap
branches/2.2/topology/test/regress/topogeo_addlinestring_expected_oldsnap
Log:
Decimate lines on topology load
Improves snapping robustness
Updates expected results in topogeo_addlinestring for old
and new snapping code (GEOS-3.3.8-, GEOS-3.3.9+)
Fixes #3380 and #3402, including automated tests for them.
Modified: branches/2.2/NEWS
===================================================================
--- branches/2.2/NEWS 2016-01-04 14:41:51 UTC (rev 14541)
+++ branches/2.2/NEWS 2016-01-04 14:45:01 UTC (rev 14542)
@@ -16,6 +16,7 @@
- #3375, crash in repeated point removal for collection(point)
- #3378, Fix handling of hierarchical TopoGeometries
in presence of multiple topologies
+ - #3380, #3402, Decimate lines on topology load
- #3389, Buffer overflow in lwgeom_to_geojson
- #3388, #3410, Fix missing end-points in ST_Removepoints
- #3393, ST_Area NaN for some polygons
Modified: branches/2.2/liblwgeom/lwgeom_topo.c
===================================================================
--- branches/2.2/liblwgeom/lwgeom_topo.c 2016-01-04 14:41:51 UTC (rev 14541)
+++ branches/2.2/liblwgeom/lwgeom_topo.c 2016-01-04 14:45:01 UTC (rev 14542)
@@ -5095,8 +5095,9 @@
LWGEOM *prj;
int contains;
GEOSGeometry *prjg, *gg;
+ LWT_ELEMID edge_id = e->edge_id;
- LWDEBUGF(1, "Splitting edge %" LWTFMT_ELEMID, e->edge_id);
+ LWDEBUGF(1, "Splitting edge %" LWTFMT_ELEMID, edge_id);
/* project point to line, split edge by point */
prj = lwgeom_closest_point(g, pt);
@@ -5155,7 +5156,7 @@
LWDEBUGF(1, "Edge %" LWTFMT_ELEMID
" does not contain projected point to it",
- e->edge_id);
+ edge_id);
/* In order to reduce the robustness issues, we'll pick
* an edge that contains the projected point, if possible */
@@ -5226,7 +5227,7 @@
}
#endif
- if ( -1 == lwt_ChangeEdgeGeom( topo, e->edge_id, snapline ) )
+ if ( -1 == lwt_ChangeEdgeGeom( topo, edge_id, snapline ) )
{
/* TODO: should have invoked lwerror already, leaking memory */
lwgeom_free(prj);
@@ -5250,7 +5251,7 @@
#endif
/* TODO: pass 1 as last argument (skipChecks) ? */
- id = lwt_ModEdgeSplit( topo, e->edge_id, lwgeom_as_lwpoint(prj), 0 );
+ id = lwt_ModEdgeSplit( topo, edge_id, lwgeom_as_lwpoint(prj), 0 );
if ( -1 == id )
{
/* TODO: should have invoked lwerror already, leaking memory */
@@ -5261,6 +5262,20 @@
}
lwgeom_free(prj);
+
+ /*
+ * TODO: decimate the two new edges with the given tolerance ?
+ *
+ * the edge identifiers to decimate would be: edge_id and "id"
+ * The problem here is that decimation of existing edges
+ * may introduce intersections or topological inconsistencies,
+ * for example:
+ *
+ * - A node may end up falling on the other side of the edge
+ * - The decimated edge might intersect another existing edge
+ *
+ */
+
break; /* we only want to snap a single edge */
}
_lwt_release_edges(edges, num);
@@ -5358,13 +5373,16 @@
{
LWCOLLECTION *col;
LWPOINT *start_point, *end_point;
- LWGEOM *tmp;
+ LWGEOM *tmp, *tmp2;
LWT_ISO_NODE *node;
LWT_ELEMID nid[2]; /* start_node, end_node */
LWT_ELEMID id; /* edge id */
POINT4D p4d;
int nn, i;
+ LWDEBUGG(1, lwline_as_lwgeom(edge), "_lwtAddLineEdge");
+ LWDEBUGF(1, "_lwtAddLineEdge with tolerance %g", tol);
+
start_point = lwline_get_lwpoint(edge, 0);
if ( ! start_point )
{
@@ -5429,7 +5447,6 @@
col = lwgeom_as_lwcollection(tmp);
if ( col )
{{
- LWGEOM *tmp2;
col = lwcollection_extract(col, LINETYPE);
@@ -5481,7 +5498,34 @@
}
/* No previously existing edge was found, we'll add one */
- /* TODO: skip checks, I guess ? */
+
+ /* Remove consecutive vertices below given tolerance
+ * on edge addition */
+ if ( tol )
+ {{
+ tmp2 = lwline_remove_repeated_points(edge, tol);
+ LWDEBUGG(1, tmp2, "Repeated-point removed");
+ edge = lwgeom_as_lwline(tmp2);
+ lwgeom_free(tmp);
+ tmp = tmp2;
+
+ /* check if the so-decimated edge _now_ exists */
+ id = _lwt_GetEqualEdge ( topo, edge );
+ LWDEBUGF(1, "_lwt_GetEqualEdge returned %" LWTFMT_ELEMID, id);
+ if ( id == -1 )
+ {
+ lwgeom_free(tmp); /* probably too late, due to internal lwerror */
+ return -1;
+ }
+ if ( id )
+ {
+ lwgeom_free(tmp); /* takes "edge" down with it */
+ return id;
+ }
+ }}
+
+
+ /* TODO: skip checks ? */
id = lwt_AddEdgeModFace( topo, nid[0], nid[1], edge, 0 );
LWDEBUGF(1, "lwt_AddEdgeModFace returned %" LWTFMT_ELEMID, id);
if ( id == -1 )
@@ -5524,7 +5568,7 @@
LWGEOM *geomsbuf[1];
LWGEOM **geoms;
int ngeoms;
- LWGEOM *noded;
+ LWGEOM *noded, *tmp;
LWCOLLECTION *col;
LWT_ELEMID *ids;
LWT_ISO_EDGE *edges;
@@ -5540,8 +5584,17 @@
LWDEBUGF(1, "Working tolerance:%.15g", tol);
LWDEBUGF(1, "Input line has srid=%d", line->srid);
+ /* Remove consecutive vertices below given tolerance upfront */
+ if ( tol )
+ {{
+ LWLINE *clean = lwgeom_as_lwline(lwline_remove_repeated_points(line, tol));
+ tmp = lwline_as_lwgeom(clean); /* NOTE: might collapse to non-simple */
+ LWDEBUGG(1, tmp, "Repeated-point removed");
+ }} else tmp=(LWGEOM*)line;
+
/* 1. Self-node */
- noded = lwgeom_node((LWGEOM*)line);
+ noded = lwgeom_node((LWGEOM*)tmp);
+ if ( tmp != (LWGEOM*)line ) lwgeom_free(tmp);
if ( ! noded ) return NULL; /* should have called lwerror already */
LWDEBUGG(1, noded, "Noded");
Modified: branches/2.2/topology/test/regress/topogeo_addlinestring.sql
===================================================================
--- branches/2.2/topology/test/regress/topogeo_addlinestring.sql 2016-01-04 14:41:51 UTC (rev 14541)
+++ branches/2.2/topology/test/regress/topogeo_addlinestring.sql 2016-01-04 14:45:01 UTC (rev 14542)
@@ -276,6 +276,38 @@
ORDER BY 1;
SELECT 't3280.end', topology.DropTopology('bug3280');
+-- See http://trac.osgeo.org/postgis/ticket/3380
+SELECT 't3380.start', CreateTopology( 'bug3380', 0, 0.01) > 0;
+SELECT 't3380.L1', TopoGeo_AddLinestring('bug3380', '
+LINESTRING(
+1612829.90652844007126987 4841274.48807844985276461,
+1612830.1566380700096488 4841287.23833953030407429,
+1612883.15799825009889901 4841277.73794914968311787)
+', 0);
+SELECT 't3380.L2', TopoGeo_AddLinestring('bug3380', '
+LINESTRING(
+1612790.88055733009241521 4841286.88526585046201944,
+1612830.15823523001745343 4841287.12674008030444384,
+1612829.98813172010704875 4841274.56198261026293039)
+', 0);
+SELECT 't3380.L3', TopoGeo_AddLinestring('bug3380', '
+ LINESTRING(
+1612830.15823523 4841287.12674008,
+1612881.64990281 4841274.56198261)
+', 0);
+SELECT 't3380.end', DropTopology( 'bug3380' );
+
+-- See http://trac.osgeo.org/postgis/ticket/3402
+
+SELECT 't3402.start', CreateTopology('bug3402') > 1;
+SELECT 't3402.L1', TopoGeo_addLinestring('bug3402',
+'010200000003000000C1AABC2B192739418E7DE0E6AB9652411F85EB5119283941F6285CEF2D9652411F85EB5128283941F6285CCF2C965241'
+, 0);
+SELECT 't3402.L2', TopoGeo_addLinestring('bug3402',
+'010200000003000000BCAABC2B192739418F7DE0E6AB96524185EB51382828394115AE47D12C96524187EB51382828394115AE47D12C965241'
+, 0);
+SELECT 't3402.end', DropTopology('bug3402');
+
-- See http://trac.osgeo.org/postgis/ticket/3412
SELECT 't3412.start', CreateTopology('bug3412', 0, 0.001) > 0;
SELECT 't3412.L1', TopoGeo_AddLinestring('bug3412',
Modified: branches/2.2/topology/test/regress/topogeo_addlinestring_expected_newsnap
===================================================================
--- branches/2.2/topology/test/regress/topogeo_addlinestring_expected_newsnap 2016-01-04 14:41:51 UTC (rev 14541)
+++ branches/2.2/topology/test/regress/topogeo_addlinestring_expected_newsnap 2016-01-04 14:45:01 UTC (rev 14542)
@@ -43,9 +43,9 @@
E|33|sn32|en19
E|34|sn31|en32
E|35|sn32|en33
+snap|7
snap|36
snap|39
-snap|40
N|34||POINT(18 22)
N|35||POINT(22.4 22)
N|36||POINT(21 20.4)
@@ -56,14 +56,13 @@
E|37|sn35|en18
E|38|sn36|en17
E|39|sn35|en36
-E|40|sn17|en35
+snap_again|7
snap_again|36
snap_again|39
-snap_again|40
-crossover|43
+crossover|42
+crossover|44
crossover|45
crossover|46
-crossover|47
N|37||POINT(9 20)
N|38||POINT(16.2 14)
N|39||POINT(21 10)
@@ -72,110 +71,112 @@
E|9|sn15|en38
E|20|sn9|en41
E|21|sn15|en40
-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
+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
crossover_again|45
crossover_again|46
-crossover_again|47
contains|25
+contains|47
contains|48
-contains|49
N|42||POINT(7 36)
N|43||POINT(14 34)
-E|48|sn21|en42
-E|49|sn43|en22
+E|47|sn21|en42
+E|48|sn43|en22
+nodecross|49
nodecross|50
-nodecross|51
N|44||POINT(18 37)
N|45||POINT(22 37)
-E|50|sn44|en4
-E|51|sn4|en45
+E|49|sn44|en4
+E|50|sn4|en45
iso_ex_2segs|28
-#1613.1|52
+#1613.1|51
N|46||POINT(556267.6 144887)
N|47||POINT(556267 144887.4)
-E|52|sn46|en47
+E|51|sn46|en47
+#1613.2|53
#1613.2|54
-#1613.2|55
N|48||POINT(556250 144887)
N|49||POINT(556267.6 144887)
N|50||POINT(556310 144887)
-E|52|sn46|en49
-E|53|sn49|en47
-E|54|sn48|en49
-E|55|sn49|en50
-#1631.1|56
+E|51|sn46|en49
+E|52|sn49|en47
+E|53|sn48|en49
+E|54|sn49|en50
+#1631.1|55
N|51||POINT(556267.6 144887)
N|52||POINT(556267.6 144888)
-E|56|sn51|en52
+E|55|sn51|en52
+#1631.2|56
#1631.2|57
-#1631.2|58
N|53||POINT(556254.6 144886.6)
N|54||POINT(556267.6 144887)
-E|57|sn53|en51
-E|58|sn51|en54
-#1641.1|59
+E|56|sn53|en51
+E|57|sn51|en54
+#1641.1|58
N|55||POINT(-0.2 0.4)
N|56||POINT(0.2 0.4)
-E|59|sn55|en56
+E|58|sn55|en56
+#1641.2|60
#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|59|sn55|en58
-E|60|sn58|en56
-E|61|sn57|en58
-E|62|sn58|en59
-#1641.3|63
+E|58|sn55|en58
+E|59|sn58|en56
+E|60|sn57|en58
+E|61|sn58|en59
+#1641.3|62
N|60||POINT(-0.2 0.4)
N|61||POINT(0.2 0.4)
-E|63|sn60|en61
+E|62|sn60|en61
+#1641.4|64
#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|63|sn60|en63
-E|64|sn63|en61
-E|65|sn62|en63
-E|66|sn63|en64
+E|62|sn60|en63
+E|63|sn63|en61
+E|64|sn62|en63
+E|65|sn63|en64
#1650.1
N|65|0|POINT(0 0)
-#1650.3|67
+#1650.3|66
N|66||POINT(10 0)
-E|67|sn65|en66
+E|66|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|68|sn68|en67
-E|69|sn67|en69
-#1706.1|E|70
+E|67|sn68|en67
+E|68|sn67|en69
+#1706.1|E|69
N|70||POINT(20 10)
N|71||POINT(10 20)
-E|70|sn70|en71
-#1706.2|E*|70
+E|69|sn70|en71
+#1706.2|E*|69
+#1706.2|E*|71
#1706.2|E*|72
-#1706.2|E*|73
N|72||POINT(10 0)
N|73||POINT(10 10)
N|74||POINT(15 10)
-E|70|sn70|en74
-E|71|sn73|en71
-E|72|sn72|en73
-E|73|sn74|en73
+E|69|sn70|en74
+E|70|sn73|en71
+E|71|sn72|en73
+E|72|sn74|en73
#1714.1|N|75
N|75|0|POINT(10 0)
-#1714.2|E*|74
+#1714.2|E*|73
+N|76||POINT(0 20)
+E|73|sn75|en76
Topology 'city_data' dropped
t3280.start|t
t3280|L11
@@ -183,6 +184,16 @@
t3280|L1b4
t3280|L1b2
t3280.end|Topology 'bug3280' dropped
+t3380.start|t
+t3380.L1|1
+t3380.L2|3
+t3380.L2|4
+t3380.L3|5
+t3380.end|Topology 'bug3380' dropped
+t3402.start|t
+t3402.L1|1
+t3402.L2|3
+t3402.end|Topology 'bug3402' dropped
t3412.start|t
t3412.L1|1
t3412.L2|2
Modified: branches/2.2/topology/test/regress/topogeo_addlinestring_expected_oldsnap
===================================================================
--- branches/2.2/topology/test/regress/topogeo_addlinestring_expected_oldsnap 2016-01-04 14:41:51 UTC (rev 14541)
+++ branches/2.2/topology/test/regress/topogeo_addlinestring_expected_oldsnap 2016-01-04 14:45:01 UTC (rev 14542)
@@ -43,9 +43,9 @@
E|33|sn32|en19
E|34|sn31|en32
E|35|sn32|en33
+snap|7
snap|36
snap|39
-snap|40
N|34||POINT(18 22)
N|35||POINT(22.4 22)
N|36||POINT(21 20.4)
@@ -56,14 +56,13 @@
E|37|sn35|en18
E|38|sn36|en17
E|39|sn35|en36
-E|40|sn17|en35
snap_again|7
snap_again|36
snap_again|39
-crossover|43
+crossover|42
+crossover|44
crossover|45
crossover|46
-crossover|47
N|37||POINT(9 20)
N|38||POINT(16.2 14)
N|39||POINT(21 10)
@@ -72,109 +71,109 @@
E|9|sn15|en38
E|20|sn9|en41
E|21|sn15|en40
-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
+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
crossover_again|45
crossover_again|46
-crossover_again|47
contains|25
+contains|47
contains|48
-contains|49
N|42||POINT(7 36)
N|43||POINT(14 34)
-E|48|sn21|en42
-E|49|sn43|en22
+E|47|sn21|en42
+E|48|sn43|en22
+nodecross|49
nodecross|50
-nodecross|51
N|44||POINT(18 37)
N|45||POINT(22 37)
-E|50|sn44|en4
-E|51|sn4|en45
+E|49|sn44|en4
+E|50|sn4|en45
iso_ex_2segs|28
-#1613.1|52
+#1613.1|51
N|46||POINT(556267.6 144887)
N|47||POINT(556267 144887.4)
-E|52|sn46|en47
+E|51|sn46|en47
+#1613.2|53
#1613.2|54
-#1613.2|55
N|48||POINT(556250 144887)
N|49||POINT(556267.6 144887)
N|50||POINT(556310 144887)
-E|52|sn46|en49
-E|53|sn49|en47
-E|54|sn48|en49
-E|55|sn49|en50
-#1631.1|56
+E|51|sn46|en49
+E|52|sn49|en47
+E|53|sn48|en49
+E|54|sn49|en50
+#1631.1|55
N|51||POINT(556267.6 144887)
N|52||POINT(556267.6 144888)
-E|56|sn51|en52
+E|55|sn51|en52
+#1631.2|56
#1631.2|57
-#1631.2|58
N|53||POINT(556254.6 144886.6)
N|54||POINT(556267.6 144887)
-E|57|sn53|en51
-E|58|sn51|en54
-#1641.1|59
+E|56|sn53|en51
+E|57|sn51|en54
+#1641.1|58
N|55||POINT(-0.2 0.4)
N|56||POINT(0.2 0.4)
-E|59|sn55|en56
+E|58|sn55|en56
+#1641.2|60
#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|59|sn55|en58
-E|60|sn58|en56
-E|61|sn57|en58
-E|62|sn58|en59
-#1641.3|63
+E|58|sn55|en58
+E|59|sn58|en56
+E|60|sn57|en58
+E|61|sn58|en59
+#1641.3|62
N|60||POINT(-0.2 0.4)
N|61||POINT(0.2 0.4)
-E|63|sn60|en61
+E|62|sn60|en61
+#1641.4|64
#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|63|sn60|en63
-E|64|sn63|en61
-E|65|sn62|en63
-E|66|sn63|en64
+E|62|sn60|en63
+E|63|sn63|en61
+E|64|sn62|en63
+E|65|sn63|en64
#1650.1
N|65|0|POINT(0 0)
-#1650.3|67
+#1650.3|66
N|66||POINT(10 0)
-E|67|sn65|en66
+E|66|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|68|sn68|en67
-E|69|sn67|en69
-#1706.1|E|70
+E|67|sn68|en67
+E|68|sn67|en69
+#1706.1|E|69
N|70||POINT(20 10)
N|71||POINT(10 20)
-E|70|sn70|en71
-#1706.2|E*|70
-#1706.2|E*|72
+E|69|sn70|en71
+#1706.2|E*|69
+#1706.2|E*|71
N|72||POINT(10 0)
N|73||POINT(9 12)
-E|70|sn70|en73
-E|71|sn73|en71
-E|72|sn72|en73
+E|69|sn70|en73
+E|70|sn73|en71
+E|71|sn72|en73
#1714.1|N|74
N|74|0|POINT(10 0)
-#1714.2|E*|73
+#1714.2|E*|72
N|75||POINT(0 20)
-E|73|sn74|en75
+E|72|sn74|en75
Topology 'city_data' dropped
t3280.start|t
t3280|L11
@@ -182,6 +181,16 @@
t3280|L1b4
t3280|L1b2
t3280.end|Topology 'bug3280' dropped
+t3380.start|t
+t3380.L1|1
+t3380.L2|3
+t3380.L2|4
+t3380.L3|5
+t3380.end|Topology 'bug3380' dropped
+t3402.start|t
+t3402.L1|1
+t3402.L2|3
+t3402.end|Topology 'bug3402' dropped
t3412.start|t
t3412.L1|1
t3412.L2|2
More information about the postgis-tickets
mailing list