diff --git a/NEWS.md b/NEWS.md index ee77dbf89c..877845bbba 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,8 @@ - DouglasPeuckerLineSimplifier, avoid crash with Point input and NaN tolerance (GH-1078, Dan Baston) - GEOSLineSubstring, avoid crash with NaN length fraction (GH-1077, Dan Baston) - MinimumClearance, avoid crash on NaN inputs (GH-1079, Dan Baston) + - Fix LineString->getPoint(n) for M geometries (GH-1191, @hsieyuan) + ## Changes in 3.12.2 2024-06-05 diff --git a/src/geom/LineString.cpp b/src/geom/LineString.cpp index e3c84c3dc8..209bef43e6 100644 --- a/src/geom/LineString.cpp +++ b/src/geom/LineString.cpp @@ -181,7 +181,16 @@ LineString::getPointN(std::size_t n) const { assert(getFactory()); assert(points.get()); - return std::unique_ptr(getFactory()->createPoint(points->getAt(n))); + if (hasM() || hasZ()) { + CoordinateXYZM c; + points->getAt(n, c); + return getFactory()->createPoint(c); + } + else { + CoordinateXY c; + points->getAt(n, c); + return getFactory()->createPoint(c); + } } std::unique_ptr diff --git a/tests/unit/geom/LineStringTest.cpp b/tests/unit/geom/LineStringTest.cpp index 26a8756bfb..1e1136fce5 100644 --- a/tests/unit/geom/LineStringTest.cpp +++ b/tests/unit/geom/LineStringTest.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ struct test_linestring_data { geos::geom::PrecisionModel pm_; geos::geom::GeometryFactory::Ptr factory_; geos::io::WKTReader reader_; + geos::io::WKTWriter writer_; std::unique_ptr empty_line_; std::unique_ptr line_; @@ -588,5 +590,23 @@ void object::test<32> ensure(!line_->hasDimension(geos::geom::Dimension::A)); } + +// https://github.com/libgeos/geos/issues/1191 +// line->getPoint(n) loses M dimension +template<> +template<> +void object::test<33> +() +{ + auto geom = reader_.read("LINESTRING M (0 1 2, 10 11 12, 20 21 22)"); + ensure(geom != nullptr); + geos::geom::LineString *line = static_cast(geom.get()); + ensure_equals(line->getCoordinateDimension(), 3); + auto pt = line->getPointN(2); + auto out = writer_.write(*pt); + ensure_equals(out, "POINT M (20 21 22)"); +} + + } // namespace tut