[geos-commits] r3228 - in trunk: . include/geos/operation/linemerge src/operation/linemerge tests/unit tests/unit/operation tests/unit/operation/linemerge

svn_geos at osgeo.org svn_geos at osgeo.org
Mon Feb 21 11:14:39 EST 2011


Author: strk
Date: 2011-02-21 08:14:38 -0800 (Mon, 21 Feb 2011)
New Revision: 3228

Added:
   trunk/tests/unit/operation/linemerge/
   trunk/tests/unit/operation/linemerge/LineMergerTest.cpp
Modified:
   trunk/NEWS
   trunk/include/geos/operation/linemerge/EdgeString.h
   trunk/include/geos/operation/linemerge/LineMergeEdge.h
   trunk/include/geos/operation/linemerge/LineMergeGraph.h
   trunk/include/geos/operation/linemerge/LineMerger.h
   trunk/src/operation/linemerge/EdgeString.cpp
   trunk/src/operation/linemerge/LineMergeEdge.cpp
   trunk/src/operation/linemerge/LineMergeGraph.cpp
   trunk/src/operation/linemerge/LineMerger.cpp
   trunk/tests/unit/Makefile.am
Log:
Sync linemerge namespace to JTS-1.12 fixing LineMerger to skip lines with only a single unique coordinate; reduce some heap allocations; add unit testing for Linemerger

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/NEWS	2011-02-21 16:14:38 UTC (rev 3228)
@@ -31,6 +31,7 @@
   - CAPI: do not leak contexts when using the non-reentrant interface
   - Fix duplicated dangles returned by Polygonizer
   - Fix SnapIfNeededOverlayOp to throw the originating exception
+  - Fixed LineMerger to skip lines with only a single unique coordinate
 
 Changes in 3.2.0 
 2009-12-14

Modified: trunk/include/geos/operation/linemerge/EdgeString.h
===================================================================
--- trunk/include/geos/operation/linemerge/EdgeString.h	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/include/geos/operation/linemerge/EdgeString.h	2011-02-21 16:14:38 UTC (rev 3228)
@@ -4,7 +4,9 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2006 Refractions Research Inc.
+ * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU Lesser General Public Licence as published
@@ -13,7 +15,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/EdgeString.java rev. 1.5 (JTS-1.10)
+ * Last port: operation/linemerge/EdgeString.java r320 (JTS-1.12)
  *
  **********************************************************************/
 
