I am currently trying to implement a motion-planning algorithm and have been using Boost's RTree to do so. Up until now, the RTree has stored std::pair<boost::geometry::model::point<double, 2, bg::cs::cartesian>, unsigned int>
and has worked just fine in answering nearest neighbor queries.
Externally, I make use of a custom struct called Node
, each of which corresponds to a point in the RTree. I maintain a vector
of Node
s so that the ids of the output pairs from the RTree queries can be used as indices to be looked up in the vector.
However, I want to eliminate the use of this large vector to see its results on time and space performance of my algorithm. To do this, I want to replace the use of point
in the pair
s with Node
s, so that the Node
s are directly output in the query results. To do this I have used boost geometry 2d point registering, with the following code:
#include <algorithm>
#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <bits/stdc++.h>
#include <boost/geometry.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <chrono>
using namespace std;
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
struct Node
{
Node *parent;
point pos;
};
typedef pair<Node, unsigned int> ptval;
typedef pair<box, unsigned int> boxval;
BOOST_GEOMETRY_REGISTER_POINT_2D(Node, double, bg::cs::cartesian, pos.get<0>(), pos.get<1>());
int main() {
cout << "hi" << endl; return 0;
}
However, a strange error results:
In file included from rrt.cpp:13:
rrt.cpp: In static member function 'static void boost::geometry::traits::access<Node, 0>::set(Node&, const double&)':
rrt.cpp:45:1: error: assignment of read-only location 'p.Node::pos.boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>::get<0>()'
BOOST_GEOMETRY_REGISTER_POINT_2D(Node, double, bg::cs::cartesian, pos.get<0>(), pos.get<1>());
This is odd as there are no const declarations anywhere here. I'm guessing it has to do with something inside of the hood of the get<>() functions, but I'm not sure exactly what it is.
Any help is appreciated, as I've not found this issue anywhere online.
What version of boost is that? BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET
takes 7 parameters, not 5, and it has done so ever since the source file appeared in January 2010, which means Boost 1.47.0.
Looking at the docs, it looks like the ()
are not supposed to be included on the member functions anyways.
Finally, you have bg::get<0>
in your question code, but since that doesn't even match with the error message you show, I'm assuming that's a simple mistake in the question.
Here's a little test program with the fixes I think you wanted:
#include <algorithm>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <chrono>
#include <iostream>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::box<point> box;
struct Node {
Node* parent;
point pos;
};
using ptval = std::pair<Node, unsigned int>;
using boxval = std::pair<box, unsigned int>;
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET( //
Node, double, bg::cs::cartesian, //
pos.get<0>, pos.get<1>, pos.set<0>, pos.set<1>)
int main() {
{
bgi::rtree<ptval, bgi::rstar<16>> index;
Node n{nullptr, {}};
bg::assign_values(n.pos, 10.0, 10.0);
int idx = 0;
index.insert({n, idx++});
for (auto pt : { point{20.0, 10.0}, {20.0, 20.0}, {10.0, 20.0} }) {
bg::assign(n.pos, pt);
index.insert({n, idx++});
}
for (auto& [g, id] : index) {
std::cout << id << ": " << bg::wkt(g) << '\n';
}
}
{
bgi::rtree<boxval, bgi::rstar<16>> index;
index.insert(boxval{{{1, 2}, {3, 4}}, 12});
for (auto& [g, id] : index) {
std::cout << id << ": " << bg::wkt(g) << '\n';
}
}
}
Printing
0: POINT(10 10)
1: POINT(20 10)
2: POINT(20 20)
3: POINT(10 20)
12: POLYGON((1 2,1 4,3 4,3 2,1 2))