Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+中使用Boost库的Rtree+;?_C++_Database_Boost_Boost Geometry_R Tree - Fatal编程技术网

C++ 如何在C+中使用Boost库的Rtree+;?

C++ 如何在C+中使用Boost库的Rtree+;?,c++,database,boost,boost-geometry,r-tree,C++,Database,Boost,Boost Geometry,R Tree,我被要求编写一个函数,该函数以一个“LatLon”作为输入(LatLon是一个具有两个双精度的类:纬度和经度),并返回到该位置最近交点的ID(int)。我得到的函数可以返回任何交叉点的位置,也可以返回两个位置之间的距离。由于“性能测试”,我的导师建议我将所有交叉点的位置存储在R树中(来自boost库),这样可以更快地找到最近的交叉点,而不是遍历所有交叉点。然而,我只是在学习R-树是如何工作的,我在如何创建R-树方面遇到了困难 问题是,我在网上看到了几个创建R树的例子,但真正让我困惑的是,它们在一

我被要求编写一个函数,该函数以一个“LatLon”作为输入(LatLon是一个具有两个双精度的类:纬度和经度),并返回到该位置最近交点的ID(int)。我得到的函数可以返回任何交叉点的位置,也可以返回两个位置之间的距离。由于“性能测试”,我的导师建议我将所有交叉点的位置存储在R树中(来自boost库),这样可以更快地找到最近的交叉点,而不是遍历所有交叉点。然而,我只是在学习R-树是如何工作的,我在如何创建R-树方面遇到了困难

问题是,我在网上看到了几个创建R树的例子,但真正让我困惑的是,它们在一个构造函数中只使用了两个参数,而不是四个。例如,他们使用:

bgi::rtreertree

其中value_t是一对box和unsigned int,另一个参数是size,但是如果我尝试:

bgi::rtree<点,bgi::二次>相交rtree

当point是一对无符号int和LatLon时,编译器抱怨我没有使用正确的构造函数,它应该有四个参数而不是两个

我在网上读过,发现我应该使用这个构造函数:

rtree(参数类型常量&,可索引获取常量&,值等于常量&,分配器类型常量&)

但是,我不理解每个参数的描述,所以我不知道如何使用这个构造函数。那么,你能帮我理解该怎么做吗?如果可能的话,你能给我举个简单的例子吗?多谢各位

这是拉特伦班。它是只读的,因此我无法修改它:

class LatLon{

public:
LatLon(){}
explicit LatLon(float lat_, float lon_) : m_lat(lat_),m_lon(lon_){}

double lat() const { return m_lat; }
double lon() const { return m_lon; }

private:
float m_lat = std::numeric_limits<float>::quiet_NaN();
float m_lon = std::numeric_limits<float>::quiet_NaN();

friend class boost::serialization::access;
template<class Archive>void serialize(Archive& ar, unsigned int)
    { ar & m_lat & m_lon; }
};

std::ostream& operator<<(std::ostream& os,LatLon);
std::array<LatLon,4> bounds_to_corners(std::pair<LatLon,LatLon> bounds);
class-LatLon{
公众:
LatLon(){}
显式LatLon(float lat_uu,float lon_u):m_lat(lat_u),m_lon(lon_u){
双lat()常量{return m_lat;}
双lon()常量{return m_lon;}
私人:
float m_lat=std::numeric_limits::quiet_NaN();
float m_lon=std::numeric_limits::quiet_NaN();
好友类boost::serialization::access;
templatevoid序列化(存档&ar,未签名int)
{ar&m_lat&m_lon;}
};

std::ostream&operator要将Boost.Geometry中的类型用作受支持的几何图形之一,您必须将此类型调整为Boost.Geometry概念之一。这就是告诉库如何使用这种类型的对象、如何访问坐标、使用哪种坐标系和坐标类型等的方法

在这一点上:

为方便起见,Boost.Geometry提供了宏,在最典型的情况下为您执行此操作:

您的示例有点问题,您的点没有定义setter,只有getter,因此某些操作无法使用它,例如,它不能存储在空间查询(例如
bgi::intersects()
)或非笛卡尔坐标系中的knn查询(
bgi::nearest()
)所需的
bg::model::box
)中因为坐标可以在内部标准化。因此,为了直接使用它,你必须做比通常需要更多的事情

因此,如果我是你,我只需将
bg::model::Point
类型的点存储在R-树中,并在插入之前将
LatLon
转换为该点,然后在执行查询之后再返回

但是如果您真的想在库中使用
LatLon
类,您可以:

  • 从它派生或将它包装为其他类型,在此类型中执行必要的操作,并使用
    REGISTER
    宏(下面的示例)
  • 调整
    LatLon
    手动键入,如下所示:
顺便说一句,如果您不想实现自己的IndexableGetter(rtree的第三个模板参数
rtree
),您必须将该点作为
第一个
类型放在
std::pair
中。下面我假设您要使用
球面坐标系
坐标系。我还假设坐标类型为
float
,因为在您的示例中,这是实际存储在
LatLon
中的坐标类型

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

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

class LatLon
{
public:
    LatLon(){}
    explicit LatLon(float lat_, float lon_) : m_lat(lat_),m_lon(lon_){}

