Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
- BufferOp returns POLYGON EMPTY when fed Inf/Nan coords (GH-1332)
- Return Inf when calculating distance to an empty geometry (GH-1345, Even Rouault)


- Fixes/Improvements:
- GEOSSnap: Recursively snap segments till nothing moves (#760, Sandro Santilli)
- Buffer of Linestring includes spurious hole (GH-1217, Moritz Kirmse)
- Preserve M values in GEOSInterpolate (GH-1390, Dan Baston)
- Preserve M values in GEOSLineMerge (GH-1364, Dan Baston)
Expand Down
10 changes: 10 additions & 0 deletions src/operation/overlay/snap/LineStringSnapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ LineStringSnapper::snapSegments(geom::CoordinateList& srcCoords,
std::cerr << "Snapping segments of: " << srcCoords << std::endl;
#endif

// Recursively snap segments till nothing moves
// See https://trac.osgeo.org/geos/ticket/760
bool moved = false;
do
{
moved = false;
for(Coordinate::ConstVect::const_iterator
it = snapPts.begin(), end = snapPts.end();
it != end;
Expand All @@ -261,6 +267,8 @@ LineStringSnapper::snapSegments(geom::CoordinateList& srcCoords,
continue;
}

moved = true;

/* Check if the snap point falls outside of the segment */
// If the snap point is outside, this means that an endpoint
// was not snap where it should have been
Expand Down Expand Up @@ -376,6 +384,8 @@ LineStringSnapper::snapSegments(geom::CoordinateList& srcCoords,
srcCoords.insert(segpos, snapPt);
}
}
// while things keep moving
} while (moved);

#if GEOS_DEBUG
std::cerr << " After segment snapping, srcCoors are: " << srcCoords << std::endl;
Expand Down
42 changes: 42 additions & 0 deletions tests/unit/operation/overlay/snap/LineStringSnapperTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,4 +355,46 @@ void object::test<9>
ensure_equals(ret->operator[](4), snp_a); // 0 0
}

// Recursive snap of segments
// See https://trac.osgeo.org/geos/ticket/760
template<>
template<>
void object::test<10>()
{
using geos::geom::Coordinate;
using geos::operation::overlay::snap::LineStringSnapper;

typedef std::auto_ptr<Coordinate::Vect> CoordsVectAptr;


// Source: (0 0,0 20)
Coordinate src_a(0, 0);
Coordinate src_b(0, 20);
Coordinate::Vect srcCoords;
srcCoords.push_back(src_a);
srcCoords.push_back(src_b);

// Snap: (1.5 17,1 18,0.5 19)
Coordinate snp_a(1.5, 17);
Coordinate snp_b(1, 18);
Coordinate snp_c(0.5, 19);
Coordinate::ConstVect snpCoords;
snpCoords.push_back( &snp_a );
snpCoords.push_back( &snp_b );
snpCoords.push_back( &snp_c );

// Snap with tolerance of 0.8
// (both first and second point could be snapped)
LineStringSnapper snapper(srcCoords, 0.8);

// Expect: (0 0,1.5 17,1 18,0.5 19,0 20)
CoordsVectAptr ret(snapper.snapTo(snpCoords));
ensure_equals(ret->size(), 5u);
ensure_equals(ret->operator[](0), src_a); // 0 0
ensure_equals(ret->operator[](1), snp_a); // 1.5 17
ensure_equals(ret->operator[](2), snp_b); // 1 18
ensure_equals(ret->operator[](3), snp_c); // 0.5 19
ensure_equals(ret->operator[](4), src_b); // 0 20
}

} // namespace tut
Loading