[geos-commits] r3847 - in branches/3.3: . src/operation/buffer tests/unit/capi

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Jul 17 09:11:54 PDT 2013


Author: strk
Date: 2013-07-17 09:11:54 -0700 (Wed, 17 Jul 2013)
New Revision: 3847

Modified:
   branches/3.3/NEWS
   branches/3.3/src/operation/buffer/BufferInputLineSimplifier.cpp
   branches/3.3/src/operation/buffer/OffsetCurveBuilder.cpp
   branches/3.3/src/operation/buffer/OffsetSegmentGenerator.cpp
   branches/3.3/tests/unit/capi/GEOSOffsetCurveTest.cpp
Log:
Fix OffsetCurve op in presence of duplicated vertices (#602)

Modified: branches/3.3/NEWS
===================================================================
--- branches/3.3/NEWS	2013-07-17 16:07:56 UTC (rev 3846)
+++ branches/3.3/NEWS	2013-07-17 16:11:54 UTC (rev 3847)
@@ -2,6 +2,7 @@
 2012-MM-DD
 
 - Bug fixes / improvements
+    - Fix OffsetCurve op in presence of duplicated vertices (#602)
     - Fix LineSegmentVisitor copy ctor (#636)
     - Fix area boundary return from GEOSPointOnSurface (#623)
     - Speedup GEOSWKBReader_read (#621)

Modified: branches/3.3/src/operation/buffer/BufferInputLineSimplifier.cpp
===================================================================
--- branches/3.3/src/operation/buffer/BufferInputLineSimplifier.cpp	2013-07-17 16:07:56 UTC (rev 3846)
+++ branches/3.3/src/operation/buffer/BufferInputLineSimplifier.cpp	2013-07-17 16:11:54 UTC (rev 3847)
@@ -81,7 +81,6 @@
 	 * This ensures that end caps are generated consistently.
 	 */
 	unsigned int index = 1;
-	//int maxIndex = inputLine.size() - 1;
 
 	unsigned int midIndex = findNextNonDeletedIndex(index);
 	unsigned int lastIndex = findNextNonDeletedIndex(midIndex);
@@ -131,7 +130,7 @@
 	for (size_t i=0, n=inputLine.size(); i<n; ++i)
 	{
 		if (isDeleted[i] != DELETE)
-			coordList->add(inputLine[i]);
+			coordList->add(inputLine[i], false);
 	}
 
 	return coordList;

Modified: branches/3.3/src/operation/buffer/OffsetCurveBuilder.cpp
===================================================================
--- branches/3.3/src/operation/buffer/OffsetCurveBuilder.cpp	2013-07-17 16:07:56 UTC (rev 3846)
+++ branches/3.3/src/operation/buffer/OffsetCurveBuilder.cpp	2013-07-17 16:11:54 UTC (rev 3847)
@@ -36,6 +36,7 @@
 #include <geos/algorithm/NotRepresentableException.h>
 #include <geos/algorithm/HCoordinate.h>
 #include <geos/util.h>
+#include <geos/util/IllegalArgumentException.h>
 
 #include "BufferInputLineSimplifier.h"
 
@@ -130,6 +131,8 @@
 
 
     int n1 = simp1.size() - 1;
+    if ( ! n1 ) 
+      throw util::IllegalArgumentException("Cannot get offset of single-vertex line");
     segGen->initSideSegments(simp1[0], simp1[1], Position::LEFT);
     segGen->addFirstSegment();
     for (int i = 2; i <= n1; ++i) {
@@ -147,6 +150,8 @@
     const CoordinateSequence& simp2 = *simp2_;
 
     int n2 = simp2.size() - 1;
+    if ( ! n2 ) 
+      throw util::IllegalArgumentException("Cannot get offset of single-vertex line");
     segGen->initSideSegments(simp2[n2], simp2[n2-1], Position::LEFT);
     segGen->addFirstSegment();
     for (int i = n2-2; i >= 0; --i) {

Modified: branches/3.3/src/operation/buffer/OffsetSegmentGenerator.cpp
===================================================================
--- branches/3.3/src/operation/buffer/OffsetSegmentGenerator.cpp	2013-07-17 16:07:56 UTC (rev 3846)
+++ branches/3.3/src/operation/buffer/OffsetSegmentGenerator.cpp	2013-07-17 16:11:54 UTC (rev 3847)
@@ -135,6 +135,10 @@
 void
 OffsetSegmentGenerator::addNextSegment(const Coordinate &p, bool addStartPoint)
 {
+
+  // do nothing if points are equal
+  if (s2==p) return;
+
   // s0-s1-s2 are the coordinates of the previous segment
   // and the current one
   s0=s1;
@@ -145,9 +149,6 @@
   seg1.setCoordinates(s1, s2);
   computeOffsetSegment(seg1, side, distance, offset1);
 
-  // do nothing if points are equal
-  if (s1==s2) return;
-
   int orientation=CGAlgorithms::computeOrientation(s0, s1, s2);
   bool outsideTurn =
     (orientation==CGAlgorithms::CLOCKWISE

Modified: branches/3.3/tests/unit/capi/GEOSOffsetCurveTest.cpp
===================================================================
--- branches/3.3/tests/unit/capi/GEOSOffsetCurveTest.cpp	2013-07-17 16:07:56 UTC (rev 3846)
+++ branches/3.3/tests/unit/capi/GEOSOffsetCurveTest.cpp	2013-07-17 16:11:54 UTC (rev 3847)
@@ -189,5 +189,96 @@
         ));
     }
 
+    // left-side and right-side curve
+    // See http://trac.osgeo.org/postgis/ticket/633
+    template<>
+    template<>
+    void object::test<7>()
+    {
+        std::string wkt0("LINESTRING ("
+            "665.7317504882812500 133.0762634277343700,"
+            "1774.4752197265625000 19.9391822814941410,"
+            "756.2413940429687500 466.8306579589843700,"
+            "626.1337890625000000 1898.0147705078125000,"
+            "433.8007202148437500 404.6052856445312500)");
+        
+        geom1_ = GEOSGeomFromWKT(wkt0.c_str());
+        ensure( 0 != geom1_ );
+
+        double width = 57.164000837203;
+
+        // left-sided
+        {
+            geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_MITRE, 5.57);
+            ensure( 0 != geom2_ );
+            // likely, 5 >= 5
+            ensure(GEOSGeomGetNumPoints(geom2_) >= GEOSGeomGetNumPoints(geom1_));
+            wkt_ = GEOSWKTWriter_write(wktw_, geom2_);
+            GEOSGeom_destroy(geom2_);
+            GEOSFree(wkt_);
+            //ensure_equals(std::string(wkt_), ...);
+        }
+
+        // right-sided
+        {
+            width = -width;
+            geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_MITRE, 5.57);
+            ensure( 0 != geom2_ );
+            // likely, 5 >= 7
+            ensure(GEOSGeomGetNumPoints(geom2_) >= GEOSGeomGetNumPoints(geom1_));
+            wkt_ = GEOSWKTWriter_write(wktw_, geom2_);
+            //ensure_equals(std::string(wkt_), ...);
+        }
+    }
+
+    // Test duplicated inner vertex in input 
+    // See http://trac.osgeo.org/postgis/ticket/602
+    template<>
+    template<>
+    void object::test<8>()
+    {
+        double width = -1;
+
+        geom1_ = GEOSGeomFromWKT("LINESTRING(0 0,0 10,0 10,10 10)");
+        ensure( 0 != geom1_ );
+
+        geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_ROUND, 0);
+        ensure( "Unexpected exception", 0 != geom2_ );
+        wkt_ = GEOSWKTWriter_write(wktw_, geom2_);
+        ensure_equals(std::string(wkt_), "LINESTRING (10 9, 1 9, 1 0)");
+    }
+
+    // Test duplicated final vertex in input 
+    // See http://trac.osgeo.org/postgis/ticket/602
+    template<>
+    template<>
+    void object::test<9>()
+    {
+        double width = -1;
+
+        geom1_ = GEOSGeomFromWKT("LINESTRING(0 0,0 10,0 10)");
+        ensure( 0 != geom1_ );
+
+        geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_ROUND, 0);
+        ensure( "Unexpected exception", 0 != geom2_ );
+        wkt_ = GEOSWKTWriter_write(wktw_, geom2_);
+        ensure_equals(std::string(wkt_), "LINESTRING (1 10, 1 0)");
+    }
+
+    // Test only duplicated vertex in input 
+    // See http://trac.osgeo.org/postgis/ticket/602
+    template<>
+    template<>
+    void object::test<10>()
+    {
+        double width = -1;
+
+        geom1_ = GEOSGeomFromWKT("LINESTRING(0 10,0 10,0 10)");
+        ensure( 0 != geom1_ );
+
+        geom2_ = GEOSOffsetCurve(geom1_, width, 8, GEOSBUF_JOIN_ROUND, 0);
+        ensure( "Missing expected exception", 0 == geom2_ );
+    }
+
 } // namespace tut
 



More information about the geos-commits mailing list