[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