@@ -50,7 +52,7 @@
 class GEOS_DLL EdgeString {
 private:
 	const geom::GeometryFactory *factory;
-	std::vector<LineMergeDirectedEdge*> *directedEdges;
+	std::vector<LineMergeDirectedEdge*> directedEdges;
 	geom::CoordinateSequence *coordinates;
 	geom::CoordinateSequence* getCoordinates();
 public:

Modified: trunk/include/geos/operation/linemerge/LineMergeEdge.h
===================================================================
--- trunk/include/geos/operation/linemerge/LineMergeEdge.h	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/include/geos/operation/linemerge/LineMergeEdge.h	2011-02-21 16:14:38 UTC (rev 3228)
@@ -13,7 +13,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/LineMergeEdge.java rev. 1.4 (JTS-1.10)
+ * Last port: operation/linemerge/LineMergeEdge.java r320 (JTS-1.12)
  *
  **********************************************************************/
 

Modified: trunk/include/geos/operation/linemerge/LineMergeGraph.h
===================================================================
--- trunk/include/geos/operation/linemerge/LineMergeGraph.h	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/include/geos/operation/linemerge/LineMergeGraph.h	2011-02-21 16:14:38 UTC (rev 3228)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2006 Refractions Research Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -13,7 +14,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/LineMergeGraph.java rev. 1.5 (JTS-1.10)
+ * Last port: operation/linemerge/LineMergeGraph.java r320 (JTS-1.12)
  *
  **********************************************************************/
 
@@ -69,9 +70,11 @@
 
 public:
 
-	/**
+	/** \brief
 	 * Adds an Edge, DirectedEdges, and Nodes for the given
 	 * LineString representation of an edge. 
+	 * 
+	 * Empty lines or lines with all coordinates equal are not added.
 	 */
 	void addEdge(const geom::LineString *lineString);
 

Modified: trunk/include/geos/operation/linemerge/LineMerger.h
===================================================================
--- trunk/include/geos/operation/linemerge/LineMerger.h	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/include/geos/operation/linemerge/LineMerger.h	2011-02-21 16:14:38 UTC (rev 3228)
@@ -13,7 +13,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/LineMerger.java rev. 1.7 (JTS-1.10)
+ * Last port: operation/linemerge/LineMerger.java r320 (JTS-1.11)
  *
  **********************************************************************/
 
@@ -126,6 +126,7 @@
 	/**
 	 * \brief
 	 * Returns the LineStrings built by the merging process.
+	 *
 	 * Ownership of vector _and_ its elements to caller.
 	 */
 	std::vector<geom::LineString*>* getMergedLineStrings();

Modified: trunk/src/operation/linemerge/EdgeString.cpp
===================================================================
--- trunk/src/operation/linemerge/EdgeString.cpp	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/src/operation/linemerge/EdgeString.cpp	2011-02-21 16:14:38 UTC (rev 3228)
@@ -4,6 +4,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
  * Copyright (C) 2006 Refractions Research Inc.
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
@@ -14,7 +15,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/EdgeString.java rev. 1.5 (JTS-1.10)
+ * Last port: operation/linemerge/EdgeString.java r320 (JTS-1.12)
  *
  **********************************************************************/
 
@@ -42,13 +43,12 @@
  */
 EdgeString::EdgeString(const GeometryFactory *newFactory):
 	factory(newFactory),
-	directedEdges(new vector<LineMergeDirectedEdge*>()),
+	directedEdges(),
 	coordinates(NULL)
 {
 }
 
 EdgeString::~EdgeString() {
-	delete directedEdges;
 }
 
 /**
@@ -57,7 +57,7 @@
 void
 EdgeString::add(LineMergeDirectedEdge *directedEdge)
 {
-	directedEdges->push_back(directedEdge);
+	directedEdges.push_back(directedEdge);
 }
 
 CoordinateSequence *
@@ -67,8 +67,8 @@
 		int forwardDirectedEdges = 0;
 		int reverseDirectedEdges = 0;
 		coordinates=factory->getCoordinateSequenceFactory()->create(NULL);
-		for (int i=0;i<(int)directedEdges->size();i++) {
-			LineMergeDirectedEdge* directedEdge=(*directedEdges)[i];
+		for (std::size_t i=0, e=directedEdges.size(); i<e; ++i) {
+			LineMergeDirectedEdge* directedEdge = directedEdges[i];
 			if (directedEdge->getEdgeDirection()) {
 				forwardDirectedEdges++;
 			} else {
@@ -76,8 +76,7 @@
 			}
 
 			assert(dynamic_cast<LineMergeEdge*>(directedEdge->getEdge()));
-			LineMergeEdge* lme=static_cast<LineMergeEdge*>(
-				directedEdge->getEdge());
+			LineMergeEdge* lme=static_cast<LineMergeEdge*>( directedEdge->getEdge());
 
 			coordinates->add(lme->getLine()->getCoordinatesRO(),
 					false,

Modified: trunk/src/operation/linemerge/LineMergeEdge.cpp
===================================================================
--- trunk/src/operation/linemerge/LineMergeEdge.cpp	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/src/operation/linemerge/LineMergeEdge.cpp	2011-02-21 16:14:38 UTC (rev 3228)
@@ -14,7 +14,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/LineMergeEdge.java rev. 1.4 (JTS-1.10)
+ * Last port: operation/linemerge/LineMergeEdge.java r320 (JTS-1.12)
  *
  **********************************************************************/
 

Modified: trunk/src/operation/linemerge/LineMergeGraph.cpp
===================================================================
--- trunk/src/operation/linemerge/LineMergeGraph.cpp	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/src/operation/linemerge/LineMergeGraph.cpp	2011-02-21 16:14:38 UTC (rev 3228)
@@ -4,7 +4,8 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.refractions.net
  *
- * Copyright (C) 2005 R-2006efractions Research Inc.
+ * Copyright (C) 2011 Sandro Santilli <strk at keybit.net>
+ * Copyright (C) 2005-2006 Refractions Research Inc.
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -14,7 +15,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/LineMergeGraph.java rev. 1.5 (JTS-1.10)
+ * Last port: operation/linemerge/LineMergeGraph.java r320 (JTS-1.12)
  *
  **********************************************************************/
 
@@ -25,6 +26,7 @@
 #include <geos/planargraph/Node.h>
 #include <geos/geom/CoordinateSequence.h>
 #include <geos/geom/LineString.h>
+#include <memory>
 
 #include <vector>
 
@@ -53,12 +55,18 @@
 	cerr<<"Adding LineString "<<lineString->toString()<<endl;
 #endif
 
-	CoordinateSequence *coordinates = 
-		CoordinateSequence::removeRepeatedPoints(lineString->getCoordinatesRO());
+	std::auto_ptr<CoordinateSequence> coordinates (
+		CoordinateSequence::removeRepeatedPoints(lineString->getCoordinatesRO())
+	);
 
-	const Coordinate& startCoordinate=coordinates->getAt(0);
-	const Coordinate& endCoordinate=coordinates->getAt(coordinates->getSize()-1);
+	std::size_t nCoords = coordinates->size(); // virtual call..
 
+	// don't add lines with all coordinates equal
+	if ( nCoords <= 1 ) return;
+
+	const Coordinate& startCoordinate = coordinates->getAt(0);
+	const Coordinate& endCoordinate = coordinates->getAt(nCoords-1);
+
 	planargraph::Node* startNode=getNode(startCoordinate);
 	planargraph::Node* endNode=getNode(endCoordinate);
 #if GEOS_DEBUG
@@ -72,7 +80,7 @@
 	newDirEdges.push_back(directedEdge0);
 
 	planargraph::DirectedEdge *directedEdge1=new LineMergeDirectedEdge(endNode,
-			startNode,coordinates->getAt(coordinates->getSize()-2),
+			startNode,coordinates->getAt(nCoords - 2),
 			false);
 	newDirEdges.push_back(directedEdge1);
 
@@ -92,7 +100,6 @@
 	cerr<<"  endNode: "<<*endNode<<endl;
 #endif
 
-	delete coordinates;
 }
 
 planargraph::Node *

