[geos-commits] [SCM] GEOS branch master updated. c771461c6caa6d7e2daad88b1ac64f9949cea80f

git at osgeo.org git at osgeo.org
Fri Nov 27 14:18:38 PST 2020


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  c771461c6caa6d7e2daad88b1ac64f9949cea80f (commit)
      from  1502648acea4405b1923d23be70d33bdf115cd63 (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 c771461c6caa6d7e2daad88b1ac64f9949cea80f
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Fri Nov 27 14:18:03 2020 -0800

    Implement SimpleSTRtree::remove() for final piece of compatibility
    with origin STRtree implementation.

diff --git a/include/geos/index/strtree/SimpleSTRnode.h b/include/geos/index/strtree/SimpleSTRnode.h
index 909de7b..426f787 100644
--- a/include/geos/index/strtree/SimpleSTRnode.h
+++ b/include/geos/index/strtree/SimpleSTRnode.h
@@ -67,6 +67,9 @@ public:
 
     void toString(std::ostream& os, int indentLevel) const;
 
+    std::size_t getNumNodes() const;
+    std::size_t getNumLeafNodes() const;
+
     const std::vector<SimpleSTRnode*>&
     getChildNodes() const
     {
@@ -77,6 +80,9 @@ public:
         return item;
     }
 
+    bool removeItem(void *item);
+    bool removeChild(SimpleSTRnode *child);
+
     /**
      * Returns a representation of space that encloses this Node
      */
diff --git a/include/geos/index/strtree/SimpleSTRtree.h b/include/geos/index/strtree/SimpleSTRtree.h
index 6baa271..c01bd5e 100644
--- a/include/geos/index/strtree/SimpleSTRtree.h
+++ b/include/geos/index/strtree/SimpleSTRtree.h
@@ -106,6 +106,8 @@ private:
         std::vector<SimpleSTRnode*>& childNodes,
         int newLevel);
 
+    bool remove(const geom::Envelope* searchBounds, SimpleSTRnode* node, void* item);
+
 
 public:
 
@@ -124,9 +126,11 @@ public:
     }
 
     std::size_t getNumLeafNodes() const {
-        return nodes.size();
+        return root->getNumLeafNodes();
     }
 
+
+
     bool getBuilt() const {
         return built;
     }
@@ -146,7 +150,7 @@ public:
 
     void query(const geom::Envelope* searchEnv, ItemVisitor& visitor) override;
 
-    bool remove(const geom::Envelope* itemEnv, void* item) override;
+    bool remove(const geom::Envelope* searchBounds, void* item) override;
 
     friend std::ostream& operator<<(std::ostream& os, const SimpleSTRtree& tree);
 
diff --git a/src/index/strtree/SimpleSTRnode.cpp b/src/index/strtree/SimpleSTRnode.cpp
index a11ca3e..ee66664 100644
--- a/src/index/strtree/SimpleSTRnode.cpp
+++ b/src/index/strtree/SimpleSTRnode.cpp
@@ -15,6 +15,7 @@
 #include <geos/index/strtree/SimpleSTRnode.h>
 #include <geos/geom/Envelope.h>
 
+#include <iostream>
 
 using namespace geos::geom;
 
@@ -48,6 +49,54 @@ SimpleSTRnode::addChildNode(SimpleSTRnode* childNode)
     childNodes.push_back(childNode);
 }
 
