]> granicus.if.org Git - postgis/commitdiff
Fix ring edge finding in ST_GetFaceEdges (#3265)
authorSandro Santilli <strk@keybit.net>
Wed, 26 Aug 2015 14:21:06 +0000 (14:21 +0000)
committerSandro Santilli <strk@keybit.net>
Wed, 26 Aug 2015 14:21:06 +0000 (14:21 +0000)
Includes regress test

git-svn-id: http://svn.osgeo.org/postgis/trunk@14007 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/lwgeom_topo.c
topology/test/regress/st_getfaceedges.sql
topology/test/regress/st_getfaceedges_expected

index ff71b19ae61bd082f4709929aabd169b1ee6ef0e..88b1aefe121a13c72fd4af953fa1930abd3c8a51 100644 (file)
@@ -2773,7 +2773,8 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
     /* ptarray_remove_repeated_points ? */
 
     getPoint2d_p(epa, 0, &p2);
-    LWDEBUGF(1, "Edges's 'first' point is %g,%g", p2.x, p2.y);
+    LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'first' point is %g,%g",
+                isoe->edge_id, p2.x, p2.y);
     LWDEBUGF(1, "Rings's 'from' point is still %g,%g", p1.x, p1.y);
     if ( p2d_same(&p1, &p2) )
     {
@@ -2784,22 +2785,35 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
       for ( j=1; j<epa->npoints; ++j )
       {
         getPoint2d_p(epa, j, &p2);
+        LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'next' point %d is %g,%g",
+                    isoe->edge_id, j, p2.x, p2.y);
         /* we won't check duplicated edge points */
         if ( p2d_same(&p1, &p2) ) continue;
         /* we assume there are no duplicated points in ring */
         getPoint2d_p(ring, from+1, &pt);
-        if ( p2d_same(&pt, &p2) )
-        {
-          match = 1;
-          break; /* no need to check more */
-        }
+        LWDEBUGF(1, "Ring's point %d is %g,%g",
+                    from+1, pt.x, pt.y);
+        match = p2d_same(&pt, &p2);
+        break; /* we want to check a single non-equal next vertex */
+      }
+#if POSTGIS_DEBUG_LEVEL > 0
+      if ( match ) {
+        LWDEBUGF(1, "Prev point of edge %" LWTFMT_ELEMID
+                    " matches ring vertex %d", isoe->edge_id, from+1);
+      } else {
+        LWDEBUGF(1, "Prev point of edge %" LWTFMT_ELEMID
+                    " does not match ring vertex %d", isoe->edge_id, from+1);
       }
+#endif
     }
-    else
+
+    if ( ! match )
     {
-      LWDEBUG(1, "p2d_same(p1,p2) returned false");
+      LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " did not match as forward",
+                 isoe->edge_id;);
       getPoint2d_p(epa, epa->npoints-1, &p2);
-      LWDEBUGF(1, "Edges's 'last' point is %g,%g", p2.x, p2.y);
+      LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'last' point is %g,%g",
+                  isoe->edge_id, p2.x, p2.y);
       if ( p2d_same(&p1, &p2) )
       {
         LWDEBUGF(1, "Last point of edge %" LWTFMT_ELEMID
@@ -2808,17 +2822,27 @@ _lwt_FindNextRingEdge(const POINTARRAY *ring, int from,
         for ( j=epa->npoints-2; j>=0; --j )
         {
           getPoint2d_p(epa, j, &p2);
+          LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " 'prev' point %d is %g,%g",
+                      isoe->edge_id, j, p2.x, p2.y);
           /* we won't check duplicated edge points */
           if ( p2d_same(&p1, &p2) ) continue;
           /* we assume there are no duplicated points in ring */
           getPoint2d_p(ring, from+1, &pt);
-          if ( p2d_same(&pt, &p2) )
-          {
-            match = 1;
-            break; /* no need to check more */
-          }
+          LWDEBUGF(1, "Ring's point %d is %g,%g",
+                      from+1, pt.x, pt.y);
+          match = p2d_same(&pt, &p2);
+          break; /* we want to check a single non-equal next vertex */
         }
       }
+#if POSTGIS_DEBUG_LEVEL > 0
+      if ( match ) {
+        LWDEBUGF(1, "Prev point of edge %" LWTFMT_ELEMID
+                    " matches ring vertex %d", isoe->edge_id, from+1);
+      } else {
+        LWDEBUGF(1, "Prev point of edge %" LWTFMT_ELEMID
+                    " does not match ring vertex %d", isoe->edge_id, from+1);
+      }
+#endif
     }
 
     if ( match ) return i;