Modified: trunk/src/operation/linemerge/LineMerger.cpp
===================================================================
--- trunk/src/operation/linemerge/LineMerger.cpp	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/src/operation/linemerge/LineMerger.cpp	2011-02-21 16:14:38 UTC (rev 3228)
@@ -14,7 +14,7 @@
  *
  **********************************************************************
  *
- * Last port: operation/linemerge/LineMerger.java rev. 1.7 (JTS-1.10)
+ * Last port: operation/linemerge/LineMerger.java r320 (JTS-1.11)
  *
  **********************************************************************/
 

Modified: trunk/tests/unit/Makefile.am
===================================================================
--- trunk/tests/unit/Makefile.am	2011-02-21 16:14:18 UTC (rev 3227)
+++ trunk/tests/unit/Makefile.am	2011-02-21 16:14:38 UTC (rev 3228)
@@ -74,6 +74,7 @@
 	operation/buffer/BufferOpTest.cpp \
 	operation/distance/DistanceOpTest.cpp \
 	operation/IsSimpleOpTest.cpp \
+	operation/linemerge/LineMergerTest.cpp \
 	operation/overlay/validate/FuzzyPointLocatorTest.cpp \
 	operation/overlay/validate/OffsetPointGeneratorTest.cpp \
 	operation/overlay/validate/OverlayResultValidatorTest.cpp \