    float lat() const { return m_lat; }
    float lon() const { return m_lon; }

private:
    float m_lat = std::numeric_limits<float>::quiet_NaN();
    float m_lon = std::numeric_limits<float>::quiet_NaN();
};

struct MyLatLon
{
    MyLatLon() {}
    MyLatLon(float lat_, float lon_) : ll(lat_, lon_){}

    float get_lat() const { return ll.lat(); }
    float get_lon() const { return ll.lon(); }
    void set_lat(float v) { ll = LatLon(v, ll.lon()); }
    void set_lon(float v) { ll = LatLon(ll.lat(), v); }

    LatLon ll;
};

BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(MyLatLon, float,
                                         bg::cs::spherical_equatorial<bg::degree>,
                                         get_lon, get_lat, set_lon, set_lat)

int main()
{
    typedef std::pair<MyLatLon, unsigned> point_pair;

    bgi::rtree<point_pair, bgi::quadratic<16>> intersectionRTree;

    intersectionRTree.insert(std::make_pair(MyLatLon(0, 0), 0));
    intersectionRTree.insert(std::make_pair(MyLatLon(2, 2), 1));

    bg::model::box<MyLatLon> b(MyLatLon(1, 1), MyLatLon(3, 3));
    std::vector<point_pair> result1;
    intersectionRTree.query(bgi::intersects(b), std::back_inserter(result1));
    if (! result1.empty())
        std::cout << bg::wkt(result1[0].first) << std::endl;

    std::vector<point_pair> result2;
    intersectionRTree.query(bgi::nearest(MyLatLon(0, 1), 1), std::back_inserter(result2));
    if (! result2.empty())
        std::cout << bg::wkt(result2[0].first) << std::endl;
}
#包括
#包括
#包括
#包括
#包括
#包括
名称空间bg=boost::geometry;
名称空间bgi=boost::geometry::index;
拉特隆级
{
公众:
LatLon(){}
显式LatLon(float lat_uu,float lon_u):m_lat(lat_u),m_lon(lon_u){
float lat()常量{return m_lat;}
float lon()常量{return m_lon;}
私人:
float m_lat=std::numeric_limits::quiet_NaN();
float m_lon=std::numeric_limits::quiet_NaN();
};
结构MyLatron
{
MyLatron(){}
MyLatLon(浮点lat_uuu,浮点lon_uuu):ll(浮点lat_uuu,lon_uuu){
float get_lat()常量{return ll.lat();}
float get_lon()常量{return ll.lon();}
void set_lat(float v){ll=LatLon(v,ll.lon());}
void set_lon(float v){ll=LatLon(ll.lat(),v);}
拉特隆;
};
增强几何、寄存器、点、2D、获取集(MyLatLon、浮点、,
bg::cs::球形赤道,
获取时间,获取时间,设置时间,设置时间)
int main()
{
typedef std::对点对;
bgi::rtree intersectionRTree;
intersectionRTree.insert(std::make_pair(mylaton(0,0,0));
intersectionRTree.insert(std::make_pair(mylaton(2,2,1));
bg::模型::盒子b(MyLatLon(1,1),MyLatLon(3,3));
std::载体结果1;
query(bgi::intersects(b),std::back_插入器(result1));
如果(!result1.empty())

std::cout请阅读。这是。你确定这是编译器抱怨的问题吗?你使用的是你自己的点类型吗?你能用rtree粘贴一段代码吗?你能检查一下吗?我已经添加了代码。
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <iostream>
#include <limits>
#include <vector>

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

class LatLon
{
public:
    LatLon(){}
    explicit LatLon(float lat_, float lon_) : m_lat(lat_),m_lon(lon_){}

    float lat() const { return m_lat; }
    float lon() const { return m_lon; }

private:
    float m_lat = std::numeric_limits<float>::quiet_NaN();
    float m_lon = std::numeric_limits<float>::quiet_NaN();
};

struct MyLatLon
{
    MyLatLon() {}
    MyLatLon(float lat_, float lon_) : ll(lat_, lon_){}

    float get_lat() const { return ll.lat(); }
    float get_lon() const { return ll.lon(); }
    void set_lat(float v) { ll = LatLon(v, ll.lon()); }
    void set_lon(float v) { ll = LatLon(ll.lat(), v); }

    LatLon ll;
};

BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(MyLatLon, float,
                                         bg::cs::spherical_equatorial<bg::degree>,
                                         get_lon, get_lat, set_lon, set_lat)

int main()
{
    typedef std::pair<MyLatLon, unsigned> point_pair;

    bgi::rtree<point_pair, bgi::quadratic<16>> intersectionRTree;

    intersectionRTree.insert(std::make_pair(MyLatLon(0, 0), 0));
    intersectionRTree.insert(std::make_pair(MyLatLon(2, 2), 1));

    bg::model::box<MyLatLon> b(MyLatLon(1, 1), MyLatLon(3, 3));
    std::vector<point_pair> result1;
    intersectionRTree.query(bgi::intersects(b), std::back_inserter(result1));
    if (! result1.empty())
        std::cout << bg::wkt(result1[0].first) << std::endl;

    std::vector<point_pair> result2;
    intersectionRTree.query(bgi::nearest(MyLatLon(0, 1), 1), std::back_inserter(result2));
    if (! result2.empty())
        std::cout << bg::wkt(result2[0].first) << std::endl;
}