[geos-commits] [SCM] GEOS branch main updated. afe4d0595b2203605f6cdccd7742a9665caab6e3
git at osgeo.org
git at osgeo.org
Sun Nov 16 16:46:26 PST 2025
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 afe4d0595b2203605f6cdccd7742a9665caab6e3 (commit)
from 26e1cddea7b6d24d1b6c836a76bb9232888b432d (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 afe4d0595b2203605f6cdccd7742a9665caab6e3
Author: Daniel Baston <dbaston at gmail.com>
Date: Sun Nov 16 19:46:04 2025 -0500
DouglasPeuckerLineSimplifier: preserve M values (#1317)
Resolves https://github.com/libgeos/geos/issues/1315
diff --git a/capi/geos_c.h.in b/capi/geos_c.h.in
index b5d5ada78..7c80f7016 100644
--- a/capi/geos_c.h.in
+++ b/capi/geos_c.h.in
@@ -5207,6 +5207,7 @@ extern GEOSGeometry GEOS_DLL *GEOSReverse(const GEOSGeometry* g);
* to the coordinate sequences of the input geometry.
* Removes "unnecessary" vertices, vertices
* that are co-linear within the tolerance distance.
+* Z and M values on the retained coordinates will be preserved.
* \param g The input geometry
* \param tolerance The tolerance to apply. Larger tolerance leads to simpler output.
* \return The simplified geometry
diff --git a/src/simplify/DouglasPeuckerLineSimplifier.cpp b/src/simplify/DouglasPeuckerLineSimplifier.cpp
index 49e040e0b..ff436e578 100644
--- a/src/simplify/DouglasPeuckerLineSimplifier.cpp
+++ b/src/simplify/DouglasPeuckerLineSimplifier.cpp
@@ -75,7 +75,7 @@ DouglasPeuckerLineSimplifier::setPreserveClosedEndpoint(bool preserve)
std::unique_ptr<CoordinateSequence>
DouglasPeuckerLineSimplifier::simplify()
{
- auto coordList = detail::make_unique<CoordinateSequence>();
+ auto coordList = detail::make_unique<CoordinateSequence>(0, pts.hasZ(), pts.hasM());
// empty coordlist is the simplest, won't simplify further
if(pts.isEmpty()) {
@@ -85,9 +85,18 @@ DouglasPeuckerLineSimplifier::simplify()
usePt = std::vector<bool>(pts.size(), true);
simplifySection(0, pts.size() - 1);
- for(std::size_t i = 0, n = pts.size(); i < n; ++i) {
- if(usePt[i]) {
- coordList->add(pts[i]);
+ // Add continuous ranges of retained points from pts to coordList
+ std::size_t from = 0;
+ while (from < pts.size() && !usePt[from]) {
+ from++;
+ }
+ for(std::size_t to = from + 1; to <= pts.size(); to++) {
+ if (to == pts.size() || !usePt[to]) {
+ coordList->add(pts, from, to - 1);
+ while (to < pts.size() && !usePt[to]) {
+ to++;
+ }
+ from = to;
}
}
@@ -96,8 +105,7 @@ DouglasPeuckerLineSimplifier::simplify()
if (simplifyRing && coordList->size() > geom::LinearRing::MINIMUM_VALID_SIZE) {
geom::LineSegment seg(coordList->getAt(coordList->size() - 2), coordList->getAt(1));
if (seg.distance(coordList->getAt(0)) <= distanceTolerance) {
- auto ret = detail::make_unique<CoordinateSequence>();
- ret->reserve(coordList->size() - 1);
+ auto ret = detail::make_unique<CoordinateSequence>(0, pts.hasZ(), pts.hasM());
ret->add(*coordList, 1, coordList->size() - 2);
ret->closeRing();
coordList = std::move(ret);
diff --git a/tests/unit/simplify/DouglasPeuckerSimplifierTest.cpp b/tests/unit/simplify/DouglasPeuckerSimplifierTest.cpp
index 83f3e9e45..ee3257a90 100644
--- a/tests/unit/simplify/DouglasPeuckerSimplifierTest.cpp
+++ b/tests/unit/simplify/DouglasPeuckerSimplifierTest.cpp
@@ -45,7 +45,7 @@ struct test_dpsimp_data {
ensure("Simplified geometry is invalid!", simplified->isValid());
GeomPtr exp(wktreader.read(wkt_expected));
- ensure_equals_geometry(simplified.get(), exp.get());
+ ensure_equals_exact_geometry_xyzm(simplified.get(), exp.get(), 0);
}
void
@@ -297,7 +297,7 @@ void object::test<16>()
{
checkDP("POLYGON ((1 0, 2 0, 2 2, 0 2, 0 0, 1 0))",
0,
- "POLYGON (( 0 0, 2 0, 2 2, 0 2, 0 0))");
+ "POLYGON ((2 0, 2 2, 0 2, 0 0, 2 0))");
}
// Test that start point of a closed LineString is not changed
@@ -318,7 +318,7 @@ void object::test<18>()
checkDP(
"POLYGON ((42 42, 0 42, 0 100, 42 100, 100 42, 42 42))",
1,
- "POLYGON ((100 42, 0 42, 0 100, 42 100, 100 42))"
+ "POLYGON ((0 42, 0 100, 42 100, 100 42, 0 42))"
);
}
@@ -349,4 +349,37 @@ void object::test<20>()
}
}
+template<>
+template<>
+void object::test<21>()
+{
+ set_test_name("Z values are preserved");
+
+ checkDP("POLYGON Z ((20 220 5, 40 220 10, 60 220 15, 80 220 20, 100 220 25, 120 220 30, 140 220 35, 140 180 40, 100 180 45, 60 180 50, 20 180 55, 20 220 5))",
+ 10.0,
+ "POLYGON Z ((20 220 5, 140 220 35, 140 180 40, 20 180 55, 20 220 5))");
+}
+
+template<>
+template<>
+void object::test<22>()
+{
+ set_test_name("M values are preserved");
+
+ checkDP("POLYGON M ((20 220 5, 40 220 10, 60 220 15, 80 220 20, 100 220 25, 120 220 30, 140 220 35, 140 180 40, 100 180 45, 60 180 50, 20 180 55, 20 220 5))",
+ 10.0,
+ "POLYGON M ((20 220 5, 140 220 35, 140 180 40, 20 180 55, 20 220 5))");
+}
+
+template<>
+template<>
+void object::test<23>()
+{
+ set_test_name("Z/M values preserved when removing polygon start point");
+
+ checkDP("POLYGON ZM ((1 0 5 7, 2 0 10 9, 2 2 15 11, 0 2 20 13, 0 0 25 15, 1 0 5 7))",
+ 0,
+ "POLYGON ZM ((2 0 10 9, 2 2 15 11, 0 2 20 13, 0 0 25 15, 2 0 10 9))");
+}
+
} // namespace tut
-----------------------------------------------------------------------
Summary of changes:
capi/geos_c.h.in | 1 +
src/simplify/DouglasPeuckerLineSimplifier.cpp | 20 +++++++----
.../unit/simplify/DouglasPeuckerSimplifierTest.cpp | 39 ++++++++++++++++++++--
3 files changed, 51 insertions(+), 9 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list