[geos-commits] r2459 - in trunk/source:
headers/geos/operation/overlay/snap operation/overlay/snap
svn_geos at osgeo.org
svn_geos at osgeo.org
Mon May 4 15:52:04 EDT 2009
Author: strk
Date: 2009-05-04 15:51:32 -0400 (Mon, 04 May 2009)
New Revision: 2459
Modified:
trunk/source/headers/geos/operation/overlay/snap/LineStringSnapper.h
trunk/source/operation/overlay/snap/LineStringSnapper.cpp
Log:
Extend to accept a vector of const Coordinate pointers for snap pointers, fix typo making it clone snap points rather than source points on snapping...
Modified: trunk/source/headers/geos/operation/overlay/snap/LineStringSnapper.h
===================================================================
--- trunk/source/headers/geos/operation/overlay/snap/LineStringSnapper.h 2009-05-02 11:01:07 UTC (rev 2458)
+++ trunk/source/headers/geos/operation/overlay/snap/LineStringSnapper.h 2009-05-04 19:51:32 UTC (rev 2459)
@@ -23,12 +23,13 @@
#include <geos/geom/LineSegment.h> // for composition
#include <geos/geom/LineString.h> // for inlined ctor
-//#include <vector>
+#include <vector>
#include <memory> // for auto_ptr
// Forward declarations
namespace geos {
namespace geom {
+ class Coordinate;
class CoordinateSequence;
}
}
@@ -93,6 +94,9 @@
std::auto_ptr<geom::CoordinateSequence> snapTo(
const geom::CoordinateSequence& snapPts);
+ std::auto_ptr<geom::CoordinateSequence> snapTo(
+ const std::vector<const geom::Coordinate*>& snapPts);
+
private:
/**
@@ -104,12 +108,19 @@
void snapVertices(geom::CoordinateSequence& srcCoords,
const geom::CoordinateSequence& snapPts);
+ void snapVertices(geom::CoordinateSequence& srcCoords,
+ const std::vector<const geom::Coordinate*>& snapPts);
+
// return pointer into snapPts memory, or null
const geom::Coordinate*
findSnapForVertex(const geom::Coordinate& pt,
const geom::CoordinateSequence& snapPts);
+ const geom::Coordinate*
+ findSnapForVertex(const geom::Coordinate& pt,
+ const std::vector<const geom::Coordinate*>& snapPts);
+
/**
* Snap segments of the source to nearby snap vertices.
* Source segments are "cracked" at a snap vertex, and further
@@ -125,6 +136,9 @@
void snapSegments(geom::CoordinateSequence& srcCoords,
const geom::CoordinateSequence& snapPts);
+ void snapSegments(geom::CoordinateSequence& srcCoords,
+ const std::vector<const geom::Coordinate*>& snapPts);
+
/** \brief
* Finds a src segment which snaps to (is close to)
* the given snap point.
@@ -142,7 +156,6 @@
int findSegmentIndexToSnap(const geom::Coordinate& snapPt,
const geom::CoordinateSequence& srcCoords);
-
double snapTolerance;
Modified: trunk/source/operation/overlay/snap/LineStringSnapper.cpp
===================================================================
--- trunk/source/operation/overlay/snap/LineStringSnapper.cpp 2009-05-02 11:01:07 UTC (rev 2458)
+++ trunk/source/operation/overlay/snap/LineStringSnapper.cpp 2009-05-04 19:51:32 UTC (rev 2459)
@@ -48,6 +48,18 @@
return coordList;
}
+/*public*/
+auto_ptr<CoordinateSequence>
+LineStringSnapper::snapTo(const vector<const Coordinate*>& snapPts)
+{
+ auto_ptr<CoordinateSequence> coordList(srcPts.clone());
+
+ snapVertices(*coordList, snapPts);
+ snapSegments(*coordList, snapPts);
+
+ return coordList;
+}
+
/*private*/
void
LineStringSnapper::snapVertices(geom::CoordinateSequence& srcCoords,
@@ -55,7 +67,7 @@
{
// try snapping vertices
// assume src list has a closing point (is a ring)
- for (int i = 0; i < srcCoords.size() - 1; i++) {
+ for (size_t i = 0; i < srcCoords.size() - 1; i++) {
const Coordinate& srcPt = srcCoords.getAt(i);
const Coordinate* snapVert = findSnapForVertex(srcPt, snapPts);
if (snapVert != NULL) {
@@ -69,11 +81,31 @@
}
/*private*/
+void
+LineStringSnapper::snapVertices(geom::CoordinateSequence& srcCoords,
+ const vector<const Coordinate*>& snapPts)
+{
+ // try snapping vertices
+ // assume src list has a closing point (is a ring)
+ for (size_t i = 0; i < srcCoords.size() - 1; i++) {
+ const Coordinate& srcPt = srcCoords.getAt(i);
+ const Coordinate* snapVert = findSnapForVertex(srcPt, snapPts);
+ if (snapVert != NULL) {
+ // update src with snap pt
+ srcCoords.setAt(*snapVert, i);
+ // keep final closing point in synch (rings only)
+ if (i == 0 && isClosed)
+ srcCoords.setAt(*snapVert, srcCoords.size() - 1);
+ }
+ }
+}
+
+/*private*/
const geom::Coordinate*
LineStringSnapper::findSnapForVertex(const geom::Coordinate& pt,
const geom::CoordinateSequence& snapPts)
{
- for (int i = 0; i < snapPts.size(); i++) {
+ for (size_t i = 0; i < snapPts.size(); i++) {
// if point is already equal to a src pt, don't snap
if (pt.equals2D(snapPts[i]))
return 0;
@@ -84,6 +116,21 @@
}
/*private*/
+const geom::Coordinate*
+LineStringSnapper::findSnapForVertex(const geom::Coordinate& pt,
+ const vector<const Coordinate*>& snapPts)
+{
+ for (size_t i = 0; i < snapPts.size(); i++) {
+ // if point is already equal to a src pt, don't snap
+ if (pt.equals2D(*snapPts[i]))
+ return 0;
+ if (pt.distance(*snapPts[i]) < snapTolerance)
+ return snapPts[i];
+ }
+ return 0;
+}
+
+/*private*/
void
LineStringSnapper::snapSegments(geom::CoordinateSequence& srcCoords,
const geom::CoordinateSequence& snapPts)
@@ -111,13 +158,40 @@
}
/*private*/
+void
+LineStringSnapper::snapSegments(geom::CoordinateSequence& srcCoords,
+ const vector<const Coordinate*>& snapPts)
+{
+ int distinctPtCount = snapPts.size();
+
+ // check for duplicate snap pts.
+ // Need to do this better - need to check all points for dups (using a Set?)
+ if (snapPts[0]->equals2D(*snapPts[snapPts.size() - 1]))
+ distinctPtCount = snapPts.size() - 1;
+
+ for (int i = 0; i < distinctPtCount; i++) {
+ const Coordinate& snapPt = *(snapPts[i]);
+ int index = findSegmentIndexToSnap(snapPt, srcCoords);
+ /**
+ * If a segment to snap to was found, "crack" it at the snap pt.
+ * The new pt is inserted immediately into the src segment list,
+ * so that subsequent snapping will take place on the latest segments.
+ * Duplicate points are not added.
+ */
+ if (index >= 0) {
+ srcCoords.add(index + 1, snapPt, false);
+ }
+ }
+}
+
+/*private*/
int
LineStringSnapper::findSegmentIndexToSnap(const geom::Coordinate& snapPt,
const geom::CoordinateSequence& srcCoords)
{
double minDist = numeric_limits<double>::max();
int snapIndex = -1;
- for (int i = 0; i < srcCoords.size() - 1; i++) {
+ for (size_t i = 0; i < srcCoords.size() - 1; i++) {
seg.p0 = srcCoords.getAt(i);
seg.p1 = srcCoords.getAt(i + 1);
More information about the geos-commits
mailing list