Boost logo

Geometry :

Subject: Re: [geometry] Integrating OGR library with Boost.Geometry
From: Eric MSP Veith (eveith_at_[hidden])
Date: 2015-01-11 11:42:46


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