From reading your comments I get an impression that you only want to store additional data in points stored in the R-tree and not to store additional data in the internal nodes of the R-tree. So here is an example showing how to store points with additional data and how to perform a query to get some of them. In the example I also show how to achieve the same with std::pair
holding a point and some additional data which works by default and you do not have to register your own point type.
Includes:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <vector>
#include <iostream>
Namespaces for convenience:
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
Definition of your own point type with 2-d coordinates and additional data (color):
enum color {red, green, blue};
struct my_point
{
double x, y;
color c;
};
Adaptation of my_point
to Boost.Geometry Point concept with a macro so the library knows that this struct is a 2-d Point and how to get the coordinates:
BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, double, bg::cs::cartesian, x, y)
Some Boost.Geometry models that will be used as well:
typedef bg::model::point<double, 2, bg::cs::cartesian> bg_point;
typedef bg::model::box<bg_point> bg_box;
Main:
int main()
{
{
Creation of the R-tree and insertion of several points:
bgi::rtree<my_point, bgi::rstar<4> > rtree;
rtree.insert(my_point{ 0, 0, red });
rtree.insert(my_point{ 1, 1, green });
rtree.insert(my_point{ 2, 5, blue });
rtree.insert(my_point{ 7, 3, red });
rtree.insert(my_point{ 8, 8, green });
rtree.insert(my_point{ 1, 9, blue });
Query for points that intersect the following box and are red:
std::vector<my_point> res;
rtree.query(bgi::intersects(bg_box{ {1, 1}, {8, 8} })
&& bgi::satisfies([](my_point const& p) {
return p.c == red;
}),
std::back_inserter(res));
Print the result:
for (my_point const& p : res)
std::cout << bg::wkt(p) << std::endl;
}
The same but std::pair<bg_point, color>
is used instead of my_point
so no registration is needed:
{
bgi::rtree<std::pair<bg_point, color>, bgi::rstar<4> > rtree;
rtree.insert(std::pair<bg_point, color>{ {0, 0}, red });
rtree.insert(std::pair<bg_point, color>{ {1, 1}, green });
rtree.insert(std::pair<bg_point, color>{ {2, 5}, blue });
rtree.insert(std::pair<bg_point, color>{ {7, 3}, red });
rtree.insert(std::pair<bg_point, color>{ {8, 8}, green });
rtree.insert(std::pair<bg_point, color>{ {1, 9}, blue });
std::vector<std::pair<bg_point, color> > res;
rtree.query(bgi::intersects(bg_box{ { 1, 1 },{ 8, 8 } })
&& bgi::satisfies([](std::pair<bg_point, color> const& p) {
return p.second == red;
}),
std::back_inserter(res));
for (std::pair<bg_point, color> const& p : res)
std::cout << bg::wkt(p.first) << std::endl;
}
}
The program above prints the following line two times:
POINT(7 3)
This is the only one red point which intersects the box.
Original answer (if you indeed want to modify the internal structure of the R-tree):
What you want to do is not supported from the public R-tree interface. You'd have to play with the internals which might change in the future.
Here is a thread explaining how you can write a visitor to traverse the R-tree nodes.
Using your own node types is harder. You'd have to:
- add new node tag like this
- specialize internal and leaf nodes (adding members you like in nodes) and all other required classes for this tag like in this file
- implement your own R-tree parameters type, e.g. based on
bgi::rstar
, like this
- specialize
bgi::detail::rtree::options_type
in order to tell the R-tree what nodes should be used for your parameters type like this
See also this node implementation used for R-tree testing. This is a node which can throw an exception on construction. It's used to test exception-safety.