[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