[geos-commits] [SCM] GEOS branch main updated. 77574b214701e0f2750b949e7f65cbdd49a4ce31
git at osgeo.org
git at osgeo.org
Tue Mar 24 09:14:17 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, main has been updated
via 77574b214701e0f2750b949e7f65cbdd49a4ce31 (commit)
from 81ab2d7b01990811c3edb00f7407a20908dfe1cc (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 77574b214701e0f2750b949e7f65cbdd49a4ce31
Author: Daniel Baston <dbaston at gmail.com>
Date: Tue Mar 24 12:13:49 2026 -0400
RingClipper: Avoid dropping M values (#1407)
diff --git a/include/geos/operation/overlayng/RingClipper.h b/include/geos/operation/overlayng/RingClipper.h
index d8f6a186e..8bee13b31 100644
--- a/include/geos/operation/overlayng/RingClipper.h
+++ b/include/geos/operation/overlayng/RingClipper.h
@@ -61,6 +61,7 @@ namespace overlayng { // geos.operation.overlayng
*/
class GEOS_DLL RingClipper {
using Coordinate = geos::geom::Coordinate;
+ using CoordinateXY = geos::geom::CoordinateXY;
using CoordinateSequence = geos::geom::CoordinateSequence;
using Envelope = geos::geom::Envelope;
@@ -87,10 +88,10 @@ private:
* with an edge of the clip box.
* The segment must be known to intersect the edge.
*/
- void intersection(const Coordinate& a, const Coordinate& b, int edgeIndex, Coordinate& rsltPt) const;
- double intersectionLineY(const Coordinate& a, const Coordinate& b, double y) const;
- double intersectionLineX(const Coordinate& a, const Coordinate& b, double x) const;
- bool isInsideEdge(const Coordinate& p, int edgeIndex) const;
+ void intersection(const CoordinateXY& a, const CoordinateXY& b, int edgeIndex, CoordinateXY& rsltPt) const;
+ static double intersectionLineY(const CoordinateXY& a, const CoordinateXY& b, double y);
+ static double intersectionLineX(const CoordinateXY& a, const CoordinateXY& b, double x);
+ bool isInsideEdge(const CoordinateXY& p, int edgeIndex) const;
public:
diff --git a/src/operation/overlayng/RingClipper.cpp b/src/operation/overlayng/RingClipper.cpp
index cf108dd1e..2551990f8 100644
--- a/src/operation/overlayng/RingClipper.cpp
+++ b/src/operation/overlayng/RingClipper.cpp
@@ -15,6 +15,7 @@
#include <geos/operation/overlayng/RingClipper.h>
using geos::geom::CoordinateSequence;
+using geos::geom::CoordinateXYZM;
namespace geos { // geos
namespace operation { // geos.operation
@@ -41,16 +42,16 @@ std::unique_ptr<CoordinateSequence>
RingClipper::clipToBoxEdge(const CoordinateSequence* pts, int edgeIndex, bool closeRing) const
{
// TODO: is it possible to avoid copying array 4 times?
- std::unique_ptr<CoordinateSequence> ptsClip(new CoordinateSequence());
+ auto ptsClip = std::make_unique<CoordinateSequence>(0, pts->hasZ(), pts->hasM());
- Coordinate p0;
+ CoordinateXYZM p0;
pts->getAt(pts->size() - 1, p0);
for (std::size_t i = 0; i < pts->size(); i++) {
- Coordinate p1;
+ CoordinateXYZM p1;
pts->getAt(i, p1);
if (isInsideEdge(p1, edgeIndex)) {
if (!isInsideEdge(p0, edgeIndex)) {
- Coordinate intPt;
+ CoordinateXY intPt;
intersection(p0, p1, edgeIndex, intPt);
ptsClip->add(intPt, false);
}
@@ -59,7 +60,7 @@ RingClipper::clipToBoxEdge(const CoordinateSequence* pts, int edgeIndex, bool cl
}
else if (isInsideEdge(p0, edgeIndex)) {
- Coordinate intPt;
+ CoordinateXY intPt;
intersection(p0, p1, edgeIndex, intPt);
ptsClip->add(intPt, false);
}
@@ -69,28 +70,26 @@ RingClipper::clipToBoxEdge(const CoordinateSequence* pts, int edgeIndex, bool cl
}
// add closing point if required
- if (closeRing && ptsClip->size() > 0) {
- const Coordinate& start = ptsClip->getAt(0);
- if (!start.equals2D(ptsClip->getAt(ptsClip->size() - 1))) {
- ptsClip->add(start);
- }
+ if (closeRing) {
+ ptsClip->closeRing();
}
+
return ptsClip;
}
/*private*/
void
-RingClipper::intersection(const Coordinate& a, const Coordinate& b, int edgeIndex, Coordinate& rsltPt) const
+RingClipper::intersection(const CoordinateXY& a, const CoordinateXY& b, int edgeIndex, CoordinateXY& rsltPt) const
{
switch (edgeIndex) {
case BOX_BOTTOM:
- rsltPt = Coordinate(intersectionLineY(a, b, clipEnv.getMinY()), clipEnv.getMinY());
+ rsltPt = CoordinateXY(intersectionLineY(a, b, clipEnv.getMinY()), clipEnv.getMinY());
break;
case BOX_RIGHT:
- rsltPt = Coordinate(clipEnv.getMaxX(), intersectionLineX(a, b, clipEnv.getMaxX()));
+ rsltPt = CoordinateXY(clipEnv.getMaxX(), intersectionLineX(a, b, clipEnv.getMaxX()));
break;
case BOX_TOP:
- rsltPt = Coordinate(intersectionLineY(a, b, clipEnv.getMaxY()), clipEnv.getMaxY());
+ rsltPt = CoordinateXY(intersectionLineY(a, b, clipEnv.getMaxY()), clipEnv.getMaxY());
break;
case BOX_LEFT:
default:
@@ -101,7 +100,7 @@ RingClipper::intersection(const Coordinate& a, const Coordinate& b, int edgeInde
/*private*/
double
-RingClipper::intersectionLineY(const Coordinate& a, const Coordinate& b, double y) const
+RingClipper::intersectionLineY(const CoordinateXY& a, const CoordinateXY& b, double y)
{
double m = (b.x - a.x) / (b.y - a.y);
double intercept = (y - a.y) * m;
@@ -110,7 +109,7 @@ RingClipper::intersectionLineY(const Coordinate& a, const Coordinate& b, double
/*private*/
double
-RingClipper::intersectionLineX(const Coordinate& a, const Coordinate& b, double x) const
+RingClipper::intersectionLineX(const CoordinateXY& a, const CoordinateXY& b, double x)
{
double m = (b.y - a.y) / (b.x - a.x);
double intercept = (x - a.x) * m;
@@ -119,7 +118,7 @@ RingClipper::intersectionLineX(const Coordinate& a, const Coordinate& b, double
/*private*/
bool
-RingClipper::isInsideEdge(const Coordinate& p, int edgeIndex) const
+RingClipper::isInsideEdge(const CoordinateXY& p, int edgeIndex) const
{
if (clipEnv.isNull()) {
return false;
diff --git a/tests/unit/operation/overlayng/OverlayNGZTest.cpp b/tests/unit/operation/overlayng/OverlayNGZTest.cpp
index e9ee46377..732d7eb25 100644
--- a/tests/unit/operation/overlayng/OverlayNGZTest.cpp
+++ b/tests/unit/operation/overlayng/OverlayNGZTest.cpp
@@ -316,4 +316,14 @@ void object::test<21>()
"LINESTRING ZM (0 0 2 9, 1 0 5 7)");
}
+template<>
+template<>
+void object::test<22> ()
+{
+ set_test_name("POLYGON XYM / POLYGON XYM intersection");
+
+ checkIntersection("POLYGON M ((4 12 6, 2 6 7, 7 6 8, 11 4 9, 15 15 10, 4 12 6))", "POLYGON M ((1 9 1, 9 9 2, 9 1 3, 1 1 4, 1 9 1))",
+ "POLYGON M ((2 6 7, 3 9 3.875, 9 9 2, 9 5 5.5, 7 6 8, 2 6 7))");
+}
+
} // namespace tut
-----------------------------------------------------------------------
Summary of changes:
include/geos/operation/overlayng/RingClipper.h | 9 ++++---
src/operation/overlayng/RingClipper.cpp | 33 +++++++++++------------
tests/unit/operation/overlayng/OverlayNGZTest.cpp | 10 +++++++
3 files changed, 31 insertions(+), 21 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list