[geos-commits] [SCM] GEOS branch 3.15 updated. 19ff2e15e6be07e853db3c4ec5c3229ed10abf42
git at osgeo.org
git at osgeo.org
Wed Sep 9 08:03:02 PDT 2026
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".
The branch, 3.15 has been updated
via 19ff2e15e6be07e853db3c4ec5c3229ed10abf42 (commit)
from 177dff96a9bf60595cd40a3051630574d03acc49 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 19ff2e15e6be07e853db3c4ec5c3229ed10abf42
Author: Daniel Baston <dbaston at gmail.com>
Date: Wed Sep 9 09:39:33 2026 -0400
NodableArcString: Skip split points having the same angle as an endpoint (#1513)
diff --git a/NEWS.md b/NEWS.md
index 5416e955d..831d214db 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -2,7 +2,7 @@
2026-xx-xx
- Fixes/Improvements:
- -
+ - Fix arc noding failure with endpoint intersections (GH-1513, Dan Baston)
## Changes in 3.15.0
2026-09-01
diff --git a/src/noding/NodableArcString.cpp b/src/noding/NodableArcString.cpp
index 6db428795..5b41a62f8 100644
--- a/src/noding/NodableArcString.cpp
+++ b/src/noding/NodableArcString.cpp
@@ -151,8 +151,32 @@ prepareArcPoints(const CircularArc& arc, std::vector<CoordinateXYZM> splitPoints
// Calculate the midpoint of an arc between p0 and p2.
// We don't actually use the calculated point here, we just want to make sure that
// the arc from p0 to p2 is long enough to contain a midpoint.
- const geom::CoordinateXY p1 = algorithm::CircularArcs::getMidpoint(p0, p2, center, arc.getRadius(), true);
+ const double t0 = algorithm::CircularArcs::getAngle(p0, center);
+ const double t2 = algorithm::CircularArcs::getAngle(p2, center);
+ if (t0 == t2) {
+#if DEBUG_NODABLE_ARC_STRING
+ std::cout << "Skipping split point " << p2 << " because the arc endpoints have the same angle" << std::endl;
+#endif
+ if (retained.size() == 1) {
+ splitStart = true;
+ }
+ continue;
+ }
+ const double t1 = algorithm::CircularArcs::getMidpointAngle(t0, t2, true);
+
+ // Reject split point where computed angle doesn't fall between endpoints
+ if (!algorithm::Angle::isWithinCCW(t1, t0, t2)) {
+#if DEBUG_NODABLE_ARC_STRING
+ std::cout << "Skipping split point " << p2 << " because the calculated arc midpoint angle " << t1 << " does not fall within the arc from " << t0 << " to " << t2 << std::endl;
+#endif
+ if (retained.size() == 1) {
+ splitStart = true;
+ }
+ continue;
+ }
+
+ const geom::CoordinateXY p1 = algorithm::CircularArcs::createPoint(center, arc.getRadius(), t1);
if (p1.equals2D(p0) || p1.equals2D(p2)) {
#if DEBUG_NODABLE_ARC_STRING
std::cout << "Skipping split point " << p2 << " because the calculated arc midpoint " << p1 << " equals one of the endpoints" << std::endl;
@@ -173,21 +197,6 @@ prepareArcPoints(const CircularArc& arc, std::vector<CoordinateXYZM> splitPoints
continue;
}
- // Reject split point where computed doesn't fall between endpoints
- const double t0 = algorithm::Angle::normalizePositive(isCCW ? arc.theta0() : arc.theta2());
- const double t1 = algorithm::Angle::normalizePositive(algorithm::CircularArcs::getAngle(p1, center));
- const double t2 = algorithm::Angle::normalizePositive(isCCW ? arc.theta2() : arc.theta0());
-
- if (!algorithm::Angle::isWithinCCW(t1, t0, t2)) { // != isCCW) {
-#if DEBUG_NODABLE_ARC_STRING
- std::cout << "Skipping split point " << p2 << " because the calculated arc midpoint " << p1 << " does not fall within the arc from " << p0 << " to " << p2 << std::endl;
-#endif
- if (retained.size() == 1) {
- splitStart = true;
- }
- continue;
- }
-
#if DEBUG_NODABLE_ARC_STRING
std::cout << "Keeping split point " << p2 << std::endl;
#endif
diff --git a/tests/unit/operation/overlayng/OverlayNGTest.cpp b/tests/unit/operation/overlayng/OverlayNGTest.cpp
index 0240fa457..3ee1821c6 100644
--- a/tests/unit/operation/overlayng/OverlayNGTest.cpp
+++ b/tests/unit/operation/overlayng/OverlayNGTest.cpp
@@ -845,4 +845,15 @@ void object::test<64>()
testOverlay(a, b, exp, OverlayNG::UNION, 0);
}
+template<>
+template<>
+void object::test<65>()
+{
+ set_test_name("Intersection of circular CurvePolygon with itself");
+
+ std::string a = "CURVEPOLYGON (CIRCULARSTRING (-1 0,0 1,1 0,0 -1,-1 0))";
+
+ testOverlay(a, a, a, OverlayNG::INTERSECTION, 0);
+}
+
} // namespace tut
-----------------------------------------------------------------------
Summary of changes:
NEWS.md | 2 +-
src/noding/NodableArcString.cpp | 33 +++++++++++++++---------
tests/unit/operation/overlayng/OverlayNGTest.cpp | 11 ++++++++
3 files changed, 33 insertions(+), 13 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list