#pragma once #include #include #include #include class QPointF; class QRectF; class QSize; class QString; namespace LtsCoordTrans { inline Q_CONSTEXPR double pi() { return M_PI; } inline Q_CONSTEXPR double deg2rad() { return pi() / 180.; } inline Q_CONSTEXPR double rad2deg() { return 1. / deg2rad(); } struct LTSCOORDTRANS_EXPORT UtmCoordinate { int zone = -1; bool northp = true; double x = 0.; double y = 0.; UtmCoordinate() = default; UtmCoordinate(int zone_, double x_, double y_, bool northp_ = true) : zone(zone_) , northp(northp_) , x(x_) , y(y_) {} bool isValid() const { return zone > 0 && zone <= 60; } QString mgrs(int prec = 5, bool withSpaces = true) const; QPointF toPoint() const; QPointF geographic(double offsetX = 0., double offsetY = 0.) const; QPointF geographic(const QPointF &offset) const; QPointF relativeTo(const UtmCoordinate &other) const; static UtmCoordinate fromGeographic(double lon, double lat, int setZone = -1); static UtmCoordinate fromGeographic(const QPointF &lonLat, int setZone = -1); static UtmCoordinate fromMgrs(const QString &mgrs); }; LTSCOORDTRANS_EXPORT QString mgrsFromGeographic(double lon, double lat, int prec = 5, bool withSpaces = true); LTSCOORDTRANS_EXPORT QPointF geographicFromMgrs(const QString &mgrs); LTSCOORDTRANS_EXPORT QRectF addMarginToArea(const QRectF &rect_LatLon_radiant, const QSize &marginMeter); LTSCOORDTRANS_EXPORT QVector getMgrsSquares(const QRectF &rect, bool setAsDefaultSquares, bool setAsPreferedSquare, bool setAsSquareWithMargin = false); QVector getMgrsSquaresInternal(const QRectF &rect); QStringList getMgrsSurroundingSquares(const QRectF &geoRect, const QSize &offsetMeter); LTSCOORDTRANS_EXPORT QVector defaultMgrsSquareWithOffsets(); LTSCOORDTRANS_EXPORT void setDefaultMgrsSquares(const QVector &squares); LTSCOORDTRANS_EXPORT QVector defaultMgrsSquares(); LTSCOORDTRANS_EXPORT UtmCoordinate preferedMgrsSquare(); LTSCOORDTRANS_EXPORT bool lonLatAltToGeocentric(double lon, double lat, double altitude, double &xOut, double &yOut, double &zOut); LTSCOORDTRANS_EXPORT bool geocentric2LonLatAlt(double x, double y, double z, double &lon, double &lat, double &altitude); inline double squareDistance(const UtmCoordinate &p1, const UtmCoordinate &p2) { if (p1.zone != p2.zone) { Q_ASSERT(false); return std::nan(""); } return std::pow(p1.x - p2.x, 2) + std::pow(p1.y - p2.y, 2); } LTSCOORDTRANS_EXPORT double squareDistance(const QPointF &p1, const QPointF &p2); inline double squareDistance(const double lon1, const double lat1, const double lon2, const double lat2) { const auto p1(UtmCoordinate::fromGeographic(lon1, lat1)); const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone)); return squareDistance(p1, p2); } inline double squareDistance(const UtmCoordinate &p1, const double lon2, const double lat2) { const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone)); return squareDistance(p1, p2); } inline double distance(const UtmCoordinate &p1, const UtmCoordinate &p2) { if (p1.zone != p2.zone) { Q_ASSERT(false); return std::nan(""); } return sqrt(squareDistance(p1, p2)); } LTSCOORDTRANS_EXPORT double distance(const QPointF &p1, const QPointF &p2); inline double distance(const double lon1, const double lat1, const double lon2, const double lat2) { return sqrt(squareDistance(lon1, lat1, lon2, lat2)); } inline double distance(const UtmCoordinate &p1, const double lon2, const double lat2) { return sqrt(squareDistance(p1, lon2, lat2)); } LTSCOORDTRANS_EXPORT void dumpConversionCounter(); LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Forward(); LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Reverse(); LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Forward(); LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Reverse(); LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Forward(); LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Reverse(); LTSCOORDTRANS_EXPORT std::ostream &operator<< (std::ostream &stream, const UtmCoordinate &coord); class LTSCOORDTRANS_EXPORT UtmCoordinate3D : public LtsCoordTrans::UtmCoordinate { using BaseClass = LtsCoordTrans::UtmCoordinate; public: UtmCoordinate3D() { reset(); } explicit UtmCoordinate3D(const LtsCoordTrans::UtmCoordinate &utm2d, double _zValue = std::nan("")) :BaseClass() { zone = utm2d.zone; northp = utm2d.northp; x = utm2d.x; y = utm2d.y; zValue = _zValue; } void reset() { zone = -1; northp = true; x = 0.; y = 0.; zValue = std::nan(""); } double z() const { return zValue; } protected: double zValue{std::nan("")}; }; }