I am trying to adapt this boost rtree example so that python calls the c++ libraries. This is my first attempt at calling c++ from python. I am using cppyy 1.8.5 (python version 3.6.7) and boost rtree header-only library (boost version 1.58) on ubuntu 16.04.7 LTS. Here is the code that I have so far.
import cppyy
cppyy.set_debug()
import cppyy.ll
cppyy.ll.set_signals_as_exception(True)
cppyy.add_include_path('/usr/include')
cppyy.include('boost/geometry.hpp')
cppyy.include('boost/geometry/geometries/point.hpp')
cppyy.include('boost/geometry/geometries/box.hpp')
cppyy.include('boost/geometry/index/rtree.hpp')
cppyy.include('vector')
cppyy.include('iostream')
cppyy.include('boost/foreach.hpp')
cpp = cppyy.gbl
std = cpp.std
bg = cpp.boost.geometry
bgi = cpp.boost.geometry.index
point = bg.model.point[float, 2, bg.cs.cartesian]
box = bg.model.box[point]
value = std.pair[box, 'unsigned']
rtree = bgi.rtree[value, bgi.quadratic(16)]
for i in range(10):
b = box(point(i + 0.0, i + 0.0), point(i + 0.5, i + 0.5))
print(bg.wkt[box](b))
with cppyy.ll.signals_as_exception():
rtree.insert(std.make_pair(b, i))
In the for loop, the box is created but the rtree.insert() call produces an error.
$ python try_cppyy_rtree.py
TClass::GetClass: Header Parsing - The representation of __cppyy_internal was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting __cppyy_internal in the linkdef/selection file.
...<trimmed>...
TClass::GetClass: Header Parsing - The representation of boost::geometry::wkt_manipulator<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> > > was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting boost::geometry::wkt_manipulator<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> > > in the linkdef/selection file.
POLYGON((0 0,0 0.5,0.5 0.5,0.5 0,0 0))
TClass::GetClass: Header Parsing - The representation of std::make_pair was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting std::make_pair in the linkdef/selection file.
TClass::GetClass: Header Parsing - The representation of std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int> was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int> in the linkdef/selection file.
TClass::GetClass: Header Parsing - The representation of std::__pair_base<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int> was not found in the type system. A lookup in the interpreter is about to be tried: this can cause parsing. This can be avoided selecting std::__pair_base<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int> in the linkdef/selection file.
In file included from input_line_19:1:
In file included from /usr/include/boost/geometry.hpp:17:
In file included from /usr/include/boost/geometry/geometry.hpp:43:
In file included from /usr/include/boost/geometry/core/radian_access.hpp:28:
In file included from /usr/include/boost/geometry/util/math.hpp:28:
In file included from /usr/include/boost/math/constants/constants.hpp:18:
In file included from /usr/include/boost/lexical_cast.hpp:30:
In file included from /usr/include/boost/range/iterator_range_core.hpp:38:
In file included from /usr/include/boost/range/functions.hpp:18:
/usr/include/boost/range/begin.hpp:47:17: error: member reference type 'std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int> *const' is a pointer; did you mean
to use '->'?
return c.begin();
~^
->
/usr/include/boost/range/begin.hpp:111:12: note: in instantiation of function template specialization 'boost::range_detail::range_begin<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, int> *const>' requested here
return range_begin( r );
^
/usr/include/boost/range/begin.hpp:127:46: note: in instantiation of function template specialization 'boost::range_adl_barrier::begin<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, int> *>' requested here
return boost::range_adl_barrier::begin( r );
^
/usr/include/boost/geometry/index/rtree.hpp:1417:30: note: in instantiation of function template specialization 'boost::range_adl_barrier::const_begin<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, int> *>' requested here
for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
^
/usr/include/boost/geometry/index/rtree.hpp:624:15: note: in instantiation of function template specialization 'boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, unsigned int>, boost::geometry::index::quadratic<16, 4>,
boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >
>::insert_dispatch<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int> *>' requested here
this->insert_dispatch(conv_or_rng, is_conv_t());
^
note: in instantiation of function template specialization 'boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, unsigned int>, boost::geometry::index::quadratic<16, 4>,
boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >
>::insert<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int> *>' requested here
In file included from input_line_19:1:
In file included from /usr/include/boost/geometry.hpp:17:
In file included from /usr/include/boost/geometry/geometry.hpp:43:
In file included from /usr/include/boost/geometry/core/radian_access.hpp:28:
In file included from /usr/include/boost/geometry/util/math.hpp:28:
In file included from /usr/include/boost/math/constants/constants.hpp:18:
In file included from /usr/include/boost/lexical_cast.hpp:30:
In file included from /usr/include/boost/range/iterator_range_core.hpp:38:
In file included from /usr/include/boost/range/functions.hpp:18:
/usr/include/boost/range/begin.hpp:47:18: error: no member named 'begin' in 'std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int>'
return c.begin();
~ ^
In file included from input_line_19:1:
In file included from /usr/include/boost/geometry.hpp:17:
In file included from /usr/include/boost/geometry/geometry.hpp:43:
In file included from /usr/include/boost/geometry/core/radian_access.hpp:28:
In file included from /usr/include/boost/geometry/util/math.hpp:28:
In file included from /usr/include/boost/math/constants/constants.hpp:18:
In file included from /usr/include/boost/lexical_cast.hpp:30:
In file included from /usr/include/boost/range/iterator_range_core.hpp:38:
In file included from /usr/include/boost/range/functions.hpp:19:
/usr/include/boost/range/end.hpp:48:21: error: member reference type 'std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int> *const' is a pointer; did you mean
to use '->'?
return c.end();
~^
->
/usr/include/boost/range/end.hpp:105:12: note: in instantiation of function template specialization 'boost::range_detail::range_end<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, int> *const>' requested here
return range_end( r );
^
/usr/include/boost/range/end.hpp:121:46: note: in instantiation of function template specialization 'boost::range_adl_barrier::end<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, int> *>' requested here
return boost::range_adl_barrier::end( r );
^
/usr/include/boost/geometry/index/rtree.hpp:1417:61: note: in instantiation of function template specialization 'boost::range_adl_barrier::const_end<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, int> *>' requested here
for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
^
/usr/include/boost/geometry/index/rtree.hpp:624:15: note: in instantiation of function template specialization 'boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, unsigned int>, boost::geometry::index::quadratic<16, 4>,
boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >
>::insert_dispatch<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int> *>' requested here
this->insert_dispatch(conv_or_rng, is_conv_t());
^
note: in instantiation of function template specialization 'boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2,
boost::geometry::cs::cartesian> >, unsigned int>, boost::geometry::index::quadratic<16, 4>,
boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >,
std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, unsigned int> >
>::insert<std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int> *>' requested here
In file included from input_line_19:1:
In file included from /usr/include/boost/geometry.hpp:17:
In file included from /usr/include/boost/geometry/geometry.hpp:43:
In file included from /usr/include/boost/geometry/core/radian_access.hpp:28:
In file included from /usr/include/boost/geometry/util/math.hpp:28:
In file included from /usr/include/boost/math/constants/constants.hpp:18:
In file included from /usr/include/boost/lexical_cast.hpp:30:
In file included from /usr/include/boost/range/iterator_range_core.hpp:38:
In file included from /usr/include/boost/range/functions.hpp:19:
/usr/include/boost/range/end.hpp:48:22: error: no member named 'end' in 'std::pair<boost::geometry::model::box<boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> >, int>'
return c.end();
~ ^
Traceback (most recent call last):
File "try_cppyy_rtree.py", line 58, in <module>
rtree.insert(std.make_pair(b, i))
TypeError: Template method resolution failed:
void boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert(const boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::value_type& value) =>
TypeError: unbound method rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert must be called with a rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > > instance as first argument
void boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert(const std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int>& conv_or_rng) =>
TypeError: unbound method rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert must be called with a rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > > instance as first argument
void boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert(std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int>*const& conv_or_rng) =>
TypeError: unbound method rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert must be called with a rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > > instance as first argument
void boost::geometry::index::rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert(const std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,int>& conv_or_rng) =>
TypeError: unbound method rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > >::insert must be called with a rtree<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int>,boost::geometry::index::quadratic<16,4>,boost::geometry::index::indexable<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> >,std::allocator<std::pair<boost::geometry::model::box<boost::geometry::model::point<float,2,boost::geometry::cs::cartesian> >,unsigned int> > > instance as first argument
Any insights on how to get this working? Is using cppyy recommended for what I am attempting? I chose cppyy initially because examples I see using other methods seem to require an object file, but boost rtree is a header-only library.
Any reason for using cppyy
1.8.5? The problem with the script is independent of cppyy
version, but I've only verified that it runs correctly with 2.0.0 (which is based on a newer version of Clang).
The problem is with this line:
rtree = bgi.rtree[value, bgi.quadratic(16)]
makes that rtree
is still only a type object. Compare the syntax to the preceding typedefs that you (correctly) transliterated before that. To get an actual instance of the bgi::rtree
, you need to instantiate the type:
rtree = bgi.rtree[value, bgi.quadratic(16)]()
Note the extra ()
.
I checked and b
is copied, so creating the boxes in a loop should be fine. Otherwise, with Python, since b
will be garbage collected (same as in C++ in the original example, really, as there they are stack objects), its lifetime should have been managed (e.g. by using smart pointers).