Boost logo

Geometry :

Subject: [geometry] Using iterator_range as a Geometry
From: Sakari Bergen (sakari.bergen_at_[hidden])
Date: 2012-05-25 09:04:52


First of all I'd like to note that I am fairly new to both Boost.Geometry
and Boost.Range, so I might be doing something non-optimal here.

I'm using two boost::circular_buffers to store "events" (time stamps and
points), one containing the time stamps and the other the points. I need to
make linestrings out of a subset of the points, and currently I'm using
iterator_range to achieve this in an efficient manner. However, the problem
I'm facing (which I did solve, a code snippet will follow) is that the
linestring template assumes that all containers take two template
parameters, the type and the allocator, where as iterator_range uses the
iterator type as it's only template parameter.

I solved the issue by making an adapter class template, which takes the
correct template parameters (the second one being unused), and provides the
appropriate two iterator constructor so that it can be used with
linestring. I wrapped all of this in macros and typedefs to make it more
generic and easier to use.

I was wondering if there is an easier way to do this, or if the library
could be modified in some way to make it easier?


Here's the code:


// Iterator range adapter for boost::geometry stuff
// (which expects containers to have two template parameters: T and
#define ITERATOR_RANGE_ADAPTER(ClassName, ContainerType, IteratorType) \
template<typename T, typename Unused> \
class ClassName \
        : public boost::iterator_range<typename
ContainerType<T>::IteratorType> \
{ \
        typedef typename ContainerType<T>::IteratorType iterator_; \
        typedef boost::iterator_range<iterator_> base_class_; \
public: \
        ClassName(iterator_ b, iterator_ e) : base_class_(b, e) {} \

// Uses the above to adapt a iterator range to a line string
#define ITERATOR_RANGE_GEOMETRY_TYPEDEF(TypedefName, GeometryType,
PointType, ContainerType, IteratorType) \
ITERATOR_RANGE_ADAPTER(TypedefName##Adapter, ContainerType, IteratorType) \
typedef GeometryType<PointType, TypedefName##Adapter> TypedefName;


After which I can do (Point3D is a typedef for a geometry::point):

boost::geometry::model::linestring, Point3D, boost::circular_buffer,
RangeLinestring rls(some_cb_iterator, other_cb_iterator);

Geometry list run by mateusz at