【问题标题】:How to iterate over a boost R-tree?如何迭代boost R-tree?
【发布时间】:2015-01-18 04:02:46
【问题描述】:

我似乎找不到一种有效的方法来迭代 boost R-tree (boost::geometry::index::rtree)。到目前为止,我想出的唯一方法是使用非常大的边界框执行查询,以便在向量中返回所有元素的副本,但这显然既不节省空间也不节省时间。理想情况下,我只想使用 STL 风格的迭代器以通常的方式迭代树,但这似乎不可能?

【问题讨论】:

  • 我猜如果你查询一个大的边界框,例如 bounds() 并使用 qbegin()qend() 它会节省空间和时间。如果您的框很大,则树使用根节点。然后,它以线性时间遍历树。
  • 知道了 - 谢谢 - 我对 qbeginqend 做了一个错误的假设,我想我现在看得更清楚了。

标签: c++ boost iterator boost-geometry r-tree


【解决方案1】:

自 1.59.0 起

begin()end() 成员函数在bgi::rtree 中定义,返回一个const_iterator。因此,可以在没有下面描述的技术的情况下迭代所有元素。在 C++11 中:

for(auto const& v: rtree)
    /* do something with v */

1.59.0 之前

正如其他人所说,要遍历存储在 rtree 中的所有元素,您可以使用查询迭代器。但是,不需要执行实际的空间查询(通过边界等)。你可以传递一个虚拟的 UnaryPredicate 总是返回 true 包裹 bgi::satisfies()。在 C++11 中:

std::for_each(rtree.qbegin(bgi::satisfies([](Value const&){ return true; })),
              rtree.qend(),
              [](Value const& v){
                  /* do something with v */
              });

非迭代查询也可以用于此目的,但它需要一个特殊的输出迭代器,例如boost::function_output_iteratorBoost.Iterator 库中实现(参见 http://www.boost.org/doc/libs/1_57_0/libs/iterator/doc/function_output_iterator.html)。在 C++11 中:

rtree.query(bgi::satisfies([](Value const&){ return true; }),
            boost::make_function_output_iterator([](Value const& v){
                /* do something with v */
            }));

旁注:

  • 以上代码需要Boost.Geometry文档中提到的库头
  • namespace bgi = boost::geometry::index
  • Value 是存储在bgi::rtree 中的一类对象
  • boost::function_output_iterator 需要 #include <boost/function_output_iterator.hpp>
  • 在 C++14 中可以使用通用 lambda,那么上面的代码将与值类型无关

【讨论】:

  • 谢谢 - 这看起来像是一个潜在有用的优化。
【解决方案2】:

如果您的查询包含要迭代的所有元素,则不必执行查询将其全部放入向量中,但可以使用 qbeginqend 来迭代直接元素。捕获所有元素的必要边界可以从bounds获得。

【讨论】:

  • 啊哈 - 谢谢 - 我想我假设我需要先执行查询才能获得 qbegin 和 qend 但我想我现在知道该怎么做了。
猜你喜欢
  • 2014-10-10
  • 1970-01-01
  • 2020-01-25
  • 2010-11-11
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-17
相关资源
最近更新 更多