Boost r-tree "correct" 访问对象的方式
Boost r-tree "correct" way to access objects
TLDR:有没有办法直接在 Boost r 树中更新对象(通过将位置 class 属性 设置为 const,或者类似的东西)?
更多信息:
我正在使用 C++ Boost 的 R-tree 来存储具有空间坐标的对象(供参考,请参阅我的 )。为了便于讨论,我们假设我的对象是 City
-ies,具有空间笛卡尔坐标和一些 class 属性;说人口和规模。
目前,我有一个单独的 std::map
,其键是一些索引,值是 City
对象。在树中,正如我在上一个问题的答案中所建议的那样,我存储了一些结构,其字段是 City
索引及其坐标。当我需要更新 City
class 属性 时,我所做的就是在树中搜索城市,然后更新 std::map
:
// The struct stored in the tree
struct CityRef {
size_t index;
point location;
};
typedef bgi::rtree< CityRef, bgi::quadratic<16>, bgi::indexable<CityRef>, index::equal_to<CityRef> > rtree_t;
//A map storing the cities:
std::map<size_t, City *> cityDict;
我觉得只是为了代码的可读性,如果不需要单独存储一个City
map的话,会更容易理解。有没有办法直接更新存储在树中的对象?我知道这可能会导致不良行为,因为如果 location
属性 发生变化,树就需要重新平衡。但是,至少在概念上,如果有一种方法可以将 location
字段定义为 const
(因此无法更改),并执行类似以下操作,那就太好了:
City::City() {
const point location;
double population;
double size;
}
并将该对象存储在树中:
typedef bgi::rtree< City, bgi::quadratic<16>, index::indexable<City>, index::equal_to<City> > rtree_t;
然后,可以使用最近邻迭代器 rtree_t::const_query_iterator it
滚动值,并执行类似
的操作
it->population = newPopulation;
不,现在不可能在 rtree 中存储可变值。
您可以将点和索引存储在 rtree 中,然后将其余数据存储在不同的容器中。如果保留索引(您不从容器中删除元素),则可以是 vector/deque ;如果需要按键排序,则可以是 map ;如果不需要,则可以是 unoredered_map 。例如:
struct data_t { double population; double size; };
point_t point;
bgi::rtree<std::pair<point_t, size_t>, bgi::quadratic<16>> rt;
std::unordered_map<size_t, data_t> umap;
for (auto it = rt.qbegin(bgi::nearest(point, 3)); it != rt.qend(); ++it)
data_t& data = umap[it->second];
另一种选择是使用 const_cast
并注意不要修改位置。所以像:
point_t point;
bgi::rtree<City, bgi::quadratic<16>> rt;
for (auto it = rt.qbegin(bgi::nearest(point, 3)); it != rt.qend(); ++it)
const_cast<double&>(it->population) = 123.4;
TLDR:有没有办法直接在 Boost r 树中更新对象(通过将位置 class 属性 设置为 const,或者类似的东西)?
更多信息:
我正在使用 C++ Boost 的 R-tree 来存储具有空间坐标的对象(供参考,请参阅我的 City
-ies,具有空间笛卡尔坐标和一些 class 属性;说人口和规模。
目前,我有一个单独的 std::map
,其键是一些索引,值是 City
对象。在树中,正如我在上一个问题的答案中所建议的那样,我存储了一些结构,其字段是 City
索引及其坐标。当我需要更新 City
class 属性 时,我所做的就是在树中搜索城市,然后更新 std::map
:
// The struct stored in the tree
struct CityRef {
size_t index;
point location;
};
typedef bgi::rtree< CityRef, bgi::quadratic<16>, bgi::indexable<CityRef>, index::equal_to<CityRef> > rtree_t;
//A map storing the cities:
std::map<size_t, City *> cityDict;
我觉得只是为了代码的可读性,如果不需要单独存储一个City
map的话,会更容易理解。有没有办法直接更新存储在树中的对象?我知道这可能会导致不良行为,因为如果 location
属性 发生变化,树就需要重新平衡。但是,至少在概念上,如果有一种方法可以将 location
字段定义为 const
(因此无法更改),并执行类似以下操作,那就太好了:
City::City() {
const point location;
double population;
double size;
}
并将该对象存储在树中:
typedef bgi::rtree< City, bgi::quadratic<16>, index::indexable<City>, index::equal_to<City> > rtree_t;
然后,可以使用最近邻迭代器 rtree_t::const_query_iterator it
滚动值,并执行类似
it->population = newPopulation;
不,现在不可能在 rtree 中存储可变值。
您可以将点和索引存储在 rtree 中,然后将其余数据存储在不同的容器中。如果保留索引(您不从容器中删除元素),则可以是 vector/deque ;如果需要按键排序,则可以是 map ;如果不需要,则可以是 unoredered_map 。例如:
struct data_t { double population; double size; };
point_t point;
bgi::rtree<std::pair<point_t, size_t>, bgi::quadratic<16>> rt;
std::unordered_map<size_t, data_t> umap;
for (auto it = rt.qbegin(bgi::nearest(point, 3)); it != rt.qend(); ++it)
data_t& data = umap[it->second];
另一种选择是使用 const_cast
并注意不要修改位置。所以像:
point_t point;
bgi::rtree<City, bgi::quadratic<16>> rt;
for (auto it = rt.qbegin(bgi::nearest(point, 3)); it != rt.qend(); ++it)
const_cast<double&>(it->population) = 123.4;