问题描述
TLDR :有没有一种方法可以直接在Boost r树中更新对象(通过将location类属性设置为const或类似的东西)?
更多信息:
我正在使用C ++ Boost的R树存储具有空间坐标的对象(有关参考,请参阅我的previous question)。为了便于讨论,我们假设我的对象是具有空间笛卡尔坐标和某些类属性的City
-ie;说人口和规模。
当前,我有一个单独的std::map
,其键是一些索引,值是City
对象。如上一个问题的答案所建议,在树中,我存储了一些结构,其字段为City
索引及其坐标。当我需要更新City
类属性时,我要做的就是在树中搜索城市,然后更新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
映射,那就更容易理解了。有没有一种方法可以直接更新存储在树中的对象?我知道这可能会导致不良行为,因为如果更改了location
属性,则需要重新平衡树。但是,至少从概念上讲,如果有一种方法可以将location
字段定义为const
(这样就不能更改),并执行类似的操作,则将很不错:
City::City() {
const point location;
double population;
double size;
}
并将该对象存储在树中:
typedef bgi::rtree< City,index::indexable<City>,index::equal_to<City> > rtree_t;
然后,可以使用最近的邻居迭代器rtree_t::const_query_iterator it
滚动浏览值,并执行类似的操作
it->population = newPopulation;
解决方法
不,目前无法在 rtree 中存储可变值。
您可以将点和索引存储在 rtree 中,然后将其余数据存储在不同的容器中。如果索引被保留(你不从容器中删除元素)或者 map 如果你需要按键排序或者 unoredered_map 如果你不需要,它可能是 vector/deque。所以例如:
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;