我正在尝试在我的某个项目中使用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;
}
答案 0 :(得分:1)
如果将范围传递给R树的构造函数,则使用打包算法:
可以使用query
方法或查询迭代器来检索R树中的值:
最后一句话。在您的代码中,您将点数传递到bgi::dynamic_rstar
。 bgi::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;
}