From e0e68f636e3b0d32dd7ae09928044699f990a447 Mon Sep 17 00:00:00 2001 From: Dan Baston Date: Thu, 21 Sep 2023 21:21:05 -0400 Subject: [PATCH] CoordinateSequence: Fix logic error when adding another CoordSeq (#963) --- NEWS.md | 3 ++- src/geom/CoordinateSequence.cpp | 7 ++++++- tests/unit/geom/CoordinateSequenceTest.cpp | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index b1be865e0c..a1502586ae 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,8 +13,9 @@ - Fix LargestEmptyCircle to respect polygonal obstacles (GH-939, Martin Davis) - Fix WKTWriter to emit EMPTY elements in multi-geometries (GH-952, Mike Taves) - Fix IncrementalDelaunayTriangulator to ensure triangulation boundary is convex (GH-953, Martin Davis) - - Fix PreparedLineStringDistance for lines within envelope and polygons (GH-959, Martin Davis) + - Fix PreparedLineStringDistance for lines within envelope and polygons (GH-959, Martin Davis) - Improve scale handling for PrecisionModel (GH-956, Martin Davis) + - Fix error in CoordinateSequence::add when disallowing repeated points (GH-963, Dan Baston) ## Changes in 3.12.0 diff --git a/src/geom/CoordinateSequence.cpp b/src/geom/CoordinateSequence.cpp index a0ff679449..fc36b4bb35 100644 --- a/src/geom/CoordinateSequence.cpp +++ b/src/geom/CoordinateSequence.cpp @@ -191,8 +191,13 @@ CoordinateSequence::add(const CoordinateSequence& cs, std::size_t from, std::siz } } + if (first > to) { + // No unique points to add. + return; + } + std::size_t last = first + 1; - const CoordinateXY* last_unique = &cs.front(); + const CoordinateXY* last_unique = &cs.getAt(first); while(last <= to) { const CoordinateXY* curr = &cs.getAt(last); if (curr->equals2D(*last_unique)) { diff --git a/tests/unit/geom/CoordinateSequenceTest.cpp b/tests/unit/geom/CoordinateSequenceTest.cpp index 7ec843badc..1d9c08782b 100644 --- a/tests/unit/geom/CoordinateSequenceTest.cpp +++ b/tests/unit/geom/CoordinateSequenceTest.cpp @@ -1493,4 +1493,21 @@ void object::test<54> ensure(xyz3_2.equalsIdentical(xyz3)); } + +// test add(CoordinateSequence&, false) when last point of receiving sequence is found after the beginning of donor sequence +template<> +template<> +void object::test<55> +() +{ + CoordinateSequence seq1{CoordinateXY(1,2), CoordinateXY(3, 4)}; + CoordinateSequence seq2{CoordinateXY(3, 4), CoordinateXY(3, 4), CoordinateXY(5, 6), CoordinateXY(3, 4), CoordinateXY(7, 8), CoordinateXY(7, 8), CoordinateXY(9, 10)}; + + CoordinateSequence expected{CoordinateXY(1, 2), CoordinateXY(3, 4), CoordinateXY(5, 6), CoordinateXY(3, 4), CoordinateXY(7, 8), CoordinateXY(9, 10)}; + + seq1.add(seq2, false); + + ensure_equals(seq1, expected); +} + } // namespace tut