Boost logo

Geometry :

Subject: Re: [geometry] Integrating OGR library with Boost.Geometry
From: Eric MSP Veith (eveith_at_[hidden])
Date: 2015-01-12 09:44:19


Hi,

did I say "implementing the Iterator for OGRLineString wasn't that hard"?
Well, I guess it actually is.

bg::model::linestring<OGRPoint> delivers the correct results for any
bg::distance() call. However, when my OGRLineString iterator_facade is being
used, the wrong points are selected. In the example containing the
LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0) and POINT(15.0 15.0),
using my own iterator_facade meant that bg::distance always calculated the
distance between the n-1th point on the linestring and the single point.

I.e., my iterator_facade is at fault. I don't know yet what's exactly wrong,
but I'll find it! :-)

Thanks for all the help so far!

                        --- Eric

On Sunday 11 January 2015 17:42:46, Eric MSP Veith <eveith_at_[hidden]> wrote:
> Hi Adam,
>
> On Sunday 11 January 2015 03:47:01, Adam Wulkiewicz
>
> <adam.wulkiewicz_at_[hidden]> wrote:
> > [...]
> >
> > You could implement some convenient macro and then use it like this:
> >
> > DEFINE_DISTANCE(OGRPoint,OGRPoint)
> > DEFINE_DISTANCE(OGRPoint,OGRLinestring)
> > DEFINE_DISTANCE(OGRPoint,OGRBox)
>
> all right; good to know that there's a last-resort hackedy-hack possible.
>
> > Well, I see now that you've defined your own coordinate system tag. [...]
>
> Yes, that was because I wanted to ensure that none of the BG strategies was
> used, because I though the deviation comes from different formulae being
> used. That's, of course, neither a problem of BG nor OGR, because I assume
> that both libraries implement their corresponding formulae correctly --- I
> just needed consistency between the two.
>
> However, I fear that neither Boost nor OGR are to blame, but simply my very
> own code, because with your test code, I get the correct result.
>
> > What bothers me is why your results are slightly different than mine. Do
> > you get the same for the following program?
> >
> > #include <iostream>
> >
> > #include <boost/geometry.hpp>
> > #include <boost/geometry/geometries/geometries.hpp>
> > #include <boost/geometry/io/wkt/wkt.hpp>
> >
> > namespace bg = boost::geometry;
> > namespace bgi = boost::geometry::index;
> >
> > int main()
> > {
> >
> > typedef bg::model::point<double, 2, bg::cs::cartesian> point;
> > typedef bg::model::linestring<point> linestring;
> >
> > point pt;
> > linestring ls, ls2;
> >
> > bg::read_wkt("LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0
> >
> > 4.0)", ls);
> >
> > bg::read_wkt("POINT(15.0 15.0)", pt);
> > bg::read_wkt("LINESTRING(15.0 15.0, 16.0 16.0)", ls2);
> >
> > std::cout << std::setprecision(24) << bg::distance(pt, ls) <<
> >
> > std::endl;
> >
> > std::cout << std::setprecision(24) << bg::distance(ls, ls2) <<
> >
> > std::endl;
> > }
>
> This outputs:
>
> [eveith_at_basileia:~/tmp/boosttest]% ./bgtest
> 15.5563491861040450459086
> 15.5563491861040450459086
>
> Exactly what I was looking for. So I cut all the custom CS/strategy stuff I
> implemented over the last few days and went back to cs::cartesian. This is
> my current testcase:
>
> --->%---
>
> OGRGeometry *ls3 = nullptr, *p2 = nullptr;
> char wktLS[] = "LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)";
> char wktP[] = "POINT(15.0 15.0)";
> char *wktLSp = static_cast<char *>(wktLS);
> char *wktPp = static_cast<char *>(wktP);
> OGRGeometryFactory::createFromWkt(&wktLSp, sref, &ls3);
> OGRGeometryFactory::createFromWkt(&wktPp, sref, &p2);
>
> QCOMPARE(
> bg::distance(
> *(dynamic_cast<OGRPoint *>(p2)),
> *(dynamic_cast<OGRLineString *>(ls3))),
> ls3->Distance(p2));
>
> --->%---
>
> The result, however, is:
>
> ---%<---
>
> FAIL! : OGRLineStringAdapterTest::testGeometry() Compared doubles are not
> the same (fuzzy compare)
> Actual (bg::distance( *(dynamic_cast<OGRPoint *>(p2)),
> *(dynamic_cast<OGRLineString *>(ls3)))): 16,9706
> Expected (ls3->Distance(p2)): 15,5563
>
> --->%---
>
> Meh. Oh, and the distance between the two linestrings is 0.0, according to
> my code.
>
> > So I guess the answer is already above. First you should probably check
> > if you really need this workadound.
> > The right way would be to properly implement missing elements in
> > Boost.Geometry :)
>
> So, yes, it seems I've made a mistake somewhere in my adapter code, and all
> workarounds are unnecessary. The iterator itself seems to work, though,
> because I can iterate over all points on a given OGRLineString using
> range_begin(ls) and range_end(ls). Hope I can find my bug.
>
> Thank you for the extensive amount of background info. I really appreciate
> it!
>
> Have a nice sunday evening!
>
> --- Eric




Geometry list run by mateusz at loskot.net