/*! \file pigeoposition.h * \ingroup Geo * \~\brief * \~english Class for geo position storage and conversions * \~russian Класс для хранения географической позиции и преобразований */ /* PIP - Platform Independent Primitives Class for geo position storage and conversions Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PIGEOPOSITION_H #define PIGEOPOSITION_H #include "piellipsoidmodel.h" #include "pimathvector.h" //! \~english Geographical position class //! \~russian Класс географической позиции class PIP_EXPORT PIGeoPosition: public PIMathVectorT3d { public: //! \~english Coordinate system types //! \~russian Типы систем координат enum CoordinateSystem { Unknown = 0, //!< Unknown coordinate system Geodetic, //!< Geodetic latitude, longitude, and height above ellipsoid Geocentric, //!< Geocentric (regular spherical coordinates) Cartesian, //!< Cartesian (Earth-centered, Earth-fixed) Spherical //!< Spherical coordinates (theta,phi,radius) }; //! \~english One centimeter tolerance //! \~russian Допуск один сантиметр static const double one_cm_tolerance; //! \~english One millimeter tolerance //! \~russian Допуск один миллиметр static const double one_mm_tolerance; //! \~english One micron tolerance //! \~russian Допуск один микрон static const double one_um_tolerance; //! \~english Default position tolerance (default 1mm) //! \~russian Допуск позиции по умолчанию (по умолчанию 1мм) static double position_tolerance; //! \~english Set position tolerance //! \~russian Установить допуск позиции //! \param tol New tolerance value //! \return Previous tolerance value static double setPositionTolerance(const double tol) { position_tolerance = tol; return position_tolerance; } //! \~english Get position tolerance //! \~russian Получить допуск позиции static double getPositionTolerance() { return position_tolerance; } //! \~english Default constructor //! \~russian Конструктор по умолчанию PIGeoPosition(); //! \~english Constructor with coordinates //! \~russian Конструктор с координатами //! \param a First coordinate //! \param b Second coordinate //! \param c Third coordinate //! \param s Coordinate system //! \param ell Ellipsoid model PIGeoPosition(double a, double b, double c, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Constructor from vector //! \~russian Конструктор из вектора //! \param v Vector with coordinates //! \param s Coordinate system //! \param ell Ellipsoid model PIGeoPosition(PIMathVectorT3d v, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Transform to specified coordinate system //! \~russian Преобразовать в указанную систему координат //! \param sys Target coordinate system //! \return Reference to this position PIGeoPosition & transformTo(CoordinateSystem sys); //! \~english Convert to geodetic coordinates //! \~russian Преобразовать в геодезические координаты PIGeoPosition & asGeodetic() { transformTo(Geodetic); return *this; } //! \~english Convert to geodetic coordinates using specified ellipsoid //! \~russian Преобразовать в геодезические координаты с указанным эллипсоидом //! \param ell Ellipsoid model to use //! \return Reference to this position PIGeoPosition & asGeodetic(const PIEllipsoidModel & ell) { setEllipsoidModel(ell); transformTo(Geodetic); return *this; } //! \~english Convert to ECEF (cartesian) coordinates //! \~russian Преобразовать в координаты ECEF (декартовы) PIGeoPosition & asECEF() { transformTo(Cartesian); return *this; } //! \~english Get X coordinate (or first coordinate in Cartesian) //! \~russian Получить координату X (или первую координату в Декартовой) double x() const; //! \~english Get Y coordinate (or second coordinate in Cartesian) //! \~russian Получить координату Y (или вторую координату в Декартовой) double y() const; //! \~english Get Z coordinate (or third coordinate in Cartesian) //! \~russian Получить координату Z (или третью координату в Декартовой) double z() const; //! \~english Get geodetic latitude in degrees //! \~russian Получить геодезическую широту в градусах double latitudeGeodetic() const; //! \~english Get geocentric latitude in degrees //! \~russian Получить геоцентрическую широту в градусах double latitudeGeocentric() const; //! \~english Get longitude in degrees //! \~russian Получить долготу в градусах double longitude() const; //! \~english Get theta (angle from Z axis) in degrees //! \~russian Получить тета (угол от оси Z) в градусах double theta() const; //! \~english Get phi (angle in XY plane from X axis) in degrees //! \~russian Получить фи (угол в плоскости XY от оси X) в градусах double phi() const; //! \~english Get radius (distance from Earth center) //! \~russian Получить радиус (расстояние от центра Земли) double radius() const; //! \~english Get height above ellipsoid //! \~russian Получить высоту над эллипсоидом double height() const; //! \~english Set ellipsoid model for this position //! \~russian Установить модель эллипсоида для этой позиции //! \param ell Ellipsoid model void setEllipsoidModel(const PIEllipsoidModel & ell) { el = ell; } //! \~english Set position from geodetic coordinates //! \~russian Установить позицию из геодезических координат //! \param lat Latitude in degrees //! \param lon Longitude in degrees //! \param ht Height above ellipsoid //! \param ell Ellipsoid model (default WGS84) //! \return Reference to this position PIGeoPosition & setGeodetic(double lat, double lon, double ht, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Set position from geocentric coordinates //! \~russian Установить позицию из геоцентрических координат //! \param lat Latitude in degrees //! \param lon Longitude in degrees //! \param rad Radius //! \return Reference to this position PIGeoPosition & setGeocentric(double lat, double lon, double rad); //! \~english Set position from spherical coordinates //! \~russian Установить позицию из сферических координат //! \param theta Angle from Z axis in degrees //! \param phi Angle in XY plane from X axis in degrees //! \param rad Radius //! \return Reference to this position PIGeoPosition & setSpherical(double theta, double phi, double rad); //! \~english Set position from ECEF coordinates //! \~russian Установить позицию из координат ECEF //! \param x X coordinate in meters //! \param y Y coordinate in meters //! \param z Z coordinate in meters //! \return Reference to this position PIGeoPosition & setECEF(double x, double y, double z); //! \~english Convert spherical to Cartesian coordinates //! \~russian Преобразовать сферические в декартовы координаты //! \param tpr Input spherical (theta, phi, radius) //! \param xyz Output Cartesian (x, y, z) static void convertSphericalToCartesian(const PIMathVectorT3d & tpr, PIMathVectorT3d & xyz); //! \~english Convert Cartesian to spherical coordinates //! \~russian Преобразовать декартовы в сферические координаты //! \param xyz Input Cartesian (x, y, z) //! \param tpr Output spherical (theta, phi, radius) static void convertCartesianToSpherical(const PIMathVectorT3d & xyz, PIMathVectorT3d & tpr); //! \~english Convert Cartesian (ECEF) to geodetic coordinates //! \~russian Преобразовать декартовы (ECEF) в геодезические координаты //! \param xyz Input Cartesian (x, y, z) //! \param llh Output geodetic (latitude, longitude, height) //! \param ell Ellipsoid model (default WGS84) static void convertCartesianToGeodetic(const PIMathVectorT3d & xyz, PIMathVectorT3d & llh, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Convert geodetic to Cartesian (ECEF) coordinates //! \~russian Преобразовать геодезические в декартовы (ECEF) координаты //! \param llh Input geodetic (latitude, longitude, height) //! \param xyz Output Cartesian (x, y, z) //! \param ell Ellipsoid model (default WGS84) static void convertGeodeticToCartesian(const PIMathVectorT3d & llh, PIMathVectorT3d & xyz, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Convert Cartesian (ECEF) to geocentric coordinates //! \~russian Преобразовать декартовы (ECEF) в геоцентрические координаты //! \param xyz Input Cartesian (x, y, z) //! \param llr Output geocentric (latitude, longitude, radius) static void convertCartesianToGeocentric(const PIMathVectorT3d & xyz, PIMathVectorT3d & llr); //! \~english Convert geocentric to Cartesian (ECEF) //! \~russian Преобразовать геоцентрические в декартовы (ECEF) //! \param llr Input geocentric (latitude, longitude, radius) //! \param xyz Output Cartesian (x, y, z) static void convertGeocentricToCartesian(const PIMathVectorT3d & llr, PIMathVectorT3d & xyz); //! \~english Convert geocentric to geodetic //! \~russian Преобразовать геоцентрические в геодезические //! \param llr Input geocentric (latitude, longitude, radius) //! \param llh Output geodetic (latitude, longitude, height) //! \param ell Ellipsoid model (default WGS84) static void convertGeocentricToGeodetic(const PIMathVectorT3d & llr, PIMathVectorT3d & llh, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Convert geodetic to geocentric //! \~russian Преобразовать геодезические в геоцентрические //! \param llh Input geodetic (latitude, longitude, height) //! \param llr Output geocentric (latitude, longitude, radius) //! \param ell Ellipsoid model (default WGS84) static void convertGeodeticToGeocentric(const PIMathVectorT3d & llh, PIMathVectorT3d & llr, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Compute radius of ellipsoid at given latitude //! \~russian Вычислить радиус эллипсоида на заданной широте //! \param geolat Geodetic latitude in degrees //! \param ell Ellipsoid model (default WGS84) //! \return Radius in meters static double radiusEarth(double geolat, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Compute radius of ellipsoid at current position //! \~russian Вычислить радиус эллипсоида в текущей позиции double radiusEarth() const { PIGeoPosition p(*this); p.transformTo(PIGeoPosition::Geodetic); return PIGeoPosition::radiusEarth((*this)[0], p.el); } //! \~english Compute range between two positions //! \~russian Вычислить расстояние между двумя позициями //! \param a First position //! \param b Second position //! \return Range in meters static double range(const PIGeoPosition & a, const PIGeoPosition & b); //! \~english Compute range from this position to another //! \~russian Вычислить расстояние от этой позиции до другой //! \param p Target position //! \return Range in meters double range(const PIGeoPosition & p) const { return range((*this), p); } //! \~english Compute elevation angle to target position //! \~russian Вычислить угол возвышения до целевой позиции //! \param p Target position //! \return Elevation angle in degrees double elevation(const PIGeoPosition & p) const; //! \~english Compute geodetic elevation angle to target position //! \~russian Вычислить геодезический угол возвышения до целевой позиции //! \param p Target position //! \return Elevation angle in degrees double elevationGeodetic(const PIGeoPosition & p) const; //! \~english Compute azimuth angle to target position //! \~russian Вычислить азимут до целевой позиции //! \param p Target position //! \return Azimuth angle in degrees double azimuth(const PIGeoPosition & p) const; //! \~english Compute geodetic azimuth angle to target position //! \~russian Вычислить геодезический азимут до целевой позиции //! \param p Target position //! \return Azimuth angle in degrees double azimuthGeodetic(const PIGeoPosition & p) const; //! \~english Get radius of curvature of the meridian //! \~russian Получить радиус кривизны меридиана //! \return Radius in meters double getCurvMeridian() const; //! \~english Get radius of curvature in the prime vertical //! \~russian Получить радиус кривизны в вертикале //! \return Radius in meters double getCurvPrimeVertical() const; //! \~english Get as PIMathVectorT3d //! \~russian Получить как PIMathVectorT3d //! \return Reference to underlying vector const PIMathVectorT3d & vector() const { return *this; } //! \~english Assignment from vector //! \~russian Присваивание из вектора PIGeoPosition & operator=(const PIMathVectorT3d & v); //! \~english Subtraction //! \~russian Вычитание PIGeoPosition & operator-=(const PIGeoPosition & right); //! \~english Addition //! \~russian Сложение PIGeoPosition & operator+=(const PIGeoPosition & right); //! \~english Subtraction //! \~russian Вычитание friend PIGeoPosition operator-(const PIGeoPosition & left, const PIGeoPosition & right); //! \~english Addition //! \~russian Сложение friend PIGeoPosition operator+(const PIGeoPosition & left, const PIGeoPosition & right); //! \~english Scalar multiplication //! \~russian Умножение на скаляр friend PIGeoPosition operator*(const double & scale, const PIGeoPosition & right); friend PIGeoPosition operator*(const PIGeoPosition & left, const double & scale); friend PIGeoPosition operator*(const int & scale, const PIGeoPosition & right); friend PIGeoPosition operator*(const PIGeoPosition & left, const int & scale); //! \~english Equality comparison //! \~russian Сравнение на равенство bool operator==(const PIGeoPosition & right) const; //! \~english Inequality comparison //! \~russian Сравнение на неравенство bool operator!=(const PIGeoPosition & right) const { return !(operator==(right)); } private: void initialize(PIMathVectorT3d v, CoordinateSystem sys = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); PIEllipsoidModel el; CoordinateSystem s; }; inline PIGeoPosition operator-(const PIGeoPosition & left, const PIGeoPosition & right) { PIGeoPosition l(left), r(right); l.transformTo(PIGeoPosition::Cartesian); r.transformTo(PIGeoPosition::Cartesian); l -= r; return l; } inline PIGeoPosition operator+(const PIGeoPosition & left, const PIGeoPosition & right) { PIGeoPosition l(left), r(right); l.transformTo(PIGeoPosition::Cartesian); r.transformTo(PIGeoPosition::Cartesian); l += r; return l; } inline PIGeoPosition operator*(const double & scale, const PIGeoPosition & right) { PIMathVectorT3d tmp(right); tmp *= scale; return PIGeoPosition(tmp); } inline PIGeoPosition operator*(const PIGeoPosition & left, const double & scale) { return operator*(scale, left); } inline PIGeoPosition operator*(const int & scale, const PIGeoPosition & right) { return operator*(double(scale), right); } inline PIGeoPosition operator*(const PIGeoPosition & left, const int & scale) { return operator*(double(scale), left); } #endif // PIGEOPOSITION_H