diff --git a/include/geos/noding/snapround/SnapRoundingIntersectionAdder.h b/include/geos/noding/snapround/SnapRoundingIntersectionAdder.h index c41497f749..067d519d3c 100644 --- a/include/geos/noding/snapround/SnapRoundingIntersectionAdder.h +++ b/include/geos/noding/snapround/SnapRoundingIntersectionAdder.h @@ -65,11 +65,6 @@ namespace snapround { // geos::noding::snapround class GEOS_DLL SnapRoundingIntersectionAdder: public SegmentIntersector { // implements SegmentIntersector private: - /** - * The division factor used to determine - * nearness distance tolerance for interior intersection detection. - */ - static constexpr int NEARNESS_FACTOR = 100; algorithm::LineIntersector li; std::unique_ptr> intersections; @@ -95,7 +90,11 @@ class GEOS_DLL SnapRoundingIntersectionAdder: public SegmentIntersector { // imp public: - SnapRoundingIntersectionAdder(const geom::PrecisionModel* newPm); + SnapRoundingIntersectionAdder(double p_nearnessTol) + : SegmentIntersector() + , intersections(new std::vector) + , nearnessTol(p_nearnessTol) + {} std::unique_ptr> getIntersections() { return std::move(intersections); }; diff --git a/include/geos/noding/snapround/SnapRoundingNoder.h b/include/geos/noding/snapround/SnapRoundingNoder.h index 0b614e9d97..369b08084d 100644 --- a/include/geos/noding/snapround/SnapRoundingNoder.h +++ b/include/geos/noding/snapround/SnapRoundingNoder.h @@ -71,6 +71,11 @@ namespace snapround { // geos::noding::snapround class GEOS_DLL SnapRoundingNoder : public Noder { private: + /** + * The division factor used to determine + * nearness distance tolerance for interior intersection detection. + */ + static constexpr int INTERSECTION_NEARNESS_FACTOR = 100; // Members const geom::PrecisionModel* pm; diff --git a/src/noding/snapround/SnapRoundingIntersectionAdder.cpp b/src/noding/snapround/SnapRoundingIntersectionAdder.cpp index 5e536a0782..de90f99fe6 100644 --- a/src/noding/snapround/SnapRoundingIntersectionAdder.cpp +++ b/src/noding/snapround/SnapRoundingIntersectionAdder.cpp @@ -38,15 +38,6 @@ namespace noding { // geos.noding namespace snapround { // geos.noding.snapround -SnapRoundingIntersectionAdder::SnapRoundingIntersectionAdder(const geom::PrecisionModel* newPm) - : SegmentIntersector() - , intersections(new std::vector) - // , pm(newPm) -{ - double snapGridSize = 1.0 / newPm->getScale(); - nearnessTol = snapGridSize / NEARNESS_FACTOR; -} - /*public*/ void SnapRoundingIntersectionAdder::processIntersections( diff --git a/src/noding/snapround/SnapRoundingNoder.cpp b/src/noding/snapround/SnapRoundingNoder.cpp index 9e70c64395..cfb76f97a6 100644 --- a/src/noding/snapround/SnapRoundingNoder.cpp +++ b/src/noding/snapround/SnapRoundingNoder.cpp @@ -77,9 +77,9 @@ SnapRoundingNoder::snapRound(std::vector& inputSegStrings, std:: void SnapRoundingNoder::addIntersectionPixels(std::vector& segStrings) { - SnapRoundingIntersectionAdder intAdder(pm); - MCIndexNoder noder; - noder.setSegmentIntersector(&intAdder); + double tolerance = 1.0 / pm->getScale() / INTERSECTION_NEARNESS_FACTOR; + SnapRoundingIntersectionAdder intAdder(tolerance); + MCIndexNoder noder(&intAdder, tolerance); noder.computeNodes(&segStrings); std::unique_ptr> intPts = intAdder.getIntersections(); pixelIndex.addNodes(*intPts); diff --git a/tests/unit/capi/GEOSGeom_setPrecisionTest.cpp b/tests/unit/capi/GEOSGeom_setPrecisionTest.cpp index 4864d02a05..4cfa3f7475 100644 --- a/tests/unit/capi/GEOSGeom_setPrecisionTest.cpp +++ b/tests/unit/capi/GEOSGeom_setPrecisionTest.cpp @@ -169,5 +169,27 @@ void object::test<10> () ensure_geometry_equals(geom2_, "LINEARRING EMPTY"); } +// Reduce polygon precision, corner case / Trac #1127 +template<> +template<> +void object::test<11> () +{ + // POLYGON(( + // 100 49.5, (1) + // 100 300, (2) + // 320 60, (3) + // 340 49.9, (4) + // 360 50.1, (5) + // 380 49.5, (6) + // 100 49.5 (7) + // )) + // * points 4 and 5 are close (less than 100.0/100) to segment (6, 7); + // * Y coordinates of points 4 and 5 are rounded to different values, 0 and 100 respectively; + // * point 4 belongs to monotone chain of size > 1 -- segments (2, 3) and (3, 4) + geom1_ = fromWKT("POLYGON((100 49.5, 100 300, 320 60, 340 49.9, 360 50.1, 380 49.5, 100 49.5))"); + geom2_ = GEOSGeom_setPrecision(geom1_, 100.0, 0); + ensure(geom2_ != nullptr); // just check that valid geometry is constructed +} + } // namespace tut