Added: trunk/tests/unit/operation/linemerge/LineMergerTest.cpp
===================================================================
--- trunk/tests/unit/operation/linemerge/LineMergerTest.cpp	                        (rev 0)
+++ trunk/tests/unit/operation/linemerge/LineMergerTest.cpp	2011-02-21 16:14:38 UTC (rev 3228)
@@ -0,0 +1,242 @@
+// 
+// Test Suite for geos::operation::linemerge::LineMerger class.
+
+// tut
+#include <tut.hpp>
+// geos
+#include <geos/operation/linemerge/LineMerger.h>
+#include <geos/platform.h>
+#include <geos/geom/GeometryFactory.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/LineString.h>
+#include <geos/io/WKTReader.h>
+#include <geos/io/WKTWriter.h>
+#include <geos/util/IllegalArgumentException.h>
+// std
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace tut
+{
+  //
+  // Test Group
+  //
+
+  // Common data used by tests
+  struct test_linemerger_data
+  {
+    typedef geos::operation::linemerge::LineMerger LineMerger;
+    typedef std::vector<geos::geom::Geometry*> GeomVect;
+    typedef std::vector<geos::geom::LineString*> LineVect;
+
+    geos::geom::GeometryFactory gf;
+    geos::io::WKTReader wktreader;
+    geos::io::WKTWriter wktwriter;
+
+    typedef geos::geom::Geometry Geom;
+    typedef geos::geom::Geometry::AutoPtr GeomPtr;
+
+    GeomVect inpGeoms;
+    GeomVect expGeoms;
+    LineVect* mrgGeoms;
+
+    test_linemerger_data()
+      : gf(), wktreader(&gf), wktwriter(), mrgGeoms(0)
+    {
+      wktwriter.setTrim(true);
+    }
+
+    ~test_linemerger_data()
+    {
+      delAll(inpGeoms);
+      delAll(expGeoms);
+      if ( mrgGeoms ) {
+        delAll(*mrgGeoms);
+        delete mrgGeoms;
+      }
+    }
+
+    GeomPtr readWKT(const std::string& inputWKT)
+    {
+        return GeomPtr(wktreader.read(inputWKT));
+    }
+
+    void readWKT(const char* const* inputWKT, std::vector<Geom*>& geoms)
+    {
+      for (const char* const* ptr=inputWKT; *ptr; ++ptr) {
+        geoms.push_back(readWKT(*ptr).release());
+      }
+    }
+
+    void doTest(const char * const * inputWKT,
+                const char * const * expectedWKT,
+                bool compareDirections=true)
+    {
+      LineMerger lineMerger;
+
+      readWKT(inputWKT, inpGeoms);
+      readWKT(expectedWKT, expGeoms);
+
+      lineMerger.add(&inpGeoms);
+      mrgGeoms = lineMerger.getMergedLineStrings();
+      compare(expGeoms, *mrgGeoms, compareDirections);
+
+    }
+
+    template <class TargetContainer>
+    void delAll(TargetContainer& geoms)
+    {
+      for (typename TargetContainer::const_iterator i = geoms.begin(),
+           e = geoms.end(); i != e; ++i)
+      {
+        Geom* g = dynamic_cast<Geom*>(*i);
+        delete g;
+      }
+    }
+
+    template <class TargetContainer1, class TargetContainer2>
+    static void compare(TargetContainer1& expectedGeometries,
+                        TargetContainer2& actualGeometries,
+                        bool compareDirections)
+    {
+      ensure_equals(actualGeometries.size(), expectedGeometries.size());
+      for (typename TargetContainer1::const_iterator
+          i = expectedGeometries.begin(),
+          e = expectedGeometries.end(); i != e; ++i)
+      {
+        Geom* g = dynamic_cast<Geom*>(*i);
+        ensure( contains(actualGeometries, g, compareDirections) );
+      }
+    }
+
+    template <class TargetContainer>
+    static bool contains(TargetContainer& actualGeometries,
+                         const Geom* g, bool exact)
+    {
+      for (typename TargetContainer::const_iterator
+           i = actualGeometries.begin(),
+           e = actualGeometries.end(); i != e; ++i)
+      {
+        Geom* element = dynamic_cast<Geom*>(*i);
+        if (exact && element->equalsExact(g)) {
+          return true;
+        }
+        if (!exact && element->equals(g)) {
+          return true;
+        }
+      }
+
+      return false;
+    }
+ 
+
+
+  private:
+    // noncopyable
+    test_linemerger_data(test_linemerger_data const& other);
+    test_linemerger_data& operator=(test_linemerger_data const& rhs);
+  };
+
+  typedef test_group<test_linemerger_data> group;
+  typedef group::object object;
+
+  group test_linemerger_group("geos::operation::linemerge::LineMerger");
+
+  //
+  // Test Cases
+  //
+
+  template<> template<>
+  void object::test<1>()
+  {
+    const char* inpWKT[] = {
+      "LINESTRING (120 120, 180 140)", "LINESTRING (200 180, 180 140)",
+      "LINESTRING (200 180, 240 180)",
+      NULL };
+    const char* expWKT[] = {
+      "LINESTRING (120 120, 180 140, 200 180, 240 180)",
+      NULL };
+
+    doTest(inpWKT, expWKT);
+  }
+
+  template<> template<>
+  void object::test<2>()
+  {
+    const char* inpWKT[] = {
+      "LINESTRING (120 300, 80 340)",
+      "LINESTRING (120 300, 140 320, 160 320)",
+      "LINESTRING (40 320, 20 340, 0 320)",
+      "LINESTRING (0 320, 20 300, 40 320)",
+      "LINESTRING (40 320, 60 320, 80 340)",
+      "LINESTRING (160 320, 180 340, 200 320)",
+      "LINESTRING (200 320, 180 300, 160 320)",
+      NULL };
+    const char* expWKT[] = {
+      "LINESTRING (160 320, 180 340, 200 320, 180 300, 160 320)",
+      "LINESTRING (40 320, 20 340, 0 320, 20 300, 40 320)",
+      "LINESTRING (40 320, 60 320, 80 340, 120 300, 140 320, 160 320)",
+      NULL };
+
+    doTest(inpWKT, expWKT);
+  }
+
+  template<> template<>
+  void object::test<3>()
+  {
+    const char* inpWKT[] = {
+      "LINESTRING (0 0, 100 100)", "LINESTRING (0 100, 100 0)",
+      NULL };
+    const char* expWKT[] = {
+      "LINESTRING (0 0, 100 100)", "LINESTRING (0 100, 100 0)",
+      NULL };
+
+    doTest(inpWKT, expWKT);
+  }
+
+  template<> template<>
+  void object::test<4>()
+  {
+    // I don't see how the following test could succeed (even in JTS)
+    // so it is disabled
+    return; 
+
+    const char* inpWKT[] = {
+      "LINESTRING EMPTY",
+      NULL };
+    const char* expWKT[] = {
+      "LINESTRING EMPTY",
+      NULL };
+
+    doTest(inpWKT, expWKT);
+  }
+
+  // Don't blame me for this, I'm just copying JTS tests :P
+  template<> template<>
+  void object::test<5>()
+  {
+    const char* inpWKT[] = {
+      NULL };
+    const char* expWKT[] = {
+      NULL };
+
+    doTest(inpWKT, expWKT);
+  }
+
+  // testSingleUniquePoint()
+  template<> template<>
+  void object::test<6>()
+  {
+    const char* inpWKT[] = {
+      "LINESTRING (10642 31441, 10642 31441)",
+      NULL };
+    const char* expWKT[] = {
+      NULL };
+
+    doTest(inpWKT, expWKT);
+  }
+
+
+} // namespace tut
+



More information about the geos-commits mailing list