[geos-commits] [SCM] GEOS branch main updated. bd42a68a09ae9001a66ad4e1a82cd563639ef30b

git at osgeo.org git at osgeo.org
Tue May 2 13:04:47 PDT 2023


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  bd42a68a09ae9001a66ad4e1a82cd563639ef30b (commit)
      from  1105298873b17260fcbcd7f82901ddcbfff8ff82 (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 bd42a68a09ae9001a66ad4e1a82cd563639ef30b
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Tue May 2 13:04:16 2023 -0700

    Use the coverage/CoverageUnion for the CAPI GEOSCoverageUnion

diff --git a/capi/geos_ts_c.cpp b/capi/geos_ts_c.cpp
index e30efc424..5ca390319 100644
--- a/capi/geos_ts_c.cpp
+++ b/capi/geos_ts_c.cpp
@@ -29,6 +29,7 @@
 #include <geos/algorithm/hull/ConcaveHullOfPolygons.h>
 #include <geos/coverage/CoverageValidator.h>
 #include <geos/coverage/CoverageSimplifier.h>
+#include <geos/coverage/CoverageUnion.h>
 #include <geos/geom/Coordinate.h>
 #include <geos/geom/CoordinateSequence.h>
 #include <geos/geom/Envelope.h>
@@ -79,7 +80,6 @@
 #include <geos/operation/relate/RelateOp.h>
 #include <geos/operation/sharedpaths/SharedPathsOp.h>
 #include <geos/operation/union/CascadedPolygonUnion.h>
-#include <geos/operation/union/CoverageUnion.h>
 #include <geos/operation/union/DisjointSubsetUnion.h>
 #include <geos/operation/valid/IsValidOp.h>
 #include <geos/operation/valid/MakeValid.h>
@@ -1494,7 +1494,7 @@ extern "C" {
     GEOSCoverageUnion_r(GEOSContextHandle_t extHandle, const Geometry* g)
     {
         return execute(extHandle, [&]() {
-            auto g3 = geos::operation::geounion::CoverageUnion::Union(g);
+            auto g3 = geos::coverage::CoverageUnion::Union(g);
             g3->setSRID(g->getSRID());
             return g3.release();
         });
diff --git a/include/geos/coverage/CoverageUnion.h b/include/geos/coverage/CoverageUnion.h
index 2bdfb0101..8983c19c0 100644
--- a/include/geos/coverage/CoverageUnion.h
+++ b/include/geos/coverage/CoverageUnion.h
@@ -48,11 +48,19 @@ public:
     /**
     * Unions a polygonal coverage.
     *
-    * @param coverage the polygons in the coverage
+    * @param coverage a vector of polygons in the coverage
     * @return the union of the coverage polygons
     */
     static std::unique_ptr<Geometry> Union(std::vector<const Geometry*>& coverage);
 
+    /**
+    * Unions a polygonal coverage.
+    *
+    * @param coverage a collection of the polygons in the coverage
+    * @return the union of the coverage polygons
+    */
+    static std::unique_ptr<Geometry> Union(const Geometry* coverage);
+
 };
 
 } // namespace geos::coverage
diff --git a/include/geos/operation/overlayng/CoverageUnion.h b/include/geos/operation/overlayng/CoverageUnion.h
index 9f9e65128..6c7a8be84 100644
--- a/include/geos/operation/overlayng/CoverageUnion.h
+++ b/include/geos/operation/overlayng/CoverageUnion.h
@@ -79,6 +79,8 @@ private:
 
 public:
 
+    static constexpr double AREA_PCT_DIFF_TOL = 1e-6;
+
     /**
     * Unions a valid polygonal coverage or linear network.
     *
diff --git a/src/coverage/CoverageUnion.cpp b/src/coverage/CoverageUnion.cpp
index 4ff5e5fe2..4e2d547e1 100644
--- a/src/coverage/CoverageUnion.cpp
+++ b/src/coverage/CoverageUnion.cpp
@@ -36,7 +36,7 @@ CoverageUnion::Union(std::vector<const Geometry*>& coverage)
     if (coverage.size() == 0)
         return nullptr;
 
-    //TODO? spatial sort polgyons to improve performance
+    // TODO? spatial sort polygons to improve performance
     // Test results are somewhat inconclusive
     //shape::fractal::HilbertEncoder::sort(coverage.begin(), coverage.end());
 
@@ -46,5 +46,17 @@ CoverageUnion::Union(std::vector<const Geometry*>& coverage)
 }
 
 
+/* public static */
+std::unique_ptr<Geometry>
+CoverageUnion::Union(const Geometry* coverage)
+{
+    const GeometryCollection* col = dynamic_cast<const GeometryCollection*>(coverage);
+
+    if (col == nullptr) return nullptr;
+
+    return operation::overlayng::CoverageUnion::geomunion(col);
+}
+
+
 } // namespace geos.coverage
 } // namespace geos
