diff --git a/src/Geo/QGCGeo.cc b/src/Geo/QGCGeo.cc index 326eebcb54f70557b51ed53fd548c837b03593a5..e45d5d567ce5f1fdaa754547f13bcd6cd975f760 100644 --- a/src/Geo/QGCGeo.cc +++ b/src/Geo/QGCGeo.cc @@ -8,23 +8,19 @@ ****************************************************************************/ #include +#include #include #include #include "QGCGeo.h" #include "UTMUPS.hpp" +#include "MGRS.hpp" // These defines are private #define M_DEG_TO_RAD (M_PI / 180.0) - #define M_RAD_TO_DEG (180.0 / M_PI) - -#define CONSTANTS_ONE_G 9.80665f /* m/s^2 */ -#define CONSTANTS_AIR_DENSITY_SEA_LEVEL_15C 1.225f /* kg/m^3 */ -#define CONSTANTS_AIR_GAS_CONST 287.1f /* J/(kg * K) */ -#define CONSTANTS_ABSOLUTE_NULL_CELSIUS -273.15f /* °C */ -#define CONSTANTS_RADIUS_OF_EARTH 6371000 /* meters (m) */ +#define CONSTANTS_RADIUS_OF_EARTH 6371000 // meters (m) static const double epsilon = std::numeric_limits::epsilon(); @@ -90,17 +86,63 @@ void convertNedToGeo(double x, double y, double z, QGeoCoordinate origin, QGeoCo } int convertGeoToUTM(const QGeoCoordinate& coord, double& easting, double& northing) +{ + try { + int zone; + bool northp; + GeographicLib::UTMUPS::Forward(coord.latitude(), coord.longitude(), zone, northp, easting, northing); + return zone; + } catch(...) { + return 0; + } +} + +bool convertUTMToGeo(double easting, double northing, int zone, bool southhemi, QGeoCoordinate& coord) +{ + double lat, lon; + try { + GeographicLib::UTMUPS::Reverse(zone, !southhemi, easting, northing, lat, lon); + } catch(...) { + return false; + } + coord.setLatitude(lat); + coord.setLongitude(lon); + + return true; +} + +QString convertGeoToMGRS(const QGeoCoordinate& coord) { int zone; bool northp; - GeographicLib::UTMUPS::Forward(coord.latitude(), coord.longitude(), zone, northp, easting, northing); - return zone; + double x, y; + std::string mgrs; + + try { + GeographicLib::UTMUPS::Forward(coord.latitude(), coord.longitude(), zone, northp, x, y); + GeographicLib::MGRS::Forward(zone, northp, x, y, coord.latitude(), 5, mgrs); + } catch(...) { + mgrs = ""; + } + + return QString::fromStdString(mgrs); } -void convertUTMToGeo(double easting, double northing, int zone, bool southhemi, QGeoCoordinate& coord) +bool convertMGRSToGeo(QString mgrs, QGeoCoordinate& coord) { + int zone, prec; + bool northp; + double x, y; double lat, lon; - GeographicLib::UTMUPS::Reverse(zone, !southhemi, easting, northing, lat, lon); + + try { + GeographicLib::MGRS::Reverse(mgrs.simplified().replace(" ", "").toStdString(), zone, northp, x, y, prec); + GeographicLib::UTMUPS::Reverse(zone, northp, x, y, lat, lon); + } catch(...) { + return false; + } coord.setLatitude(lat); coord.setLongitude(lon); + + return true; } diff --git a/src/Geo/QGCGeo.h b/src/Geo/QGCGeo.h index 18f91ed2cdff24e1d267d18fde9577ece26f6829..4dc59106edd11137d5b3186f228a9cd96c788347 100644 --- a/src/Geo/QGCGeo.h +++ b/src/Geo/QGCGeo.h @@ -58,6 +58,7 @@ void convertNedToGeo(double x, double y, double z, QGeoCoordinate origin, QGeoCo // // Returns: // The UTM zone used for calculating the values of x and y. +// If conversion failed the function returns 0 int convertGeoToUTM(const QGeoCoordinate& coord, double& easting, double& northing); // UTMXYToLatLon @@ -78,7 +79,30 @@ int convertGeoToUTM(const QGeoCoordinate& coord, double& easting, double& northi // lon - The longitude of the point, in radians. // // Returns: -// The function does not return a value. -void convertUTMToGeo(double easting, double northing, int zone, bool southhemi, QGeoCoordinate& coord); +// The function returns true if conversion succeeded. +bool convertUTMToGeo(double easting, double northing, int zone, bool southhemi, QGeoCoordinate& coord); + +// Converts a latitude/longitude pair to MGRS string +// +// Inputs: +// coord - Latitude, Longiture coordinate +// +// Returns: +// The MGRS coordinate string +// If conversion fails the function returns empty string +QString convertGeoToMGRS(const QGeoCoordinate& coord); + +// Converts MGRS string to a latitude/longitude pair. +// +// Inputs: +// mgrs - MGRS coordinate string +// +// Outputs: +// lat - The latitude of the point, in radians. +// lon - The longitude of the point, in radians. +// +// Returns: +// The function returns true if conversion succeeded. +bool convertMGRSToGeo(QString mgrs, QGeoCoordinate& coord); #endif // QGCGEO_H diff --git a/src/SHPFileHelper.cc b/src/SHPFileHelper.cc index 1178c58aa59363681287da15a957ff6ae8a5dab9..86462947301688c172c76e17490c0f9a000e0492 100644 --- a/src/SHPFileHelper.cc +++ b/src/SHPFileHelper.cc @@ -142,9 +142,7 @@ bool SHPFileHelper::loadPolygonFromFile(const QString& shpFile, QListnVertices; i++) { QGeoCoordinate coord; - if (utmZone) { - convertUTMToGeo(shpObject->padfX[i], shpObject->padfY[i], utmZone, utmSouthernHemisphere, coord); - } else { + if (!utmZone || !convertUTMToGeo(shpObject->padfX[i], shpObject->padfY[i], utmZone, utmSouthernHemisphere, coord)) { coord.setLatitude(shpObject->padfY[i]); coord.setLongitude(shpObject->padfX[i]); }