[postgis-tickets] r15331 - Fix azimuth computation for 2.5D edge ends

Sandro Santilli strk at kbt.io
Sat Mar 11 08:23:45 PST 2017


Author: strk
Date: 2017-03-11 08:23:45 -0800 (Sat, 11 Mar 2017)
New Revision: 15331

Modified:
   branches/2.3/NEWS
   branches/2.3/liblwgeom/lwgeom_topo.c
   branches/2.3/topology/test/regress/topogeo_addlinestring.sql
   branches/2.3/topology/test/regress/topogeo_addlinestring_expected_newsnap
   branches/2.3/topology/test/regress/topogeo_addlinestring_expected_oldsnap
Log:
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

Closes #3711 (in 2.3 branch)

Modified: branches/2.3/NEWS
===================================================================
--- branches/2.3/NEWS	2017-03-11 16:21:18 UTC (rev 15330)
+++ branches/2.3/NEWS	2017-03-11 16:23:45 UTC (rev 15331)
@@ -1,3 +1,10 @@
+PostGIS 2.3.3dev
+YYYY/MM/DD
+
+  * Bug Fixes
+
+  - #3711, Azimuth error upon adding 2.5D edges to topology
+
 PostGIS 2.3.2
 2017/01/31
 

Modified: branches/2.3/liblwgeom/lwgeom_topo.c
===================================================================
--- branches/2.3/liblwgeom/lwgeom_topo.c	2017-03-11 16:21:18 UTC (rev 15330)
+++ branches/2.3/liblwgeom/lwgeom_topo.c	2017-03-11 16:23:45 UTC (rev 15331)
@@ -1401,7 +1401,7 @@
  * 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 @@
 
     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 @@
 
     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 @@
   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 @@
   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 @@
 
   /* 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;
   }

Modified: branches/2.3/topology/test/regress/topogeo_addlinestring.sql
===================================================================
--- branches/2.3/topology/test/regress/topogeo_addlinestring.sql	2017-03-11 16:21:18 UTC (rev 15330)
+++ branches/2.3/topology/test/regress/topogeo_addlinestring.sql	2017-03-11 16:23:45 UTC (rev 15331)
@@ -322,3 +322,13 @@
 '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');

Modified: branches/2.3/topology/test/regress/topogeo_addlinestring_expected_newsnap
===================================================================
--- branches/2.3/topology/test/regress/topogeo_addlinestring_expected_newsnap	2017-03-11 16:21:18 UTC (rev 15330)
+++ branches/2.3/topology/test/regress/topogeo_addlinestring_expected_newsnap	2017-03-11 16:23:45 UTC (rev 15331)
@@ -201,3 +201,8 @@
 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

Modified: branches/2.3/topology/test/regress/topogeo_addlinestring_expected_oldsnap
===================================================================
--- branches/2.3/topology/test/regress/topogeo_addlinestring_expected_oldsnap	2017-03-11 16:21:18 UTC (rev 15330)
+++ branches/2.3/topology/test/regress/topogeo_addlinestring_expected_oldsnap	2017-03-11 16:23:45 UTC (rev 15331)
@@ -198,3 +198,8 @@
 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



More information about the postgis-tickets mailing list