I am currently using the GEOS library through OGR and data from a PostGIS database to work with geospatial data. I now found myself in the need to use some of the algorithms Boost.Geometry and Boost.Graph offers, so I've adopted the OGR classes to boost's iterator/range concept. However, the two libraries yield different results, and I am unsure why. From the compiler perspective everything works; however, a simple test case fails.
Step by step, here is what I did.
I define two linestrings and a point and assign WGS84 as projection, in PostGIS:
ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', 4326),
ST_GeomFromText('LINESTRING(15.0 15.0, 16.0 16.0)', 4326)
ST_GEomFromText('POINT(15.0 15.0)', 4326)
Then I calculate the distance between the first and the second linestring and the distance between the first linestring and the point:
db=# SELECT ST_Distance(
ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', 4326),
ST_GeomFromText('POINT(15.0 15.0)', 4326));
st_distance
-----------------
15.556349186104
db=# SELECT ST_Distance(
ST_GeomFromText('LINESTRING(0.0 0.0, 1.0 1.0, 2.0 2.0, 3.0 3.0, 4.0 4.0)', 4326),
ST_GeomFromText('LINESTRING(15.0 15.0, 16.0 16.0)', 4326));
st_distance
-----------------
15.556349186104
Using OGR/GEOS to do the same calculations in the client program yields the same results.
Now I compare those with the result of the boost adaption. I registered OGRPoint
with the boost library with the following code:
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(
OGRPoint,
qreal,
boost::geometry::cs::cartesian,
getX,
getY,
setX,
setY)
The most important part is the fourth line, where the coordinate system is defined. Since all my coordinates are in WGS84 projection, I chose "cartesian" as the appropriate coordinate system.
And here is the relevant code from my unit test:
OGRLineString ls1, ls2;
OGRPoint distantPoint(15.0, 15.0);
OGRSpatialReference *sref = new OGRSpatialReference();
OGRErr rc = sref->importFromEPSG(4326);
QVERIFY(OGRERR_NONE == rc);
ls1.assignSpatialReference(sref);
ls2.assignSpatialReference(sref);
distantPoint.assignSpatialReference(sref);
for (int i = 0; i != 5; ++i) {
ls1.addPoint(static_cast<qreal>(i), static_cast<qreal>(i));
}
ls2.addPoint(15.0, 15.0);
ls2.addPoint(16.0, 16.0);
QCOMPARE(
bg::crosses(ls1, distantPoint),
ls1.Crosses(&distantPoint));
QCOMPARE(
bg::intersects(ls1, distantPoint),
ls1.Intersects(&distantPoint));
QCOMPARE(bg::distance(ls1, ls2), ls1.Distance(&ls2));
QCOMPARE(
bg::distance(
ls1,
distantPoint),
ls1.Distance(&distantPoint));
delete sref;
However, using boost's boost::geometry::distance
yields totally different results: For the distance linestring to linestring, the result is 0, for point to linestring, 16.9706. Using one of the other strategies defined in the boost library also yields completely different results, such as 0.294082 for boost::geometry::cs::geographic
.
What is the reason for this? What am I doing wrong?