[geos-commits] [SCM] GEOS branch master updated. 4b6ccd37d457db83e1c26d2dc051dfe29f83b0d0

git at osgeo.org git at osgeo.org
Thu Feb 4 16:06:01 PST 2021


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, master has been updated
       via  4b6ccd37d457db83e1c26d2dc051dfe29f83b0d0 (commit)
       via  0726ed493068994a4675266cc6cba18430f4a661 (commit)
       via  63fc947c1669dd42e2b4e4731ea2b91dfbfd1a6d (commit)
       via  77663b3d32d677e873cf5dec9cc7c3c94476e7f6 (commit)
       via  b7bcd68145a5bcdd2c56a91352aa4bb59f06d8c1 (commit)
      from  caa54c38e85d5393d7f045f4f3253fff61de72a9 (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 4b6ccd37d457db83e1c26d2dc051dfe29f83b0d0
Merge: 0726ed4 63fc947
Author: Daniel Baston <dbaston at gmail.com>
Date:   Thu Feb 4 19:05:47 2021 -0500

    Merge remote-tracking branch 'eyal0/patch-1'


commit 0726ed493068994a4675266cc6cba18430f4a661
Merge: caa54c3 77663b3
Author: Daniel Baston <dbaston at gmail.com>
Date:   Thu Feb 4 19:05:19 2021 -0500

    Merge branch 'combiner-rehab'


commit 63fc947c1669dd42e2b4e4731ea2b91dfbfd1a6d
Author: Eyal <109809+eyal0 at users.noreply.github.com>
Date:   Wed Feb 3 21:14:25 2021 -0700

    Remove autotools configuration instructions
    
    autotools configuration was already removed in 29802a665505aa5fa00f942754d6d16ddfed5823

diff --git a/INSTALL b/INSTALL
index e9ea10a..c9895a8 100644
--- a/INSTALL
+++ b/INSTALL
@@ -7,24 +7,7 @@ compiler.
 
 ### Unix
 
-GEOS can be built on Unix systems using either the autotools or CMake build
-systems.
-
-#### Using Autotools:
-
-When building GEOS using autotools, a `configure` script must first be generated
-using the `autogen.sh` file included in the root of the repository:
-
-    ./autogen.sh
-
-An out-of-tree build can then be initiated by creating a subdirectory and
-running the generated `configure` script from that subdirectory:
-
-    mkdir obj && cd obj && ../configure
-
-Once the `configure` script has run, GEOS can be built by running `make` and
-installed by running `make install`. The test suite can be run using `make
-check`.
+GEOS can be built on Unix systems using the CMake build system.
 
 #### Using CMake:
 

commit 77663b3d32d677e873cf5dec9cc7c3c94476e7f6
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed Feb 3 20:15:35 2021 -0500

    Fix MSVC build

diff --git a/include/geos/geom/util/GeometryCombiner.h b/include/geos/geom/util/GeometryCombiner.h
index 44da3de..dbe06a6 100644
--- a/include/geos/geom/util/GeometryCombiner.h
+++ b/include/geos/geom/util/GeometryCombiner.h
@@ -22,6 +22,8 @@
 #include <memory>
 #include <vector>
 
+#include <geos/export.h>
+
 // Forward declarations
 namespace geos {
 namespace geom {
@@ -46,7 +48,7 @@ namespace util { // geos.geom.util
  *
  * @see GeometryFactory#buildGeometry
  */
-class GeometryCombiner {
+class GEOS_DLL GeometryCombiner {
 public:
     /** \brief
      * Copies a collection of geometries and combines the result.

commit b7bcd68145a5bcdd2c56a91352aa4bb59f06d8c1
Author: Daniel Baston <dbaston at gmail.com>
Date:   Wed Feb 3 17:32:09 2021 -0500

    Enable GeometryCombiner to consume its inputs
    
    Add test cases and make "skipEmpty" flag settable.

diff --git a/include/geos/geom/GeometryFactory.h b/include/geos/geom/GeometryFactory.h
index 9953e70..23d74c3 100644
--- a/include/geos/geom/GeometryFactory.h
+++ b/include/geos/geom/GeometryFactory.h
@@ -353,7 +353,7 @@ public:
     //
     /// Will clone the geometries accessible trough the iterator.
     ///
-    /// @tparam T an iterator yelding something which casts to const Geometry*
+    /// @tparam T an iterator yielding something which casts to const Geometry*
     /// @param from start iterator
     /// @param toofar end iterator
     ///
diff --git a/include/geos/geom/util/GeometryCombiner.h b/include/geos/geom/util/GeometryCombiner.h
index 3faf21b..44da3de 100644
--- a/include/geos/geom/util/GeometryCombiner.h
+++ b/include/geos/geom/util/GeometryCombiner.h
@@ -49,16 +49,23 @@ namespace util { // geos.geom.util
 class GeometryCombiner {
 public:
     /** \brief
-     * Combines a collection of geometries.
+     * Copies a collection of geometries and combines the result.
      *
      * @param geoms the geometries to combine (ownership left to caller)
      * @return the combined geometry
      */
     static std::unique_ptr<Geometry> combine(std::vector<const Geometry*> const& geoms);
-    static std::unique_ptr<Geometry> combine(std::vector<std::unique_ptr<Geometry>> const& geoms);
 
     /** \brief
-     * Combines two geometries.
+     * Combines a collection of geometries.
+     *
+     * @param geoms the geometries to combine (ownership transferred to combined geometry)
+     * @return the combined geometry
+     */
+    static std::unique_ptr<Geometry> combine(std::vector<std::unique_ptr<Geometry>> && geoms);
+
+    /** \brief
+     * Copies two geometries and combines the result.
      *
      * @param g0 a geometry to combine (ownership left to caller)
      * @param g1 a geometry to combine (ownership left to caller)
@@ -67,7 +74,17 @@ public:
     static std::unique_ptr<Geometry> combine(const Geometry* g0, const Geometry* g1);
 
     /** \brief
-     * Combines three geometries.
+     * Combines two geometries.
+     *
+     * @param g0 a geometry to combine (ownership transferred to combined geometry)
+     * @param g1 a geometry to combine (ownership transferred to combined geometry)
+     * @return the combined geometry
+     */
+    static std::unique_ptr<Geometry> combine(std::unique_ptr<Geometry> && g0,
+                                             std::unique_ptr<Geometry> && g1);
+
+    /** \brief
+     * Copies three geometries and combines the result.
      *
      * @param g0 a geometry to combine (ownership left to caller)
      * @param g1 a geometry to combine (ownership left to caller)
@@ -76,10 +93,21 @@ public:
      */
     static std::unique_ptr<Geometry> combine(const Geometry* g0, const Geometry* g1, const Geometry* g2);
 
+    /** \brief
+     * Combines three geometries.
+     *
+     * @param g0 a geometry to combine (ownership transferred to combined geometry)
+     * @param g1 a geometry to combine (ownership transferred to combined geometry)
+     * @param g2 a geometry to combine (ownership transferred to combined geometry)
+     * @return the combined geometry
+     */
+    static std::unique_ptr<Geometry> combine(std::unique_ptr<Geometry> && g0,
+                                             std::unique_ptr<Geometry> && g1,
+                                             std::unique_ptr<Geometry> && g2);
+
 private:
-    GeometryFactory const* geomFactory;
+    std::vector<std::unique_ptr<Geometry>> inputGeoms;
     bool skipEmpty;
-    std::vector<const Geometry*> const& inputGeoms;
 
 public:
     /** \brief
@@ -87,15 +115,16 @@ public:
      *
      * @param geoms the geometries to combine
      */
-    GeometryCombiner(std::vector<const Geometry*> const& geoms);
+    explicit GeometryCombiner(std::vector<const Geometry*> const& geoms);
+
+    explicit GeometryCombiner(std::vector<std::unique_ptr<Geometry>> && geoms);
 
     /** \brief
      * Extracts the GeometryFactory used by the geometries in a collection.
      *
-     * @param geoms
      * @return a GeometryFactory
      */
-    static GeometryFactory const* extractFactory(std::vector<const Geometry*> const& geoms);
+    GeometryFactory const* extractFactory() const;
 
     /** \brief
      * Computes the combination of the input geometries
@@ -105,8 +134,10 @@ public:
      */
     std::unique_ptr<Geometry> combine();
 
-private:
-    void extractElements(const Geometry* geom, std::vector<const Geometry*>& elems);
+    /** \brief
+     * Set a flag indicating that empty geometries should be omitted from the result.
+     */
+    void setSkipEmpty(bool);
 
     // Declare type as noncopyable
     GeometryCombiner(const GeometryCombiner& other) = delete;
diff --git a/src/geom/util/GeometryCombiner.cpp b/src/geom/util/GeometryCombiner.cpp
index d99c350..3a5b174 100644
--- a/src/geom/util/GeometryCombiner.cpp
+++ b/src/geom/util/GeometryCombiner.cpp
@@ -19,20 +19,15 @@
 #include <geos/geom/util/GeometryCombiner.h>
 #include <geos/geom/Geometry.h>
 #include <geos/geom/GeometryFactory.h>
-#include <geos/geom/GeometryCollection.h>
 
 namespace geos {
 namespace geom { // geos.geom
 namespace util { // geos.geom.util
 
 std::unique_ptr<Geometry>
-GeometryCombiner::combine(std::vector<std::unique_ptr<Geometry>> const& geoms)
+GeometryCombiner::combine(std::vector<std::unique_ptr<Geometry>>&& geoms)
 {
-    std::vector<const Geometry*> geomptrs;
-    for(const auto& g : geoms) {
-        geomptrs.push_back(g.get());
-    }
-    GeometryCombiner combiner(geomptrs);
+    GeometryCombiner combiner(std::move(geoms));
     return combiner.combine();
 }
 
@@ -55,6 +50,30 @@ GeometryCombiner::combine(const Geometry* g0, const Geometry* g1)
 }
 
 std::unique_ptr<Geometry>
+GeometryCombiner::combine(std::unique_ptr<Geometry> && g0,
+                          std::unique_ptr<Geometry> && g1)
+{
+    std::vector<std::unique_ptr<Geometry>> geoms(2);
+    geoms[0] = std::move(g0);
+    geoms[1] = std::move(g1);
+    GeometryCombiner combiner(std::move(geoms));
+    return combiner.combine();
+}
+
+std::unique_ptr<Geometry>
+GeometryCombiner::combine(std::unique_ptr<Geometry> && g0,
+                          std::unique_ptr<Geometry> && g1,
+                          std::unique_ptr<Geometry> && g2)
+{
+    std::vector<std::unique_ptr<Geometry>> geoms(3);
+    geoms[0] = std::move(g0);
+    geoms[1] = std::move(g1);
+    geoms[2] = std::move(g2);
+    GeometryCombiner combiner(std::move(geoms));
+    return combiner.combine();
+}
+
+std::unique_ptr<Geometry>
 GeometryCombiner::combine(const Geometry* g0, const Geometry* g1,
                           const Geometry* g2)
 {
@@ -67,51 +86,47 @@ GeometryCombiner::combine(const Geometry* g0, const Geometry* g1,
     return combiner.combine();
 }
 
-GeometryCombiner::GeometryCombiner(std::vector<const Geometry*> const& geoms)
-    : geomFactory(extractFactory(geoms)), skipEmpty(false), inputGeoms(geoms)
+GeometryCombiner::GeometryCombiner(std::vector<const Geometry*> const& geoms) : skipEmpty(false)
 {
+    for(const auto& geom : geoms) {
+        for (std::size_t i = 0; i < geom->getNumGeometries(); i++) {
+            auto part = geom->getGeometryN(i);
+            inputGeoms.push_back(part->clone());
+        }
+    }
 }
 
-GeometryFactory const*
-GeometryCombiner::extractFactory(std::vector<const Geometry*> const& geoms)
+GeometryCombiner::GeometryCombiner(std::vector<std::unique_ptr<Geometry>> && geoms) : skipEmpty(false)
 {
-    return geoms.empty() ? nullptr : geoms.front()->getFactory();
+    for(auto& geom : geoms) {
+        auto coll = dynamic_cast<GeometryCollection *>(geom.get());
+        if (coll) {
+            for (auto &part : coll->releaseGeometries()) {
+                inputGeoms.push_back(std::move(part));
+            }
+        } else {
+            inputGeoms.push_back(std::move(geom));
+        }
+    }
 }
 
 std::unique_ptr<Geometry>
 GeometryCombiner::combine()
 {
-    std::vector<const Geometry*> elems;
+    auto geomFactory = inputGeoms.empty() ? GeometryFactory::getDefaultInstance() : inputGeoms.front()->getFactory();
 
-    for(const auto& geom : inputGeoms) {
-        extractElements(geom, elems);
-    }
-
-    if(elems.empty()) {
-        if(geomFactory != nullptr) {
-            return std::unique_ptr<Geometry>(geomFactory->createGeometryCollection());
-        }
-        return nullptr;
+    if (skipEmpty) {
+        inputGeoms.erase(std::remove_if(inputGeoms.begin(), inputGeoms.end(), [](std::unique_ptr<Geometry> & g) {
+            return g->isEmpty();
+        }), inputGeoms.end());
     }
 
     // return the "simplest possible" geometry
-    return std::unique_ptr<Geometry>(geomFactory->buildGeometry(elems));
+    return geomFactory->buildGeometry(std::move(inputGeoms));
 }
 
-void
-GeometryCombiner::extractElements(const Geometry* geom, std::vector<const Geometry*>& elems)
-{
-    if(geom == nullptr) {
-        return;
-    }
-
-    for(std::size_t i = 0; i < geom->getNumGeometries(); ++i) {
-        const Geometry* elemGeom = geom->getGeometryN(i);
-        if(skipEmpty && elemGeom->isEmpty()) {
-            continue;
-        }
-        elems.push_back(elemGeom);
-    }
+void GeometryCombiner::setSkipEmpty(bool b) {
+    skipEmpty = b;
 }
 
 } // namespace geos.geom.util
diff --git a/src/operation/union/OverlapUnion.cpp b/src/operation/union/OverlapUnion.cpp
index 7e21ed2..c17e06c 100644
--- a/src/operation/union/OverlapUnion.cpp
+++ b/src/operation/union/OverlapUnion.cpp
@@ -84,7 +84,7 @@ OverlapUnion::combine(std::unique_ptr<Geometry>& unionGeom, std::vector<std::uni
         return std::move(unionGeom);
 
     disjointPolys.push_back(std::move(unionGeom));
-    return GeometryCombiner::combine(disjointPolys);
+    return GeometryCombiner::combine(std::move(disjointPolys));
 }
 
 /* private */
diff --git a/tests/unit/geom/util/GeometryCombinerTest.cpp b/tests/unit/geom/util/GeometryCombinerTest.cpp
new file mode 100644
index 0000000..7ec489b
--- /dev/null
+++ b/tests/unit/geom/util/GeometryCombinerTest.cpp
@@ -0,0 +1,125 @@
+//
+// Test Suite for geos::geom::util::GeometryCombiner class.
+
+// tut
+#include <tut/tut.hpp>
+// geos
+#include <geos/io/WKTReader.h>
+#include <geos/geom/util/GeometryCombiner.h>
+
+#include <utility.h>
+// std
+#include <vector>
+
+namespace tut {
+//
+// Test Group
+//
+
+// Common data used by tests
+struct test_geometrycombiner_data {
+    using GeometryCombiner = geos::geom::util::GeometryCombiner;
+
+    geos::io::WKTReader wktreader_;
+};
+
+typedef test_group<test_geometrycombiner_data> group;
+typedef group::object object;
+
+group test_geometrycombiner_group("geos::geom::util::GeometryCombiner");
+
+// Two-argument version
+template<>
+template<>
+void object::test<1>(){
+    auto g1 = wktreader_.read("POINT (1 1)");
+    auto g2 = wktreader_.read("POINT (2 2)");
+
+    auto result_via_copy = GeometryCombiner::combine(g1.get(), g2.get());
+    ensure_equals_geometry(result_via_copy.get(), "MULTIPOINT ((1 1), (2 2))");
+
+    auto result_via_move = GeometryCombiner::combine(std::move(g1), std::move(g2));
+    ensure_equals_geometry(result_via_move.get(), result_via_copy.get());
+}
+
+// Three-argument version
+template<>
+template<>
+void object::test<2>(){
+    auto g1 = wktreader_.read("POINT (1 1)");
+    auto g2 = wktreader_.read("POINT (2 2)");
+    auto g3 = wktreader_.read("LINESTRING (3 3, 4 4)");
+
+    auto result_via_copy = GeometryCombiner::combine(g1.get(), g2.get(), g3.get());
+    ensure_equals_geometry(result_via_copy.get(), "GEOMETRYCOLLECTION (POINT (1 1), POINT (2 2), LINESTRING (3 3, 4 4))");
+
+    auto result_via_move = GeometryCombiner::combine(std::move(g1), std::move(g2), std::move(g3));
+    ensure_equals_geometry(result_via_move.get(), result_via_copy.get());
+}
+
+// Vector version
+template<>
+template<>
+void object::test<3>() {
+    std::vector<std::unique_ptr<geos::geom::Geometry>> geoms;
+    geoms.push_back(wktreader_.read("POINT (1 1)"));
+    geoms.push_back(wktreader_.read("POLYGON EMPTY"));
+    geoms.push_back(wktreader_.read("POINT (2 2)"));
+
+    GeometryCombiner gc(std::move(geoms));
+    gc.setSkipEmpty(true);
+
+    auto result = gc.combine();
+
+    ensure_equals_geometry(result.get(), "MULTIPOINT ((1 1), (2 2))");
+}
+
+// Outermost level of GeometryCollection is collapsed
+template<>
+template<>
+void object::test<4>() {
+    auto g1 = wktreader_.read("MULTIPOINT ((1 1), (2 2))");
+    auto g2 = wktreader_.read("MULTILINESTRING ((3 3, 4 4), (5 5, 6 6))");
+
+    auto result_via_copy = GeometryCombiner::combine(g1->clone(), g2->clone());
+    ensure_equals_geometry(result_via_copy.get(), "GEOMETRYCOLLECTION("
+                                                  "POINT (1 1),"
+                                                  "POINT (2 2),"
+                                                  "LINESTRING (3 3, 4 4),"
+                                                  "LINESTRING (5 5, 6 6))");
+
+    auto result_via_move = GeometryCombiner::combine(std::move(g1), std::move(g2));
+    ensure_equals_geometry(result_via_move.get(), result_via_copy.get());
+}
+
+// Test behavior when only empty inputs provided
+template<>
+template<>
+void object::test<5>()
+{
+    std::vector<std::unique_ptr<geos::geom::Geometry>> geoms;
+    geoms.emplace_back(wktreader_.read("POINT EMPTY"));
+
+    GeometryCombiner gc(std::move(geoms));
+    gc.setSkipEmpty(true);
+
+    auto result = gc.combine();
+
+    ensure_equals_geometry(result.get(), "GEOMETRYCOLLECTION EMPTY");
+}
+
+// Test behavior when no inputs provided
+template<>
+template<>
+void object::test<6>()
+{
+    std::vector<const geos::geom::Geometry*> geoms;
+    GeometryCombiner gc(geoms);
+
+    auto result = gc.combine();
+
+    ensure_equals_geometry(result.get(), "GEOMETRYCOLLECTION EMPTY");
+}
+
+
+} // namespace tut
diff --git a/tests/unit/utility.h b/tests/unit/utility.h
index d239a76..12e3c47 100644
--- a/tests/unit/utility.h
+++ b/tests/unit/utility.h
@@ -125,6 +125,7 @@ ensure_equals_geometry(T1 const* lhs, T2 const* rhs)
     ensure(lhs != 0 && rhs != 0 && lhs != rhs);
 }
 
+
 template <typename T>
 inline void
 ensure_equals_geometry(T const* lhs_in, T const* rhs_in, double tolerance = 0.0)
@@ -189,7 +190,21 @@ ensure_equals_geometry(T const* lhs_in, T const* rhs_in, double tolerance = 0.0)
     // }
 }
 
+template<typename T>
+inline void
+ensure_equals_geometry(const T& lhs, const char* rhs, double tolerance = 0.0) {
+    geos::io::WKTReader reader(lhs->getFactory());
+    auto rhs_geom = reader.read(rhs);
+    ensure_equals_geometry(lhs, rhs_geom.get(), tolerance);
+}
 
+template<typename T>
+inline void
+ensure_equals_geometry(const T& lhs, const std::string& rhs, double tolerance = 0.0) {
+    geos::io::WKTReader reader(lhs->getFactory());
+    auto rhs_geom = reader.read(rhs);
+    ensure_equals_geometry(lhs, rhs_geom.get(), tolerance);
+}
 
 template <>
 inline void

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

Summary of changes:
 INSTALL                                       |  19 +---
 include/geos/geom/GeometryFactory.h           |   2 +-
 include/geos/geom/util/GeometryCombiner.h     |  57 +++++++++---
 src/geom/util/GeometryCombiner.cpp            |  89 ++++++++++--------
 src/operation/union/OverlapUnion.cpp          |   2 +-
 tests/unit/geom/util/GeometryCombinerTest.cpp | 125 ++++++++++++++++++++++++++
 tests/unit/utility.h                          |  15 ++++
 7 files changed, 240 insertions(+), 69 deletions(-)
 create mode 100644 tests/unit/geom/util/GeometryCombinerTest.cpp


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list