GeoUtilities.cc 3.45 KB
Newer Older
1 2 3
#include "GeoUtilities.h"


4
namespace GeoUtilities {
5

6 7 8 9 10
    QGeoCoordinate toGeo(const QVector3D &point, const QGeoCoordinate &origin)
    {
        using namespace PolygonCalculus;
        double z = point.z();
        double h   = origin.altitude();
11

12 13 14
        QGeoCoordinate coordinate(toGeo(point.toPointF(), origin));
        coordinate.setAltitude(z + h);
        return coordinate;
15

16
    }
17

18 19
    QVector3D toCartesian(const QGeoCoordinate &coordinate, const QGeoCoordinate &origin)
    {
20

21 22
        double h   = coordinate.altitude();
        double hO   = origin.altitude();
23

24 25
        QVector3D point(toCartesian2D(coordinate, origin));
        point.setZ(h - hO);
26

27 28
        return  point;
    }
29

30
    QGeoVector toGeo(const QVector3DList &points, const QGeoCoordinate &origin)
31
    {
32 33
        QGeoVector coordinates;
        coordinates.reserve(points.size());
34 35
        for (auto point : points)
            coordinates.append(toGeo(point, origin));
36

37 38
        return coordinates;
    }
39

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    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)
    }
67

68 69 70
    QPointFList toCartesian2D(const QGeoList &coordinates, const QGeoCoordinate &origin)
    {
        QPointFList listF;
71
        listF.reserve(coordinates.size());
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96

        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)
    }

97
    QGeoVector toGeo(const QPointFList &points, const QGeoCoordinate &origin)
98
    {
99 100
        QGeoVector coordinates;
        coordinates.reserve(points.size());
101 102 103 104 105
        for ( auto point : points)
            coordinates.append(toGeo(point, origin));

        return coordinates;
    }
106

107
    QGeoVector toGeo(const QPointFVector &points, const QGeoCoordinate &origin)
108
    {
109 110
        QGeoVector coordinates;
        coordinates.reserve(points.size());
111 112 113 114 115 116
        for ( auto point : points)
            coordinates.append(toGeo(point, origin));

        return coordinates;
    }

117
}
118