From: Sandro Santilli Date: Sat, 11 Mar 2017 16:21:18 +0000 (+0000) Subject: Fix azimuth computation for 2.5D edge ends X-Git-Tag: 2.4.0alpha~153 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=29c050afb4e12afa98c18a86842d71606cccfeb4;p=postgis Fix azimuth computation for 2.5D edge ends The change disreguard vertical movemements of the edge and computes azimuth of the first segment getting away from the node. Includes automated testcase See #3711 git-svn-id: http://svn.osgeo.org/postgis/trunk@15330 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/lwgeom_topo.c b/liblwgeom/lwgeom_topo.c index 9602238be..17535cfac 100644 --- a/liblwgeom/lwgeom_topo.c +++ b/liblwgeom/lwgeom_topo.c @@ -1401,7 +1401,7 @@ typedef struct edgeend_t { * Get first distinct vertex from endpoint * @param pa the pointarray to seek points in * @param ref the point we want to search a distinct one - * @param from vertex index to start from + * @param from vertex index to start from (will really start from "from"+dir) * @param dir 1 to go forward * -1 to go backward * @return 0 if edge is collapsed (no distinct points) @@ -1570,7 +1570,12 @@ _lwt_FindAdjacentEdges( LWT_TOPOLOGY* topo, LWT_ELEMID node, edgeend *data, if ( edge->start_node == node ) { getPoint2d_p(pa, 0, &p1); - getPoint2d_p(pa, 1, &p2); + if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &p2) ) + { + lwerror("Edge %d has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ", + edge->edge_id, p1.x, p1.y, p2.x, p2.y); + return -1; + } LWDEBUGF(1, "edge %" LWTFMT_ELEMID " starts on node %" LWTFMT_ELEMID ", edgeend is %g,%g-%g,%g", @@ -1627,7 +1632,12 @@ _lwt_FindAdjacentEdges( LWT_TOPOLOGY* topo, LWT_ELEMID node, edgeend *data, if ( edge->end_node == node ) { getPoint2d_p(pa, pa->npoints-1, &p1); - getPoint2d_p(pa, pa->npoints-2, &p2); + if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, pa->npoints-1, -1, &p2) ) + { + lwerror("Edge %d has no distinct vertices: [%.15g %.15g,%.15g %.15g]: ", + edge->edge_id, p1.x, p1.y, p2.x, p2.y); + return -1; + } LWDEBUGF(1, "edge %" LWTFMT_ELEMID " ends on node %" LWTFMT_ELEMID ", edgeend is %g,%g-%g,%g", edge->edge_id, node, p1.x, p1.y, p2.x, p2.y); @@ -2362,6 +2372,7 @@ _lwt_AddEdge( LWT_TOPOLOGY* topo, newedge.geom = geom; newedge.face_left = -1; newedge.face_right = -1; + /* TODO: should do the repeated points removal in 2D space */ cleangeom = lwgeom_remove_repeated_points( lwline_as_lwgeom(geom), 0 ); pa = lwgeom_as_lwline(cleangeom)->points; @@ -2375,18 +2386,17 @@ _lwt_AddEdge( LWT_TOPOLOGY* topo, span.cwFace = span.ccwFace = epan.cwFace = epan.ccwFace = -1; - /* Compute azimut of first edge end on start node */ + /* Compute azimuth of first edge end on start node */ getPoint2d_p(pa, 0, &p1); - getPoint2d_p(pa, 1, &pn); - if ( p2d_same(&p1, &pn) ) { + if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &pn) ) + { lwgeom_free(cleangeom); - /* Can still happen, for 2-point lines */ lwerror("Invalid edge (no two distinct vertices exist)"); return -1; } if ( ! azimuth_pt_pt(&p1, &pn, &span.myaz) ) { lwgeom_free(cleangeom); - lwerror("error computing azimuth of first edgeend [%g,%g-%g,%g]", + lwerror("error computing azimuth of first edgeend [%.15g %.15g,%.15g %.15g]", p1.x, p1.y, pn.x, pn.y); return -1; } @@ -2394,10 +2404,16 @@ _lwt_AddEdge( LWT_TOPOLOGY* topo, /* Compute azimuth of last edge end on end node */ getPoint2d_p(pa, pa->npoints-1, &p2); - getPoint2d_p(pa, pa->npoints-2, &pn); + if ( ! _lwt_FirstDistinctVertex2D(pa, &p2, pa->npoints-1, -1, &pn) ) + { + lwgeom_free(cleangeom); + /* This should never happen as we checked the edge while computing first edgend */ + lwerror("Invalid clean edge (no two distinct vertices exist) - should not happen"); + return -1; + } lwgeom_free(cleangeom); if ( ! azimuth_pt_pt(&p2, &pn, &epan.myaz) ) { - lwerror("error computing azimuth of last edgeend [%g,%g-%g,%g]", + lwerror("error computing azimuth of last edgeend [%.15g %.15g,%.15g %.15g]", p2.x, p2.y, pn.x, pn.y); return -1; } diff --git a/topology/test/regress/topogeo_addlinestring.sql b/topology/test/regress/topogeo_addlinestring.sql index 283ef7048..83397d054 100644 --- a/topology/test/regress/topogeo_addlinestring.sql +++ b/topology/test/regress/topogeo_addlinestring.sql @@ -322,3 +322,13 @@ SELECT 't3412.L2', TopoGeo_AddLinestring('bug3412', '0102000000020000003AB42BBFEE4C22410010C5A997A6524167BB5DBDEE4C224117FE3DA85FA75241' ::geometry, 0); SELECT 't3412.end', DropTopology('bug3412'); + +-- See http://trac.osgeo.org/postgis/ticket/3711 +SELECT 't3371.start', topology.CreateTopology('bug3711', 0, 0, true) > 1; +SELECT 't3371.L1', topology.TopoGeo_AddLineString('bug3711', +'LINESTRING (618369 4833784 0.88, 618370 4833784 1.93, 618370 4833780 1.90)' +::geometry, 0); +SELECT 't3371.L2', topology.TopoGeo_AddLineString( 'bug3711', +'LINESTRING (618370 4833780 1.92, 618370 4833784 1.90, 618371 4833780 1.93)' +::geometry, 0); +SELECT 't3371.end', topology.DropTopology('bug3711'); diff --git a/topology/test/regress/topogeo_addlinestring_expected_newsnap b/topology/test/regress/topogeo_addlinestring_expected_newsnap index 0c564763c..475bb7598 100644 --- a/topology/test/regress/topogeo_addlinestring_expected_newsnap +++ b/topology/test/regress/topogeo_addlinestring_expected_newsnap @@ -201,3 +201,8 @@ t3412.L2|3 t3412.L2|5 t3412.L2|4 t3412.end|Topology 'bug3412' dropped +t3371.start|t +t3371.L1|1 +t3371.L2|3 +t3371.L2|2 +t3371.end|Topology 'bug3711' dropped diff --git a/topology/test/regress/topogeo_addlinestring_expected_oldsnap b/topology/test/regress/topogeo_addlinestring_expected_oldsnap index dec535d4b..f3e29c3c8 100644 --- a/topology/test/regress/topogeo_addlinestring_expected_oldsnap +++ b/topology/test/regress/topogeo_addlinestring_expected_oldsnap @@ -198,3 +198,8 @@ t3412.L2|3 t3412.L2|5 t3412.L2|4 t3412.end|Topology 'bug3412' dropped +t3371.start|t +t3371.L1|1 +t3371.L2|3 +t3371.L2|2 +t3371.end|Topology 'bug3711' dropped