[geos-commits] r3125 - in trunk: . include/geos/operation/sharedpaths src/operation/sharedpaths

svn_geos at osgeo.org svn_geos at osgeo.org
Mon Nov 29 04:33:24 EST 2010


Author: strk
Date: 2010-11-29 01:33:24 -0800 (Mon, 29 Nov 2010)
New Revision: 3125

Modified:
   trunk/.vimrc
   trunk/include/geos/operation/sharedpaths/SharedPathsOp.h
   trunk/src/operation/sharedpaths/SharedPathsOp.cpp
Log:
Complete implementation of SharedPathsOp

Modified: trunk/.vimrc
===================================================================
--- trunk/.vimrc	2010-11-29 09:33:12 UTC (rev 3124)
+++ trunk/.vimrc	2010-11-29 09:33:24 UTC (rev 3125)
@@ -1,6 +1,6 @@
 " This file is for reference for when
 " there _is_ a standard style (none yet)
 
-"set tabstop=3
-"set shiftwidth=3
-"set expandtab
+set tabstop=2
+set shiftwidth=2
+set expandtab

Modified: trunk/include/geos/operation/sharedpaths/SharedPathsOp.h
===================================================================
--- trunk/include/geos/operation/sharedpaths/SharedPathsOp.h	2010-11-29 09:33:12 UTC (rev 3124)
+++ trunk/include/geos/operation/sharedpaths/SharedPathsOp.h	2010-11-29 09:33:24 UTC (rev 3125)
@@ -26,10 +26,11 @@
 
 // Forward declarations
 namespace geos {
-	namespace geom {
-		//class LineString;
-		class Geometry;
-	}
+  namespace geom {
+    class LineString;
+    class Geometry;
+    class GeometryFactory;
+  }
 }
 
 
@@ -48,35 +49,97 @@
 {
 public:
 
-	/// Find paths shared between two linear geometries
-	//
-	/// @param g1
-	///	First geometry. Must be linear.
-	///
-	/// @param g2
-	///	Second geometry. Must be linear.
-	///
-	/// @param tol
-	///	Tolerance by which very close paths are considered shared.
-	///	TODO: specify more about the semantic, check SnapOp 
-	///
-	/// @param sameDir
-	///	Shared edges having the same direction are pushed
-	///     onto this vector. They'll be of type LineString.
-	///	Ownership of the edges is tranferred.
-	///
-	/// @param oppositeDir
-	///	Shared edges having the opposite direction are pushed
-	///     onto this vector. They'll be of type LineString.
-	///	Ownership of the edges is tranferred.
-	///
-	static void getSharedPaths(
-		const geom::Geometry& g1,
-		const geom::Geometry& g2,
-		double tol,
-		std::vector<geom::Geometry*>& sameDirection,
-		std::vector<geom::Geometry*>& oppositeDirection);
+  /// Find paths shared between two linear geometries
+  //
+  /// @param g1
+  ///   First geometry. Must be linear.
+  ///
+  /// @param g2
+  ///   Second geometry. Must be linear.
+  ///
+  /// @param tol
+  ///   Tolerance by which very close paths are considered shared.
+  ///   TODO: specify more about the semantic, check SnapOp 
+  ///
+  /// @param sameDir
+  ///   Shared edges having the same direction are pushed
+  ///   onto this vector. They'll be of type LineString.
+  ///   Ownership of the edges is tranferred.
+  ///
+  /// @param oppositeDir
+  ///   Shared edges having the opposite direction are pushed
+  ///   onto this vector. They'll be of type geom::LineString.
+  ///   Ownership of the edges is tranferred.
+  ///
+  static void sharedPathsOp(const geom::Geometry& g1,
+                            const geom::Geometry& g2,
+                            double tol,
+                            std::vector<geom::Geometry*>& sameDirection,
+                            std::vector<geom::Geometry*>& oppositeDirection);
 
+  /// Constructor
+  //
+  /// @param g1
+  ///   First geometry. Must be linear.
+  ///
+  /// @param g2
+  ///   Second geometry. Must be linear.
+  ///
+  SharedPathsOp(const geom::Geometry& g1, const geom::Geometry& g2);
+
+  /// Get shared paths gith a given tolerance 
+  //
+  /// @param tol
+  ///   Tolerance by which very close paths are considered shared.
+  ///   TODO: specify more about the semantic, check SnapOp 
+  ///
+  /// @param sameDir
+  ///   Shared edges having the same direction are pushed
+  ///   onto this vector. They'll be of type geom::LineString.
+  ///   Ownership of the edges is tranferred.
+  ///
+  /// @param oppositeDir
+  ///   Shared edges having the opposite direction are pushed
+  ///   onto this vector. They'll be of type geom::LineString.
+  ///   Ownership of the edges is tranferred.
+  ///
+  void getSharedPaths(double tolerance,
+                      std::vector<geom::Geometry*>& sameDirection,
+                      std::vector<geom::Geometry*>& oppositeDirection);
+
+private:
+
+  /// LineString vector (list of edges)
+  typedef std::vector<geom::LineString*> EdgeList;
+
+  /// Delete all edges in the list
+  static void clearEdges(EdgeList& from);
+
+  /// Get all the linear intersections
+  //
+  /// Ownership of linestring pushed to the given container
+  /// is transferred to caller. See clearEdges for a deep
+  /// release if you need one.
+  ///
+  void findLinearIntersections(EdgeList& to);
+
+  /// Check if the given edge goes forward or backward on the given line.
+  //
+  /// PRECONDITION: It is assumed the edge fully lays on the geometry
+  ///
+  bool isForward(const geom::LineString& edge,
+                 const geom::Geometry& geom);
+
+  // Check if the given edge goes in the same direction over
+  // the two geometries.
+  bool isSameDirection(const geom::LineString& edge) {
+    return (isForward(edge, _g1) == isForward(edge, _g2));
+  }
+
+  const geom::Geometry& _g1;
+  const geom::Geometry& _g2;
+  const geom::GeometryFactory& _gf;
+
 };
 
 } // namespace geos.operation.sharedpaths

