使用几何中的boost rtree查找结果点

时间:2017-04-09 06:02:58

标签: c++ boost geometry c++14 boost-geometry

我正在尝试在我的某个项目中使用boost::geometry的rtree DS,但我发现很难浏览文档。某些方法记录很少,我找不到足够的例子。现在我正在尝试构建一个示例程序,以便我可以进一步构建它。

所以,在下面的例子中,我有一个点和一个盒子,我需要找到那个盒子里面的所有点。我想问的另一件事是,我找不到packing algorithm构造函数或方法,所以如何使用它。这是我到目前为止所做的事情 -

#include <iostream>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/box.hpp>
#include <boost/geometry/index/rtree.hpp>


namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;


struct my_point
{
    float x, y;
    my_point(float _x, float _y) : x(_x), y(_y) {}
};

struct my_box
{
    my_point ll, ur;
    my_box(float x1, float y1, float x2, float y2) : ll(x1,y1), ur(x2,y2) {}
};

// Register the point type
BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, float, cs::cartesian, x, y)

// Register the box type, also notifying that it is based on "my_point"
BOOST_GEOMETRY_REGISTER_BOX(my_box, my_point, ll, ur)



int main()
{
    std::vector<std::pair<my_point, int>> pts;
    pts.emplace_back(std::make_pair(my_point(2,2), 5));
    pts.emplace_back(std::make_pair(my_point(3,3), 1));
    pts.emplace_back(std::make_pair(my_point(4,5), 3));
    pts.emplace_back(std::make_pair(my_point(4,4), 12));
    pts.emplace_back(std::make_pair(my_point(1,2), 50));
    // ....

    bgi::rtree<std::pair<my_point, int>, bgi::dynamic_rstar> rT(bgi::dynamic_rstar(pts.size()));
    rT.insert(pts.begin(), pts.end());

    my_box box1(1,1,4,4);
    // how to retrieve all points or their .second inside this box?

    return 0;
}

2 个答案:

答案 0 :(得分:1)

如果将范围传递给R树的构造函数,则使用打包算法:

可以使用query方法或查询迭代器来检索R树中的值:

另见R-tree Quick Start example

最后一句话。在您的代码中,您将点数传递到bgi::dynamic_rstarbgi::dynamic_rstar的参数不是包含值的数量。它是存储在R树的单个节点中的最大值数(对应于持久性/基于磁盘的R树的页面大小)。因此,如果你传递bgi::dynamic_rstar(pts.size()),R树只包含一个包含所有点的节点,这意味着没有节点层次结构,没有空间划分,有效的rtree就像一个向量。而是使用例如如果值重叠,bgi::rstar<4>或更大的数字很大,但在您的情况下,它不应该存储点。这就够了:

bgi::rtree<std::pair<my_point, int>, bgi::rstar<4> > rT(pts);

答案 1 :(得分:0)

您需要在rtree上使用query方法并传递适当的查询策略,例如 -

std::vector<std::pair<my_point, int>> result;
rT.query(bgi::covered_by(box1), std::back_inserter(result));

对于打包算法,虽然我不确定但这应该有效 -

bgi::rtree<std::pair<my_point, int>, bgi::dynamic_rstar> rT(pts, bgi::dynamic_rstar(pts.size()));

但是,我建议根据文档对其进行验证。这是我在我的机器上本地测试的完整程序 -

#include <iostream>
#include <vector>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometries/register/box.hpp>
#include <boost/geometry/index/rtree.hpp>


namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;


struct my_point
{
    float x, y;
    my_point(float _x, float _y) : x(_x), y(_y) {}
};

struct my_box
{
    my_point ll, ur;
    my_box(float x1, float y1, float x2, float y2) : ll(x1,y1), ur(x2,y2) {}
};

// Register the point type
BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, float, cs::cartesian, x, y)

// Register the box type, also notifying that it is based on "my_point"
BOOST_GEOMETRY_REGISTER_BOX(my_box, my_point, ll, ur)



int main()
{
    std::vector<std::pair<my_point, int>> pts;
    pts.emplace_back(std::make_pair(my_point(2,2), 5));
    pts.emplace_back(std::make_pair(my_point(3,3), 1));
    pts.emplace_back(std::make_pair(my_point(4,5), 3));
    pts.emplace_back(std::make_pair(my_point(4,4), 12));
    pts.emplace_back(std::make_pair(my_point(1,2), 50));
    // ....

    bgi::rtree<std::pair<my_point, int>, bgi::dynamic_rstar> rT(pts, bgi::dynamic_rstar(pts.size()));

    my_box box1(1,1,4,4);
    std::vector<std::pair<my_point, int>> result;
    rT.query(bgi::covered_by(box1), std::back_inserter(result));
    for(const auto &r: result){
        std::cout << r.second << ' ' << '\n';
    }
    return 0;
}