+/*public*/
+std::size_t
+SimpleSTRnode::getNumNodes() const
+{
+    std::size_t count = 1;
+    if (isLeaf())
+        return count;
+
+    for (auto* node: getChildNodes())
+        count += node->getNumNodes();
+
+    return count;
+}
+
+/*public*/
+std::size_t
+SimpleSTRnode::getNumLeafNodes() const
+{
+    std::size_t count = isLeaf() ? 1 : 0;
+    for (auto* node: getChildNodes())
+        count += node->getNumLeafNodes();
+    return count;
+}
+
+bool
+SimpleSTRnode::removeItem(void *item)
+{
+    for (auto it = childNodes.begin(); it != childNodes.end(); ++it) {
+        if ((*it)->getItem() == item) {
+            childNodes.erase(it);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+SimpleSTRnode::removeChild(SimpleSTRnode *child)
+{
+    for (auto it = childNodes.begin(); it != childNodes.end(); ++it) {
+        if ((*it) == child) {
+            childNodes.erase(it);
+            return true;
+        }
+    }
+    return false;
+}
+
 
 
 } // namespace geos.index.strtree
diff --git a/src/index/strtree/SimpleSTRtree.cpp b/src/index/strtree/SimpleSTRtree.cpp
index f922e4e..9d60adc 100644
--- a/src/index/strtree/SimpleSTRtree.cpp
+++ b/src/index/strtree/SimpleSTRtree.cpp
@@ -268,14 +268,47 @@ SimpleSTRtree::query(const geom::Envelope* searchEnv,
 
 /* public */
 bool
-SimpleSTRtree::remove(const geom::Envelope* itemEnv, void* item)
+SimpleSTRtree::remove(const geom::Envelope* searchBounds, void* item)
 {
-    ::geos::ignore_unused_variable_warning(itemEnv);
-    ::geos::ignore_unused_variable_warning(item);
-    assert(false);
+    build();
+    if(root->getEnvelope().intersects(searchBounds)) {
+        return remove(searchBounds, root, item);
+    }
     return false;
 }
 
+/* private */
+bool
+SimpleSTRtree::remove(const geom::Envelope* searchBounds,
+    SimpleSTRnode* node, void* item)
+{
+    bool found = node->removeItem(item);
+    if (found)
+        return true;
+
+    SimpleSTRnode* childToPrune = nullptr;
+    auto childNodes = node->getChildNodes();
+    for (auto* child: childNodes) {
+        if (! searchBounds->intersects(child->getEnvelope())) {
+            continue;
+        }
+        if (!child->isLeaf()) {
+            found = remove(searchBounds, child, item);
+            if (found) {
+                childToPrune = child;
+                break;
+            }
+        }
+    }
+    if (childToPrune != nullptr) {
+        // Only remove empty child nodes
+        if (childToPrune->getChildNodes().empty()) {
+            node->removeChild(childToPrune);
+        }
+    }
+    return found;
+}
+
 
 /*public static*/
 std::ostream&
diff --git a/tests/unit/index/strtree/SimpleSTRtreeTest.cpp b/tests/unit/index/strtree/SimpleSTRtreeTest.cpp
index 5bae49b..5c7d239 100644
--- a/tests/unit/index/strtree/SimpleSTRtreeTest.cpp
+++ b/tests/unit/index/strtree/SimpleSTRtreeTest.cpp
@@ -6,6 +6,7 @@
 #include <geos/index/strtree/SimpleSTRtree.h>
 #include <geos/index/strtree/GeometryItemDistance.h>
 #include <geos/index/ItemVisitor.h>
+#include <geos/io/WKTReader.h>
 
 
 using namespace geos;
@@ -114,5 +115,42 @@ void object::test<2>
 }
 
 
+template<>
+template<>
+void object::test<3>
+()
+{
+    auto gf = geom::GeometryFactory::create();
+    geos::io::WKTReader wkt(*gf);
+    index::strtree::SimpleSTRtree t(10);
+    std::vector<std::unique_ptr<geom::Geometry>> geoms;
+    geoms.emplace_back(wkt.read(std::string("LINESTRING(0 0, 10 10)")).release());
+    geoms.emplace_back(wkt.read(std::string("LINESTRING(5 5, 15 15)")).release());
+    geoms.emplace_back(wkt.read(std::string("LINESTRING(10 10, 20 20)")).release());
+    geoms.emplace_back(wkt.read(std::string("LINESTRING(15 15, 25 25)")).release());
+
+    for (auto& g: geoms) {
+        t.insert(g.get());
+    }
+
+    std::size_t leaf_before = t.getRoot()->getNumLeafNodes();
+    // std::cout << "leaf_before " << leaf_before << std::endl;
+    std::size_t all_before = t.getRoot()->getNumNodes();
+    // std::cout << "all_before " << all_before << std::endl;
+    ensure(leaf_before = 4u);
+    ensure(all_before  = 5u);
+
+    t.remove(geoms[3]->getEnvelopeInternal(), geoms[3].get());
+
+    std::size_t leaf_after = t.getRoot()->getNumLeafNodes();
+    // std::cout << "leaf_after " << leaf_after << std::endl;
+    std::size_t all_after = t.getRoot()->getNumNodes();
+    // std::cout << "all_after " << all_after << std::endl;
+    ensure(leaf_after = 3u);
+    ensure(all_after  = 4u);
+}
+
+
+
 } // namespace tut
 

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

Summary of changes:
 include/geos/index/strtree/SimpleSTRnode.h     |  6 ++++
 include/geos/index/strtree/SimpleSTRtree.h     |  8 +++--
 src/index/strtree/SimpleSTRnode.cpp            | 49 ++++++++++++++++++++++++++
 src/index/strtree/SimpleSTRtree.cpp            | 41 ++++++++++++++++++---
 tests/unit/index/strtree/SimpleSTRtreeTest.cpp | 38 ++++++++++++++++++++
 5 files changed, 136 insertions(+), 6 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list