From 1ee3b0be4e860b0b76e857075b4f51de01be581b Mon Sep 17 00:00:00 2001 From: Paul Ramsey Date: Fri, 15 Nov 2024 14:35:25 -0800 Subject: [PATCH] Fix line->getPoint(n) error with m coordinates GH-1191 --- src/geom/SimpleCurve.cpp | 13 ++++++++- tests/unit/geom/LineStringTest.cpp | 46 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/geom/SimpleCurve.cpp b/src/geom/SimpleCurve.cpp index be9b50b443..6bb589257b 100644 --- a/src/geom/SimpleCurve.cpp +++ b/src/geom/SimpleCurve.cpp @@ -251,7 +251,18 @@ SimpleCurve::getPointN(std::size_t n) const { assert(getFactory()); assert(points.get()); - return std::unique_ptr(getFactory()->createPoint(points->getAt(n))); + + std::unique_ptr point; + 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..06e1dfa0cf 100644 --- a/tests/unit/geom/LineStringTest.cpp +++ b/tests/unit/geom/LineStringTest.cpp @@ -35,6 +35,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 +589,50 @@ 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)"); +} + +template<> +template<> +void object::test<34> +() +{ + auto geom = reader_.read("LINESTRING Z (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 Z (20 21 22)"); +} + +template<> +template<> +void object::test<35> +() +{ + auto geom = reader_.read("LINESTRING ZM (0 1 2 3, 10 11 12 13, 20 21 22 23)"); + ensure(geom != nullptr); + geos::geom::LineString *line = static_cast(geom.get()); + ensure_equals(line->getCoordinateDimension(), 4); + auto pt = line->getPointN(2); + auto out = writer_.write(*pt); + ensure_equals(out, "POINT ZM (20 21 22 23)"); +} + + } // namespace tut