#include "GeoUtilities.h" namespace GeoUtilities { QGeoCoordinate toGeo(const QVector3D &point, const QGeoCoordinate &origin) { using namespace PolygonCalculus; double z = point.z(); double h = origin.altitude(); QGeoCoordinate coordinate(toGeo(point.toPointF(), origin)); coordinate.setAltitude(z + h); return coordinate; } QVector3D toCartesian(const QGeoCoordinate &coordinate, const QGeoCoordinate &origin) { double h = coordinate.altitude(); double hO = origin.altitude(); QVector3D point(toCartesian2D(coordinate, origin)); point.setZ(h - hO); return point; } QGeoVector toGeo(const QVector3DList &points, const QGeoCoordinate &origin) { QGeoVector coordinates; coordinates.reserve(points.size()); for (auto point : points) coordinates.append(toGeo(point, origin)); return coordinates; } QVector3DList toCartesian(const QGeoList &coordinates, const QGeoCoordinate &origin) { QVector3DList points; for (auto coordinate : coordinates ) points.append(toCartesian(coordinate, origin)); return points; } QPointF toCartesian2D(const QGeoCoordinate &point, const QGeoCoordinate &origin) { double lat = point.latitude()/180*M_PI; double lon = point.longitude()/180*M_PI; double latO = origin.latitude()/180*M_PI; double lonO = origin.longitude()/180*M_PI; double dlon = lon-lonO; double dlat = lat-latO; if (!qFuzzyCompare(dlon, M_PI_2) && !qFuzzyCompare(dlat, M_PI_2)) return QPointF(/* x */ qTan(dlon)*earthRadius*qCos(latO), /* y */ qTan(dlat)*earthRadius); else return QPointF(); // singularity occurred (tan(pi/2) = inf) } QPointFList toCartesian2D(const QGeoList &coordinates, const QGeoCoordinate &origin) { QPointFList listF; listF.reserve(coordinates.size()); for ( auto coordinate : coordinates) listF.append(toCartesian2D(coordinate, origin)); return listF; } QGeoCoordinate toGeo(const QPointF &point, const QGeoCoordinate &origin) { double x = point.x(); double y = point.y(); double lat = origin.latitude(); double lon = origin.longitude(); //qWarning("%lf %lf %lf %lf", x, y, lat, lon); if (!qFuzzyCompare(lat, M_PI_2)) // this could (unlikely) be a problem, replace with different coordinate transformation return QGeoCoordinate(/* lat */ qAtan(y/earthRadius)*180/M_PI + lat, /* lon */ qAtan(x/cos(lat/180*M_PI)/earthRadius)*180/M_PI + lon, /* alt */ origin.altitude()); else return QGeoCoordinate(); // singularity occurred (1/cos(pi/2) = inf) } QGeoVector toGeo(const QPointFList &points, const QGeoCoordinate &origin) { QGeoVector coordinates; coordinates.reserve(points.size()); for ( auto point : points) coordinates.append(toGeo(point, origin)); return coordinates; } QGeoVector toGeo(const QPointFVector &points, const QGeoCoordinate &origin) { QGeoVector coordinates; coordinates.reserve(points.size()); for ( auto point : points) coordinates.append(toGeo(point, origin)); return coordinates; } }