Skip to content

Commit

Permalink
Complete implementation of SharedPathsOp
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/geos/trunk@3125 5242fede-7e19-0410-aef8-94bd7d2200fb
  • Loading branch information
Sandro Santilli committed Nov 29, 2010
1 parent 80c5296 commit b8b7d4e
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 42 deletions.
6 changes: 3 additions & 3 deletions .vimrc
Original file line number Diff line number Diff line change
@@ -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
127 changes: 95 additions & 32 deletions include/geos/operation/sharedpaths/SharedPathsOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@

// Forward declarations
namespace geos {
namespace geom {
//class LineString;
class Geometry;
}
namespace geom {
class LineString;
class Geometry;
class GeometryFactory;
}
}


Expand All @@ -48,34 +49,96 @@ class GEOS_DLL SharedPathsOp
{
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;

};

Expand Down
108 changes: 101 additions & 7 deletions src/operation/sharedpaths/SharedPathsOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,116 @@
**********************************************************************/

#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)
{
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)
{
throw geos::util::IllegalArgumentException("Not implemented yet");
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
Expand Down

0 comments on commit b8b7d4e

Please sign in to comment.