Modified: trunk/src/operation/sharedpaths/SharedPathsOp.cpp
===================================================================
--- trunk/src/operation/sharedpaths/SharedPathsOp.cpp	2010-11-29 09:33:12 UTC (rev 3124)
+++ trunk/src/operation/sharedpaths/SharedPathsOp.cpp	2010-11-29 09:33:24 UTC (rev 3125)
@@ -18,24 +18,118 @@
  **********************************************************************/
 
 #include <geos/operation/sharedpaths/SharedPathsOp.h>
+#include <geos/geom/Geometry.h>
+#include <geos/geom/LineString.h>
+#include <geos/linearref/LinearLocation.h>
+#include <geos/linearref/LocationIndexOfPoint.h>
+#include <geos/operation/overlay/OverlayOp.h>
 #include <geos/util/IllegalArgumentException.h>
+#include <geos/geom/util/LinearComponentExtracter.h>
 
+using namespace geos::geom;
+
 namespace geos {
 namespace operation { // geos.operation
 namespace sharedpaths { // geos.operation.sharedpaths
 
-using namespace geos::geom;
-
 /* public static */
 void
-SharedPathsOp::getSharedPaths(const Geometry& g1, const Geometry& g2,
-		double tol,
-		std::vector<Geometry*>& sameDirection,
-		std::vector<Geometry*>& oppositeDirection)
+SharedPathsOp::sharedPathsOp(const Geometry& g1, const Geometry& g2,
+    double tol,
+    std::vector<Geometry*>& sameDirection,
+    std::vector<Geometry*>& oppositeDirection)
 {
-	throw geos::util::IllegalArgumentException("Not implemented yet");
+  SharedPathsOp sp(g1, g2);
+  sp.getSharedPaths(tol, sameDirection, oppositeDirection);
 }
 
+/* public */
+SharedPathsOp::SharedPathsOp(
+    const geom::Geometry& g1, const geom::Geometry& g2)
+  :
+  _g1(g1),
+  _g2(g2),
+  _gf(*g1.getFactory())
+{
+}
+
+/* public */
+void
+SharedPathsOp::getSharedPaths(double tol,
+    std::vector<Geometry*>& sameDirection,
+    std::vector<Geometry*>& oppositeDirection)
+{
+  EdgeList paths;
+  findLinearIntersections(paths);
+  for (size_t i=0, n=paths.size(); i<n; ++i)
+  {
+    LineString* path = paths[i];
+    if ( isSameDirection(*path) ) sameDirection.push_back(path);
+    else oppositeDirection.push_back(path);
+  }
+}
+
+/* static private */
+void
+SharedPathsOp::clearEdges(EdgeList& edges)
+{
+  for (EdgeList::const_iterator
+        i=edges.begin(), e=edges.end();
+        i!=e; ++i)
+  {
+    delete *i;
+  }
+  edges.clear();
+}
+
+/* private */
+void
+SharedPathsOp::findLinearIntersections(EdgeList& to)
+{
+  using geos::operation::overlay::OverlayOp;
+
+  // TODO: optionally use the tolerance,
+  //       snapping _g2 over _g1 ?
+
+  std::auto_ptr<Geometry> full ( OverlayOp::overlayOp(
+    &_g1, &_g2, OverlayOp::opINTERSECTION) );
+
+  for (size_t i=0, n=full->getNumGeometries(); i<n; ++i)
+  {
+    const Geometry* sub = full->getGeometryN(i);
+    const LineString* path = dynamic_cast<const LineString*>(sub);
+    if ( path ) { 
+      to.push_back(_gf.createLineString(*path).release());
+    }
+  }
+}
+
+/* private */
+bool
+SharedPathsOp::isForward(const geom::LineString& edge,
+                       const geom::Geometry& geom)
+{
+  using namespace geos::linearref;
+
+  /*
+     ALGO:
+      1. find first point of edge on geom (linearref)
+      2. find second point of edge on geom (linearref)
+      3. if first < second, we're forward
+
+     PRECONDITIONS:
+      1. edge has at least 2 points
+      2. edge first two points are not equal
+      3. geom is simple
+   */
+
+  const Coordinate& pt1 = edge.getCoordinateN(0);
+  const Coordinate& pt2 = edge.getCoordinateN(1);
+  LinearLocation l1 = LocationIndexOfPoint::indexOf(&geom, pt1);
+  LinearLocation l2 = LocationIndexOfPoint::indexOf(&geom, pt2);
+  return l1.compareTo(l2) < 0;
+}
+
 } // namespace geos.operation.sharedpaths
 } // namespace geos::operation
 } // namespace geos



More information about the geos-commits mailing list