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;