Technaton
Technaton

Reputation: 974

Storing OGRPoint in Boost.Geometry rtree

I'm trying to register the OGR geometry classes with Boost.Geometry to ultimately use them in a Boost.Geometry RTree. To that end, I've followed the tutorial/example in the Boost.Geometry documentation and registered OGRPoint using the BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET macro:

BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(
    OGRPoint,
    double,
    boost::geometry::cs::spherical_equatorial<boost::geometry::degree>,
    getX,
    getY,
    setX,
    setY)

My simple test driver just creates an RTree with a boost::geometry::model::box Indexable:

typedef bg::model::box<OGRPoint> OGRBox;
typedef std::pair <OGRBox, unsigned> Value;

bgi::rtree<Value, bgi::rstar<16>> rtree;
OGRPoint testP0(12.0, 18.0),
        testP1(1.2, 1.8);

rtree.insert(std::make_pair(OGRBox(testP0, testP0), 0));
rtree.insert(std::make_pair(OGRBox(testP1, testP1), 1));

However, I'm stuck with a compile error that boils down to a assertion in Boost:

../../../../include/boost/geometry/index/rtree.hpp:576:398: note:   cannot convert 'boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::insert(const Range&)::PASSED_OBJECT_IS_NOT_A_RANGE576::assert_arg<std::pair<boost::geometry::model::box<OGRPoint>, int> >()' (type 'mpl_::failed************ (boost::geometry::index::rtree<Value, Options, IndexableGetter, EqualTo, Allocator>::insert(const Range&) [with Range = std::pair<boost::geometry::model::box<OGRPoint>, int>; Value = std::pair<boost::geometry::model::box<OGRPoint>, unsigned int>; Parameters = boost::geometry::index::rstar<16ul>; IndexableGetter = boost::geometry::index::indexable<std::pair<boost::geometry::model::box<OGRPoint>, unsigned int> >; EqualTo = boost::geometry::index::equal_to<std::pair<boost::geometry::model::box<OGRPoint>, unsigned int> >; Allocator = std::allocator<std::pair<boost::geometry::model::box<OGRPoint>, unsigned int> >]::PASSED_OBJECT_IS_NOT_A_RANGE::************)(std::pair<boost::geometry::model::box<OGRPoint>, int>)') to type 'mpl_::assert<false>::type {aka mpl_::assert<false>}'
     BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range));

Is there anything else I need to do, like implementing Boost.Range for boost::geometry::model::box<OGRPoint>?

Upvotes: 3

Views: 412

Answers (2)

Adam Wulkiewicz
Adam Wulkiewicz

Reputation: 2098

This problem exist in Boost 1.56 and older.

There are 3 overloads of rtree::insert():

rtree::insert(value_type const&)
rtree::insert(Iter first, Iter last)
rtree::insert(Range const&) // 1.56 and older

In Boost 1.56 and older when an object of a type different than value_type is passed into the insert() member function the rtree treats it as a Range (an object of type adapted to one of the Boost.Range concepts). The error message is produced in compile-time when a parameter is not a Range.

In Boost 1.57 your code should work because the function now recognizes parameters convertible to value_type. Now the 3rd overload is:

rtree::insert(ConvertibleOrRange const&) // 1.57

If you had some suggestions or found a bug don't hesitate to contact the developers on the mailing list or report a bug here.

Upvotes: 3

Technaton
Technaton

Reputation: 974

In that particular case, there was no error with my adapter code. Actually, it was all in the error message to begin with:

typedef std::pair <OGRBox, unsigned> Value;

Note the unsigned.

The error, however states:

std::pair<boost::geometry::model::box<OGRPoint>, int>

Yes, int. The solution is to either use the constructor of std::pair<OGRBox, unsigned> directly, or append u to the number literal, like this:

rtree.insert(std::make_pair(OGRBox(testP0, testP0), 0u));

I cannot belive that this has just caused me three hours of searching. I hope it helps somebody.

Upvotes: 1

Related Questions