[geos-commits] r2337 - in trunk/source: geomgraph headers/geos/geomgraph headers/geos/noding

svn_geos at osgeo.org svn_geos at osgeo.org
Wed Apr 8 12:52:28 EDT 2009


Author: strk
Date: 2009-04-08 12:52:28 -0400 (Wed, 08 Apr 2009)
New Revision: 2337

Modified:
   trunk/source/geomgraph/EdgeList.cpp
   trunk/source/headers/geos/geomgraph/EdgeList.h
   trunk/source/headers/geos/noding/OrientedCoordinateArray.h
Log:
Improve duplicate edge detection performance (JTS-1.9 sync) - fme.xml runs 3 times as fast now.


Modified: trunk/source/geomgraph/EdgeList.cpp
===================================================================
--- trunk/source/geomgraph/EdgeList.cpp	2009-04-08 16:51:48 UTC (rev 2336)
+++ trunk/source/geomgraph/EdgeList.cpp	2009-04-08 16:52:28 UTC (rev 2337)
@@ -11,6 +11,10 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: geomgraph/EdgeList.java rev. 1.4 (JTS-1.9)
+ *
  **********************************************************************/
 
 #include <string>
@@ -19,6 +23,7 @@
 
 #include <geos/geomgraph/Edge.h>
 #include <geos/geomgraph/EdgeList.h>
+#include <geos/noding/OrientedCoordinateArray.h> 
 #include <geos/profiler.h>
 
 #ifndef GEOS_DEBUG
@@ -26,7 +31,7 @@
 #endif
 
 using namespace std;
-using namespace geos::index::quadtree;
+using namespace geos::noding;
 
 namespace geos {
 namespace geomgraph { // geos.geomgraph
@@ -40,7 +45,8 @@
 EdgeList::add(Edge *e)
 {
 	edges.push_back(e);
-	index->insert(e->getEnvelope(), e);
+	OrientedCoordinateArray* oca = new OrientedCoordinateArray(*(e->getCoordinates()));
+	ocaMap[oca] = e;
 }
 
 void
@@ -52,7 +58,6 @@
 	}
 }
 
-// <FIX> fast lookup for edges
 /**
  * If there is an edge equal to e already in the list, return it.
  * Otherwise return null.
@@ -66,26 +71,17 @@
 	static Profile *prof = profiler->get("EdgeList::findEqualEdge(Edge *e)");
 	prof->start();
 #endif
-	vector<void*> testEdges;
-	index->query(e->getEnvelope(), testEdges);
+
+	OrientedCoordinateArray oca(*(e->getCoordinates()));
+
+	EdgeMap::iterator it = ocaMap.find(&oca);
+
 #if PROFILE
 	prof->stop();
 #endif
 
-#if GEOS_DEBUG
-	cerr << "EdgeList::findEqualEdge found " << testEdges.size() <<
-			" overlapping edges" << endl;
-#endif
-
-	for (std::size_t i=0, s=testEdges.size(); i<s; ++i)
-	{
-		Edge* testEdge=static_cast<Edge*>(testEdges[i]);
-		if (testEdge->equals(e))
-		{
-			return testEdge;
-		}
-	}
-	return NULL;
+	if ( it != ocaMap.end() ) return it->second;
+	return 0;
 }
 
 Edge*
@@ -149,6 +145,14 @@
 	return os;
 }
 
+EdgeList::~EdgeList()
+{
+	for (EdgeMap::iterator i=ocaMap.begin(), e=ocaMap.end(); i!=e; ++i)
+	{
+		delete i->first; // OrientedCoordinateArray
+	}
+}
+
 } // namespace geos.geomgraph
 } // namespace geos
 

Modified: trunk/source/headers/geos/geomgraph/EdgeList.h
===================================================================
--- trunk/source/headers/geos/geomgraph/EdgeList.h	2009-04-08 16:51:48 UTC (rev 2336)
+++ trunk/source/headers/geos/geomgraph/EdgeList.h	2009-04-08 16:52:28 UTC (rev 2337)
@@ -12,6 +12,10 @@
  * by the Free Software Foundation. 
  * See the COPYING file for more information.
  *
+ **********************************************************************
+ *
+ * Last port: geomgraph/EdgeList.java rev. 1.4 (JTS-1.9)
+ *
  **********************************************************************/
 
 
@@ -19,10 +23,11 @@
 #define GEOS_GEOMGRAPH_EDGELIST_H
 
 #include <vector>
+#include <map>
 #include <string>
 #include <iostream>
 
-#include <geos/indexQuadtree.h> // for inlined ctor
+#include <geos/noding/OrientedCoordinateArray.h> // for map comparator
 
 #include <geos/inline.h>
 
@@ -39,22 +44,37 @@
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 
+/** 
+ * A EdgeList is a list of Edges. 
+ *
+ * It supports locating edges
+ * that are pointwise equals to a target edge.
+ */
 class EdgeList {
 
 private:
 
 	std::vector<Edge*> edges;
 
+	struct OcaCmp {
+		bool operator()(
+			const noding::OrientedCoordinateArray *oca1,
+			const noding::OrientedCoordinateArray *oca2) const
+		{
+			return oca1->compareTo(*oca2)<0;
+		}
+	};
+
 	/**
 	 * An index of the edges, for fast lookup.
-	 *
-	 * a Quadtree is used, because this index needs to be dynamic
-	 * (e.g. allow insertions after queries).
-	 * An alternative would be to use an ordered set based on the values
-	 * of the edge coordinates
-	 *
+	 * 
+	 * OrientedCoordinateArray objects are owned by us.
+	 * TODO: optimize by dropping the OrientedCoordinateArray
+	 *       construction as a whole, and use CoordinateSequence
+	 *       directly instead..
 	 */
-	geos::index::SpatialIndex* index;
+	typedef std::map<noding::OrientedCoordinateArray*, Edge*, OcaCmp> EdgeMap;
+	EdgeMap ocaMap;
 
 public:
 	friend std::ostream& operator<< (std::ostream& os, const EdgeList& el);
@@ -62,10 +82,10 @@
 	EdgeList()
 		:
 		edges(),
-		index(new geos::index::quadtree::Quadtree())
+		ocaMap()
 	{}
 
-	virtual ~EdgeList() { delete index; }
+	virtual ~EdgeList();
 
 	/**
 	 * Insert an edge unless it is already in the list

Modified: trunk/source/headers/geos/noding/OrientedCoordinateArray.h
===================================================================
--- trunk/source/headers/geos/noding/OrientedCoordinateArray.h	2009-04-08 16:51:48 UTC (rev 2336)
+++ trunk/source/headers/geos/noding/OrientedCoordinateArray.h	2009-04-08 16:52:28 UTC (rev 2337)
@@ -70,7 +70,7 @@
 	 * In JTS, this is used automatically by ordered lists.
 	 * In C++, operator< would be used instead....
 	 */
-	int compareTo(const OrientedCoordinateArray& o1);
+	int compareTo(const OrientedCoordinateArray& o1) const;
 
 
 private:



More information about the geos-commits mailing list