TLDR: is there a way to update object directly in a Boost r-tree (by setting the location class property to const, or something similar)?
More info:
I am using C++ Boost's R-tree to store objects with spatial coordinates (for reference, please see my previous question). For the sake of the discussion, let's assume my objects are City
-ies with spatial cartesian coordinates and some class properties; say population and size.
Currently, I have a separate std::map
whose keys are some indices and values are the City
objects. In the tree, as suggested in the answer to my previous question, I store some struct whose fields are the City
index and its coordinates. When I need update a City
class property, all I do is search for the city in the tree, and update the 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;
I think that just for code readably, it would be much more comprehensible if I did not need to store a separate City
map. Is there a way to directly update the object stored in the tree? I understand this may lead to unwanted behavior, as the tree needs to be re-balanced if the location
property is ever changed. However, at least conceptually, it would be nice if there was a way to define just the location
field as a const
(so it couldn't be changed), and do something like:
City::City() {
const point location;
double population;
double size;
}
And store that object in the tree:
typedef bgi::rtree< City, bgi::quadratic<16>, index::indexable<City>, index::equal_to<City> > rtree_t;
Then, it would be possible to use a nearest neighbor iterator rtree_t::const_query_iterator it
scroll through the values, and do something like
it->population = newPopulation;
No, it's not possible to store mutable values in the rtree right now.
You could store the point and index in the rtree and then the rest of the data in a different container. It could be vector/deque if the index is preserved (you don't remove elements from the container) or map if you need sorting by key or unoredered_map if you don't. So e.g.:
Another option would be to use
const_cast
and be careful to not modify the location. So something like: