[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