提高r树的“正确”访问对象的方式

问题描述

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;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...