diff --git a/src/operation/overlayng/CoverageUnion.cpp b/src/operation/overlayng/CoverageUnion.cpp
index 5483be9bb..c0c8a1458 100644
--- a/src/operation/overlayng/CoverageUnion.cpp
+++ b/src/operation/overlayng/CoverageUnion.cpp
@@ -18,6 +18,7 @@
 #include <geos/noding/BoundaryChainNoder.h>
 #include <geos/operation/overlayng/OverlayNG.h>
 #include <geos/geom/Geometry.h>
+#include <geos/util/TopologyException.h>
 
 using geos::geom::Geometry;
 using geos::noding::SegmentExtractingNoder;
@@ -32,17 +33,27 @@ namespace overlayng { // geos.operation.overlayng
 std::unique_ptr<Geometry>
 CoverageUnion::geomunion(const Geometry* coverage)
 {
+    double area_in = coverage->getArea();
+    std::unique_ptr<Geometry> result;
 
     // a precision model is not needed since no noding is done
     //-- linear networks require a segment-extracting noder
     if (coverage->getDimension() < 2) {
         SegmentExtractingNoder sen;
-        return OverlayNG::geomunion(coverage, nullptr, &sen);
+        result = OverlayNG::geomunion(coverage, nullptr, &sen);
     }
     else {
         BoundaryChainNoder bcn;
-        return OverlayNG::geomunion(coverage, nullptr, &bcn);
+        result = OverlayNG::geomunion(coverage, nullptr, &bcn);
     }
+
+    double area_out = result->getArea();
+
+    if (std::abs((area_out - area_in)/area_in) > AREA_PCT_DIFF_TOL) {
+        throw geos::util::TopologyException("CoverageUnion cannot process overlapping inputs.");
+    }
+
+    return result;
 }
 
 
diff --git a/tests/unit/capi/GEOSCoverageUnionTest.cpp b/tests/unit/capi/GEOSCoverageUnionTest.cpp
index 992a685aa..6b8a71e7a 100644
--- a/tests/unit/capi/GEOSCoverageUnionTest.cpp
+++ b/tests/unit/capi/GEOSCoverageUnionTest.cpp
@@ -83,7 +83,7 @@ template<>
 template<>
 void object::test<2>
 () {
-    // Overlapping inputs (error)
+    // Overlapping inputs (unchanged output)
     std::vector<std::string> wkt{
             "POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))",
             "POLYGON ((1 0, 0.9 1, 2 1, 2 0, 1 0))"
@@ -96,10 +96,11 @@ void object::test<2>
 
     auto input = GEOSGeom_createCollection_r(m_context, GEOS_GEOMETRYCOLLECTION, geoms, 2);
     auto result = GEOSCoverageUnion_r(m_context, input);
-
-    ensure( result == nullptr );
+    ensure( result != nullptr );
+    ensure( GEOSEquals_r(m_context, input, result) );
 
     GEOSGeom_destroy_r(m_context, input);
+    GEOSGeom_destroy_r(m_context, result);
 }
 
 

-----------------------------------------------------------------------

Summary of changes:
 capi/geos_ts_c.cpp                               |  4 ++--
 include/geos/coverage/CoverageUnion.h            | 10 +++++++++-
 include/geos/operation/overlayng/CoverageUnion.h |  2 ++
 src/coverage/CoverageUnion.cpp                   | 14 +++++++++++++-
 src/operation/overlayng/CoverageUnion.cpp        | 15 +++++++++++++--
 tests/unit/capi/GEOSCoverageUnionTest.cpp        |  7 ++++---
 6 files changed, 43 insertions(+), 9 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list