@@ -2906,7 +2930,7 @@ lwt_GetFaceEdges(LWT_TOPOLOGY* topo, LWT_ELEMID face_id, LWT_ELEMID **out )
 #if 0
   {
   size_t sz;
-  char *wkt = lwgeom_to_wkt(face, WKT_ISO, 2, &sz);
+  char *wkt = lwgeom_to_wkt(face, WKT_ISO, 6, &sz);
   LWDEBUGF(1, "Geometry of face %" LWTFMT_ELEMID " is: %s",
               face_id, wkt);
   lwfree(wkt);
@@ -2960,10 +2984,13 @@ lwt_GetFaceEdges(LWT_TOPOLOGY* topo, LWT_ELEMID face_id, LWT_ELEMID **out )
                   nextedge->edge_id, i, j, j + nextline->points->npoints - 1);
 
 #if 0
+      {
       size_t sz;
+      char *wkt = lwgeom_to_wkt(lwline_as_lwgeom(nextline), WKT_ISO, 6, &sz);
       LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " is %s",
-                  nextedge->edge_id,
-lwgeom_to_wkt(lwline_as_lwgeom(nextline), WKT_ISO, 2, &sz));
+                  nextedge->edge_id, wkt);
+      lwfree(wkt);
+      }
 #endif
 
       j += nextline->points->npoints - 1;
index 2927d79c3a88b15df473eecec4994a74085374e4..6ff65b468ba5680a0f6a9c954cff6aaaefa60d5f 100644 (file)
@@ -28,5 +28,17 @@ SELECT 'F2', (topology.ST_GetFaceEdges('tt', 2)).*;
 
 SELECT 'F0', (topology.ST_GetFaceEdges('tt', 0)).*;
 
+SELECT topology.DropTopology('tt');
 
+-- See https://trac.osgeo.org/postgis/ticket/3265
+SELECT topology.CreateTopology('tt') > 0;
+SELECT '#3265.1', 'E'||topology.TopoGeo_addLinestring('tt',
+  'LINESTRING(150 150, 180 150, 180 180)');
+SELECT '#3265.2', 'E'||topology.TopoGeo_addLinestring('tt',
+  'LINESTRING(150 150, 180 180)');
+SELECT '#3265.3', 'E'||topology.TopoGeo_addLinestring('tt',
+  'LINESTRING(178 170, 178 161, 170 161, 178 170)');
+SELECT '#3265.4', 0, ST_GetFaceEdges('tt', 0);
+SELECT '#3265.5', 1, ST_GetFaceEdges('tt', 1);
+SELECT '#3265.6', 2, ST_GetFaceEdges('tt', 2);
 SELECT topology.DropTopology('tt');
index 556a240e441f573f02a24a11fca2b0c9ec779150..08d619f6f11ed9adb29ea3cc3ad8333c1753cc21 100644 (file)
@@ -28,3 +28,14 @@ F0|2|6
 F0|3|-7
 F0|4|-5
 Topology 'tt' dropped
+t
+#3265.1|E1
+#3265.2|E2
+#3265.3|E3
+#3265.4|0|(1,-1)
+#3265.4|0|(2,2)
+#3265.5|1|(1,-3)
+#3265.6|2|(1,1)
+#3265.6|2|(2,-2)
+#3265.6|2|(3,3)
+Topology 'tt' dropped