diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 20c52d68aa939af3c5cfe4567ffee72e60082b20..90354514d9421e42c6fe00e4c781c07c6da782ce 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -429,7 +429,8 @@ HEADERS += \ src/Wima/PlanimetryCalculus.h \ src/Wima/Circle.h \ src/Wima/PolygonCalculus.h \ - src/Wima/OptimisationTools.h + src/Wima/OptimisationTools.h \ + src/Wima/GeoUtilities.h SOURCES += \ src/api/QGCCorePlugin.cc \ src/api/QGCOptions.cc \ @@ -457,7 +458,8 @@ SOURCES += \ src/Wima/PlanimetryCalculus.cc \ src/Wima/Circle.cc \ src/Wima/PolygonCalculus.cc \ - src/Wima/OptimisationTools.cc + src/Wima/OptimisationTools.cc \ + src/Wima/GeoUtilities.cc # # Unit Test specific configuration goes here (requires full debug build with all plugins) diff --git a/src/Wima/GeoUtilities.cc b/src/Wima/GeoUtilities.cc new file mode 100644 index 0000000000000000000000000000000000000000..0984e2fdde543ef174b1a1ad99fb779cd47ea3c0 --- /dev/null +++ b/src/Wima/GeoUtilities.cc @@ -0,0 +1,62 @@ +#include "GeoUtilities.h" +#include + + +QGeoCoordinate GeoUtilites::toGeo(const QVector3D &point, const QGeoCoordinate &origin) +{ + double x = point.x(); + double y = point.y(); + double z = point.z(); + + double lat = origin.latitude()/180*M_PI; + double lon = origin.longitude()/180*M_PI; + double h = origin.altitude(); + + if (!qFuzzyCompare(lat, M_PI_2)) // this could (unlikely) be a problem, replace with different coordinate transformation + return QGeoCoordinate(/* lat */ qAtan(x/cos(lat)/earthRadius) + lon, + /* lon */ qAtan(y/earthRadius) + lat, + /* alt */ h + z); + else + return QGeoCoordinate(); // singularity occurred (1/cos(pi/2) = inf) +} + +QVector3D GeoUtilites::toCartesian(const QGeoCoordinate &point, const QGeoCoordinate &origin) +{ + double lat = point.latitude()/180*M_PI; + double lon = point.longitude()/180*M_PI; + double h = point.altitude(); + + double latO = origin.latitude()/180*M_PI; + double lonO = origin.longitude()/180*M_PI; + double hO = origin.altitude(); + + double dlon = lon-lonO; + double dlat = lat-latO; + + + if (!qFuzzyCompare(dlon, M_PI_2) && !qFuzzyCompare(dlat, M_PI_2)) + return QVector3D(/* x */ qTan(dlon)*earthRadius*qCos(latO), + /* y */ qTan(dlat)*earthRadius, + /* z */ h - hO); + else + return QVector3D(); // singularity occurred (tan(pi/2) = inf) + +} + +GeoUtilites::QGeoList GeoUtilites::toGeo(const GeoUtilites::QVector3DFList &points, const QGeoCoordinate &origin) +{ + GeoUtilites::QGeoList coordinates; + for (auto point : points) + coordinates.append(toGeo(point, origin)); + + return coordinates; +} + +GeoUtilites::QVector3DFList GeoUtilites::toCartesian(const GeoUtilites::QGeoList &coordinates, const QGeoCoordinate &origin) +{ + GeoUtilites::QVector3DFList points; + for (auto coordinate : coordinates ) + points.append(toCartesian(coordinate, origin)); + + return points; +} diff --git a/src/Wima/GeoUtilities.h b/src/Wima/GeoUtilities.h new file mode 100644 index 0000000000000000000000000000000000000000..14b9eb28dc0295a049d236d2c2416bdc216e3292 --- /dev/null +++ b/src/Wima/GeoUtilities.h @@ -0,0 +1,22 @@ +#ifndef GEOPOLYGONUTILITIES_H +#define GEOPOLYGONUTILITIES_H + +#include +#include +#include +#include + + +namespace GeoUtilites { + + typedef QList QVector3DFList; + typedef QList QGeoList; + + const double earthRadius = 6378137; // meter + + QGeoCoordinate toGeo (const QVector3D &point, const QGeoCoordinate &origin); + QGeoList toGeo (const QVector3DFList &points, const QGeoCoordinate &origin); + QVector3D toCartesian (const QGeoCoordinate &point, const QGeoCoordinate &origin); + QVector3DFList toCartesian (const QGeoList &coordinates, const QGeoCoordinate &origin); +} +#endif // GEOPOLYGONUTILITIES_H