[geos-commits] [SCM] GEOS branch main updated. fc95e4b8f8490f952a3d3759684dc1c3330f5f83
git at osgeo.org
git at osgeo.org
Mon Nov 18 14:43:02 PST 2024
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 fc95e4b8f8490f952a3d3759684dc1c3330f5f83 (commit)
via 32a3bf4923b6c1c8ce38f21260d6e1a02d0bbb2f (commit)
from dc4e7b2b2e6f3d61f0bd1881015a250ebd988606 (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 fc95e4b8f8490f952a3d3759684dc1c3330f5f83
Author: Daniel Baston <dbaston at gmail.com>
Date: Mon Nov 18 12:16:49 2024 -0500
BoundaryOp: Preserve M values in (Multi)LineString inputs
Fixes https://github.com/libgeos/geos/issues/1195
diff --git a/src/operation/BoundaryOp.cpp b/src/operation/BoundaryOp.cpp
index b407a2a41..c0c452c45 100644
--- a/src/operation/BoundaryOp.cpp
+++ b/src/operation/BoundaryOp.cpp
@@ -139,7 +139,9 @@ BoundaryOp::boundaryMultiLineString(const geom::MultiLineString& mLine)
// return Point or MultiPoint
if (bdyPts->size() == 1) {
- return std::unique_ptr<Geometry>(m_geomFact.createPoint(bdyPts->getAt(0)));
+ return bdyPts->applyAt(0, [this](const auto& c) {
+ return m_geomFact.createPoint(c);
+ });
}
// this handles 0 points case as well
return std::unique_ptr<Geometry>(m_geomFact.createMultiPoint(*bdyPts));
@@ -148,8 +150,8 @@ BoundaryOp::boundaryMultiLineString(const geom::MultiLineString& mLine)
std::unique_ptr<CoordinateSequence>
BoundaryOp::computeBoundaryCoordinates(const geom::MultiLineString& mLine)
{
- auto bdyPts = detail::make_unique<CoordinateSequence>();
- std::map<Coordinate, int> endpointMap;
+ auto bdyPts = detail::make_unique<CoordinateSequence>(0, mLine.hasZ(), mLine.hasM());
+ std::map<geom::CoordinateXYZM, int> endpointMap;
for (std::size_t i = 0; i < mLine.getNumGeometries(); i++) {
const LineString* line = mLine.getGeometryN(i);
@@ -158,14 +160,20 @@ BoundaryOp::computeBoundaryCoordinates(const geom::MultiLineString& mLine)
continue;
}
- endpointMap[line->getCoordinateN(0)]++;
- endpointMap[line->getCoordinateN(line->getNumPoints() - 1)]++;
+ const CoordinateSequence& pts = *line->getCoordinatesRO();
+
+ geom::CoordinateXYZM start;
+ geom::CoordinateXYZM end;
+ pts.getAt(0, start);
+ pts.getAt(pts.size() - 1, end);
+
+ endpointMap[start]++;
+ endpointMap[end]++;
}
- for (const auto& entry: endpointMap) {
- auto valence = entry.second;
+ for (const auto& [coord, valence] : endpointMap) {
if (m_bnRule.isInBoundary(valence)) {
- bdyPts->add(entry.first);
+ bdyPts->add(coord);
}
}
diff --git a/tests/unit/capi/GEOSBoundaryTest.cpp b/tests/unit/capi/GEOSBoundaryTest.cpp
index d24bd558f..17f4af46e 100644
--- a/tests/unit/capi/GEOSBoundaryTest.cpp
+++ b/tests/unit/capi/GEOSBoundaryTest.cpp
@@ -41,5 +41,27 @@ void object::test<2>()
ensure(result_ == nullptr);
}
+template<>
+template<>
+void object::test<3>()
+{
+ input_ = fromWKT("MULTILINESTRING M ((10 11 3, 20 21 4), (20 21 4, 32 21 3))");
+ result_ = GEOSBoundary(input_);
+ expected_ = fromWKT("MULTIPOINT M ((10 11 3), (32 21 3))");
+
+ ensure_geometry_equals_identical(result_, expected_);
+}
+
+template<>
+template<>
+void object::test<4>()
+{
+ input_ = fromWKT("POLYGON M ((0 0 0, 1 0 1, 1 1 2, 0 1 3, 0 0 4))");
+ result_ = GEOSBoundary(input_);
+ expected_ = fromWKT("LINESTRING M (0 0 0, 1 0 1, 1 1 2, 0 1 3, 0 0 4)");
+
+ ensure_geometry_equals_identical(result_, expected_);
+}
+
} // namespace tut
diff --git a/tests/unit/capi/capi_test_utils.h b/tests/unit/capi/capi_test_utils.h
index 803c51cf2..aef573565 100644
--- a/tests/unit/capi/capi_test_utils.h
+++ b/tests/unit/capi/capi_test_utils.h
@@ -72,7 +72,10 @@ namespace capitest {
fromWKT(const char* wkt)
{
GEOSGeometry* g = GEOSGeomFromWKT(wkt);
- tut::ensure(g != nullptr);
+ if (g == nullptr) {
+ std::string message = "WKT is invalid: " + std::string(wkt);
+ tut::ensure(message, g != nullptr);
+ }
return g;
}
commit 32a3bf4923b6c1c8ce38f21260d6e1a02d0bbb2f
Author: Daniel Baston <dbaston at gmail.com>
Date: Mon Nov 18 08:39:42 2024 -0500
CoordinateSequence: Add applyAt method
diff --git a/include/geos/geom/CoordinateSequence.h b/include/geos/geom/CoordinateSequence.h
index b49b8693f..c135ce18d 100644
--- a/include/geos/geom/CoordinateSequence.h
+++ b/include/geos/geom/CoordinateSequence.h
@@ -679,6 +679,16 @@ public:
}
}
+ template<typename F>
+ auto applyAt(size_t i, F&& fun) const {
+ switch(getCoordinateType()) {
+ case CoordinateType::XYZ: return fun(getAt<Coordinate>(i));
+ case CoordinateType::XYM: return fun(getAt<CoordinateXYM>(i));
+ case CoordinateType::XYZM: return fun(getAt<CoordinateXYZM>(i));
+ default: return fun(getAt<CoordinateXY>(i));
+ }
+ }
+
template<typename F>
void forEach(F&& fun) const {
switch(getCoordinateType()) {
diff --git a/src/geom/SimpleCurve.cpp b/src/geom/SimpleCurve.cpp
index 882fb9402..952d207d0 100644
--- a/src/geom/SimpleCurve.cpp
+++ b/src/geom/SimpleCurve.cpp
@@ -252,16 +252,9 @@ SimpleCurve::getPointN(std::size_t n) const
assert(getFactory());
assert(points.get());
- if (hasM() || hasZ()) {
- CoordinateXYZM c;
- points->getAt(n, c);
+ return points->applyAt(n, [this](const auto& c) {
return getFactory()->createPoint(c);
- }
- else {
- CoordinateXY c;
- points->getAt(n, c);
- return getFactory()->createPoint(c);
- }
+ });
}
std::unique_ptr<Point>
-----------------------------------------------------------------------
Summary of changes:
include/geos/geom/CoordinateSequence.h | 10 ++++++++++
src/geom/SimpleCurve.cpp | 11 ++---------
src/operation/BoundaryOp.cpp | 24 ++++++++++++++++--------
tests/unit/capi/GEOSBoundaryTest.cpp | 22 ++++++++++++++++++++++
tests/unit/capi/capi_test_utils.h | 5 ++++-
5 files changed, 54 insertions(+), 18 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list