Using iterator_range as a Geometry

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Using iterator_range as a Geometry

Sakari Bergen
Hello,

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?

-Sakari-

Here's the code:

-----------------------

// Iterator range adapter for boost::geometry stuff
// (which expects containers to have two template parameters: T and Allocator)
#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):

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

_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry
Reply | Threaded
Open this post in threaded view
|

Re: Using iterator_range as a Geometry

feverzsj
hi, Sakari

Sakari Bergen wrote
Hello,

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?

-Sakari-

Here's the code:

-----------------------

// Iterator range adapter for boost::geometry stuff
// (which expects containers to have two template parameters: T and
Allocator)
#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):

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

_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry

a dirty and quick way, just as a hint

// this will register any iterator_range<> as ggl linestring

namespace boost{ namespace geometry{ namespace traits{

template<class Iter>
struct tag<iterator_range<Iter> >
{
    typedef linestring_tag type;
};

}}}

regards, zsj
Reply | Threaded
Open this post in threaded view
|

Re: Using iterator_range as a Geometry

Sakari Bergen
Ok, now I just feel stupid :P

BOOST_GEOMETRY_REGISTER_LINESTRING_TEMPLATED(boost::iterator_range); 
seems to do the trick. I thought I tried that already, but I must have done something else wrong since I didn't get it to work with my code...

Thanks for the hint, now I can get rid of that ugly piece of coding!

-Sakari-

On Fri, May 25, 2012 at 5:01 PM, feverzsj <[hidden email]> wrote:
hi, Sakari


Sakari Bergen wrote
>
> Hello,
>
> 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?
>
> -Sakari-
>
> Here's the code:
>
> -----------------------
>
> // Iterator range adapter for boost::geometry stuff
> // (which expects containers to have two template parameters: T and
> Allocator)
> #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):
>
> ITERATOR_RANGE_GEOMETRY_TYPEDEF(RangeLinestring,
> boost::geometry::model::linestring, Point3D, boost::circular_buffer,
> const_iterator)
> RangeLinestring rls(some_cb_iterator, other_cb_iterator);
>
> _______________________________________________
> Geometry mailing list
> Geometry@.boost
> http://lists.boost.org/mailman/listinfo.cgi/geometry
>


a dirty and quick way, just as a hint

// this will register any iterator_range<> as ggl linestring

namespace boost{ namespace geometry{ namespace traits{

template<class Iter>
struct tag<iterator_range<Iter> >
{
   typedef linestring_tag type;
};

}}}

regards, zsj

--
View this message in context: http://boost-geometry.203548.n3.nabble.com/Using-iterator-range-as-a-Geometry-tp4015187p4015268.html
Sent from the Boost Geometry mailing list archive at Nabble.com.
_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry


_______________________________________________
Geometry mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/geometry