I wrote this small program, following the boost documentation, but I get pages of errors when building it.
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <iostream>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
typedef bg::model::d2::point_xy<double> point_2d;
class Foo
{
public:
point_2d position;
Foo(double x, double y) : position(x, y) {}
auto get() const { return position; }
};
int main()
{
bgi::rtree<Foo, bgi::quadratic<16>> rtree;
rtree.insert(Foo(1.0, 2.0));
rtree.insert(Foo(3.0, 4.0));
rtree.insert(Foo(5.0, 6.0));
rtree.insert(Foo(7.0, 8.0));
// Define a search box with a certain distance from a given point
point_2d search_point(0.0, 0.0);
double search_distance = 5.0;
point_2d lower_left(search_point.x() - search_distance, search_point.y() - search_distance);
point_2d upper_right(search_point.x() + search_distance, search_point.y() + search_distance);
bg::model::box<point_2d> search_box(lower_left, upper_right);
// Use the rtree to search for instances of Foo within the search box
std::vector<Foo> result;
rtree.query(bgi::intersects(search_box), std::back_inserter(result));
// Print the results
std::cout << "Found " << result.size() << " instances of Foo within the search box" << std::endl;
for (const auto& foo : result)
std::cout << "Foo at position (" << foo.position.x() << ", " << foo.position.y() << ")" << std::endl;
}
Here is the build:
clang++ --std=c++17 tree.cpp -lboost-geometry 2>&1 | head -n50
In file included from tree.cpp:1:
In file included from /usr/include/boost/geometry/index/rtree.hpp:49:
/usr/include/boost/geometry/index/indexable.hpp:64:5: error: no matching function for call to 'assertion_failed'
BOOST_MPL_ASSERT_MSG(
^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/mpl/assert.hpp:454:51: note: expanded from macro 'BOOST_MPL_ASSERT_MSG'
# define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \
^
/usr/include/boost/mpl/assert.hpp:440:9: note: expanded from macro '\
BOOST_MPL_ASSERT_MSG_IMPL'
boost::mpl::assertion_failed<(c)>( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/mpl/assert.hpp:60:58: note: expanded from macro '\
BOOST_MPL_AUX_ASSERT_CONSTANT'
# define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) enum { expr }
^~~~
/usr/include/boost/geometry/index/indexable.hpp:351:7: note: in instantiation of template class 'boost::geometry::index::detail::indexable<Foo, false>' requested here
: detail::indexable<Value>
^
/usr/include/boost/geometry/index/detail/translator.hpp:46:14: note: in instantiation of template class 'boost::geometry::index::indexable<Foo>' requested here
: public IndexableGetter
^
/usr/include/boost/geometry/index/detail/translator.hpp:74:22: note: in instantiation of template class 'boost::geometry::index::detail::translator<boost::geometry::index::indexable<Foo>, boost::geometry::index::equal_to<Foo> >' requested here
typedef typename IndexableGetter::result_type type;
^
/usr/include/boost/geometry/index/detail/translator.hpp:82:22: note: in instantiation of template class 'boost::geometry::index::detail::result_type<boost::geometry::index::detail::translator<boost::geometry::index::indexable<Foo>, boost::geometry::index::equal_to<Foo> > >' requested here
typename result_type<IndexableGetter>::type
^
/usr/include/boost/geometry/index/rtree.hpp:177:37: note: in instantiation of template class 'boost::geometry::index::detail::indexable_type<boost::geometry::index::detail::translator<boost::geometry::index::indexable<Foo>, boost::geometry::index::equal_to<Foo> > >' requested here
typedef typename index::detail::indexable_type<
^
tree.cpp:27:41: note: in instantiation of template class 'boost::geometry::index::rtree<Foo, boost::geometry::index::quadratic<16, 4>, boost::geometry::index::indexable<Foo>, boost::geometry::index::equal_to<Foo>, boost::container::new_allocator<Foo> >' requested here
bgi::rtree<Foo, bgi::quadratic<16>> rtree;
^
/usr/include/boost/mpl/assert.hpp:83:5: note: candidate function template not viable: no known conversion from 'boost::mpl::failed ************(boost::geometry::index::detail::indexable<Foo, false>::NOT_VALID_INDEXABLE_TYPE::************)(Foo)' to 'typename assert<false>::type' (aka 'mpl_::assert<false>') for 1st argument
int assertion_failed( typename assert<C>::type );
^
In file included from tree.cpp:1:
In file included from /usr/include/boost/geometry/index/rtree.hpp:28:
In file included from /usr/include/boost/geometry/algorithms/detail/comparable_distance/interface.hpp:23:
In file included from /usr/include/boost/geometry/geometries/concepts/check.hpp:28:
In file included from /usr/include/boost/geometry/geometries/concepts/box_concept.hpp:23:
In file included from /usr/include/boost/geometry/core/access.hpp:25:
In file included from /usr/include/boost/geometry/core/coordinate_type.hpp:20:
/usr/include/boost/geometry/core/point_type.hpp:45:5: error: no matching function for call to 'assertion_failed'
BOOST_MPL_ASSERT_MSG
^~~~~~~~~~~~~~~~~~~~
/usr/include/boost/mpl/assert.hpp:454:51: note: expanded from macro 'BOOST_MPL_ASSERT_MSG'
# define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \
Foo is not an indexable type. Meaning, mainly, that rtree
doesn't know what geometry to index it by.
Let's make an IndexableGetter:
struct ByPos {
using result_type = point_2d;
result_type const& operator()(Foo const& f) const { return f.position; }
};
Now you can use it:
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <iostream>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
using point_2d = bg::model::d2::point_xy<double> ;
using box = bg::model::box<point_2d>;
struct Foo {
point_2d position;
Foo(double x, double y) : position(x, y) {}
auto get() const { return position; }
struct ByPos {
using result_type = point_2d;
result_type const& operator()(Foo const& f) const { return f.position; }
};
};
auto intersecting(auto const& search, auto const& tree) {
std::vector<std::reference_wrapper<Foo const>> result;
tree.query(bgi::intersects(search), back_inserter(result));
return result;
}
int main() {
bgi::rtree<Foo, bgi::quadratic<16>, Foo::ByPos> rtree;
rtree.insert({1.0, 2.0});
rtree.insert({3.0, 4.0});
rtree.insert({5.0, 6.0});
rtree.insert({7.0, 8.0});
// box with given distance from center
auto makebox = [&](double d, point_2d c = {}) {
return box{{c.x() - d, c.y() - d}, {c.x() + d, c.y() + d}};
};
auto key = makebox(5.0);
std::cout << "Within " << bg::dsv(key) << ":\n";
for (Foo const& foo : intersecting(key, rtree))
std::cout << " - at " << bg::dsv(foo.position) << "\n";
}
Prints
Within ((-5, -5), (5, 5)):
- at (1, 2)
- at (3, 4)