2017-04-09 109 views
4

我試圖在我的一個項目上使用boost::geometry的rtree DS,但我發現很難瀏覽文檔。某些方法記錄不完善,我找不到足夠的例子。現在我正在嘗試構建一個示例程序,以便我可以進一步構建它。在幾何圖形中使用boost rtree查找結果點

因此,在下面的例子中,我有一個點和一個盒子,我需要找到那個盒子裏面的所有點。我想問的另一件事是,我找不到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; 
} 

回答

4

您需要使用您的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())); 

但是,我會建議對照文檔進行驗證。下面是我在我的機器上本地測試完整的程序 - 如果你傳遞一個範圍內進入R樹的構造

#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; 
} 
1

包裝算法用於:

從R-tree中檢索值可以用query方法或查詢迭代器完成:

另見本R-tree Quick Start example

最後一句話。在你的代碼中,你將點數傳遞給bgi::dynamic_rstarbgi::dynamic_rstar的參數不是包含值的數量。它是存儲在R-tree的單個節點中的值的最大數量(對應於基於持久性/基於磁盤的R樹的頁面大小)。所以如果你通過bgi::dynamic_rstar(pts.size()) R樹只包含一個包含所有點的節點,這意味着沒有節點層次結構,沒有空間分割,並且有效地使得rtree的行爲像一個向量。使用例如bgi::rstar<4>或更大的數字,如果價值重疊很大,但在你的情況下,它不應該因爲你存儲點。這就足夠了:

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