Boost logo

Geometry :

Subject: Re: [geometry] Using Boost.Geometry with a legacy class hierarchy
From: Barend Gehrels (barend_at_[hidden])
Date: 2012-02-19 16:41:23


Hi Mats,

On 17-2-2012 12:10, Mats Taraldsvik wrote:
> Hi,
>
> With the help of boost::iterator_facade and stackoverflow.com [1],
> I've almost managed to adapt the Ring concept to my legacy objects,
> but I got a compile time error which I don't understand. As you can
> see from the code, the iterator exposes QPoint* objects directly, so
> that should work properly.
>
> The cpp files and the errors from the build log is here [2].
>
> [1]
> http://stackoverflow.com/questions/9251537/how-to-create-a-boost-range-that-hides-multiple-layers-of-vectors-and-exposes-it
> [2] https://gist.github.com/1852693
>
> Regards,
> Mats Taraldsvik
>

There are two different problems.

Problem 1: const pointer.

If you add to your program:
     QPoint const* pc = *ri;
     std::cout << boost::geometry::wkt(pc);

it fails too. So the version with a QPoint* succeeded, but with a QPoint
const* fails.

That can be fixed by adding traits classes for QPoint const*

That is straightforward, I pasted on http://codepad.org/fZAGMA2w
you can skip the set within the access traits classes for any const
point type.

This normally does not have to be done for Boost.Geometry. But because
of the pointer-to-point type it has to. The library is not (yet) tested
for these types.

Problem 2: const/non const behaviour.
Now that we fixed problem one, we get other problems. The good news is
that it is, for WKT writing, easy to solve. I believe that for the
moment this is what you need.

This needs two fixes:
2a: your declaration if your iterator should be:
     class RingIteratorImpl : public boost::iterator_facade<
             RingIteratorImpl<I,R>, R, boost::forward_traversal_tag, R>

so R instead of QPoint*, I think this should be done anyway. This makes
the second template parameter in iterator_facade const too.

2b: line 138 in boost/geometry/io/wkt/write.hpp reads:
     typedef typename boost::range_value<Range>::type point_type;

if you change that by adding a const, to:
     typedef typename boost::range_value<Range const>::type point_type;

it will write the WKT if your ring.

I think we can do that in Boost.Geometry safely, on this place. However
if I change this to geometry::point_type (which we normally use) it does
not work (with or without const). And if I try to print the area I get
another error (not related to range_value).

That has to be figured out more.

Anyway the WKT writing shows that at least it could work, and for your
purposes it works.

There might be more solutions e.g. in writing the iterator, but until
now I could not solve it that way (besides 2a)

Regards, Barend



Geometry list run by mateusz at loskot.net