//! \~\ingroup Geo //! \~\file pigeoposition.h //! \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" //! \~\ingroup Geo //! \~\brief //! \~english Geographic position represented in one of several coordinate systems. //! \~russian Географическая позиция, представленная в одной из нескольких систем координат. //! \details //! \~english This class provides functionality for storing and converting between different coordinate systems including geodetic, //! geocentric, Cartesian, and spherical coordinates. It supports various ellipsoid models for Earth representation. //! \~russian Этот класс предоставляет функциональность для хранения и преобразования между различными системами координат, включая //! геодезическую, геоцентрическую, декартову и сферическую. Он поддерживает различные модели эллипсоида для представления Земли. class PIP_EXPORT PIGeoPosition: public PIMathVectorT3d { public: //! \~english Coordinate system used by stored components. //! \~russian Система координат, используемая для хранимых компонент. enum CoordinateSystem { Unknown = 0 /** \~english Unknown coordinate system \~russian Неизвестная система координат */, Geodetic /** \~english Geodetic latitude, longitude and height above the ellipsoid \~russian Геодезическая широта, долгота и высота над эллипсоидом */ , Geocentric /** \~english Geocentric latitude, longitude and radius \~russian Геоцентрическая широта, долгота и радиус */, Cartesian /** \~english Earth-centered Earth-fixed Cartesian coordinates \~russian Декартовы координаты ECEF */, Spherical /** \~english Spherical coordinates as theta, phi and radius \~russian Сферические координаты: тета, фи и радиус */ }; //! \~english One centimeter tolerance in meters. //! \~russian Допуск в один сантиметр в метрах. static const double one_cm_tolerance; //! \~english One millimeter tolerance in meters. //! \~russian Допуск в один миллиметр в метрах. static const double one_mm_tolerance; //! \~english One micron tolerance in meters. //! \~russian Допуск в один микрон в метрах. static const double one_um_tolerance; //! \~english Default comparison and singularity tolerance in meters. //! \~russian Допуск по умолчанию для сравнений и вырожденных случаев, в метрах. static double position_tolerance; //! \~english Sets the default tolerance in meters. //! \~russian Устанавливает допуск по умолчанию в метрах. static double setPositionTolerance(const double tol) { position_tolerance = tol; return position_tolerance; } //! \~english Returns the default tolerance in meters. //! \~russian Возвращает допуск по умолчанию в метрах. static double getPositionTolerance() { return position_tolerance; } //! \~english Constructs the zero position in Cartesian coordinates. //! \~russian Создает нулевую позицию в декартовой системе координат. PIGeoPosition(); //! \~english Constructs a position from three components in the selected coordinate system. //! \~russian Создает позицию из трех компонент в выбранной системе координат. PIGeoPosition(double a, double b, double c, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Constructs a position from an existing 3D vector. //! \~russian Создает позицию из существующего трехмерного вектора. PIGeoPosition(PIMathVectorT3d v, CoordinateSystem s = Cartesian, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Converts the stored value to another coordinate system in place. //! \~russian Преобразует хранимое значение в другую систему координат на месте. PIGeoPosition & transformTo(CoordinateSystem sys); //! \~english Converts this position to geodetic coordinates. //! \~russian Преобразует позицию в геодезические координаты. PIGeoPosition & asGeodetic() { transformTo(Geodetic); return *this; } //! \~english Switches to another ellipsoid and converts to geodetic coordinates. //! \~russian Переключает эллипсоид и преобразует позицию в геодезические координаты. PIGeoPosition & asGeodetic(const PIEllipsoidModel & ell) { setEllipsoidModel(ell); transformTo(Geodetic); return *this; } //! \~english Converts this position to Cartesian ECEF coordinates. //! \~russian Преобразует позицию в декартовы координаты ECEF. PIGeoPosition & asECEF() { transformTo(Cartesian); return *this; } //! \~english Returns the X component in Cartesian ECEF coordinates. //! \~russian Возвращает компоненту X в декартовых координатах ECEF. double x() const; //! \~english Returns the Y component in Cartesian ECEF coordinates. //! \~russian Возвращает компоненту Y в декартовых координатах ECEF. double y() const; //! \~english Returns the Z component in Cartesian ECEF coordinates. //! \~russian Возвращает компоненту Z в декартовых координатах ECEF. double z() const; //! \~english Returns geodetic latitude in degrees. //! \~russian Возвращает геодезическую широту в градусах. double latitudeGeodetic() const; //! \~english Returns geocentric latitude in degrees. //! \~russian Возвращает геоцентрическую широту в градусах. double latitudeGeocentric() const; //! \~english Returns longitude in degrees. //! \~russian Возвращает долготу в градусах. double longitude() const; //! \~english Returns spherical theta angle in degrees (angle from Z axis). //! \~russian Возвращает сферический угол тета в градусах (угол от оси Z). double theta() const; //! \~english Returns spherical phi angle in degrees (angle in XY plane from X axis). //! \~russian Возвращает сферический угол фи в градусах (угол в плоскости XY от оси X). double phi() const; //! \~english Returns radius in meters for spherical or geocentric form (distance from Earth center). //! \~russian Возвращает радиус в метрах для сферического или геоцентрического представления (расстояние от центра Земли). double radius() const; //! \~english Returns geodetic height above the ellipsoid in meters. //! \~russian Возвращает геодезическую высоту над эллипсоидом в метрах. double height() const; //! \~english Sets the ellipsoid model used by geodetic conversions. //! \~russian Устанавливает модель эллипсоида, используемую в геодезических преобразованиях. void setEllipsoidModel(const PIEllipsoidModel & ell) { el = ell; } //! \~english Sets geodetic latitude, longitude and height in degrees/meters. //! \~russian Устанавливает геодезические широту, долготу и высоту в градусах и метрах. PIGeoPosition & setGeodetic(double lat, double lon, double ht, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Sets geocentric latitude, longitude and radius in degrees/meters. //! \~russian Устанавливает геоцентрические широту, долготу и радиус в градусах и метрах. PIGeoPosition & setGeocentric(double lat, double lon, double rad); //! \~english Sets spherical theta, phi and radius in degrees/meters. //! \~russian Устанавливает сферические тета, фи и радиус в градусах и метрах. PIGeoPosition & setSpherical(double theta, double phi, double rad); //! \~english Sets Cartesian ECEF coordinates in meters. //! \~russian Устанавливает декартовы координаты ECEF в метрах. PIGeoPosition & setECEF(double x, double y, double z); //! \~english Converts spherical coordinates to Cartesian ECEF coordinates. //! \~russian Преобразует сферические координаты в декартовы координаты ECEF. static void convertSphericalToCartesian(const PIMathVectorT3d & tpr, PIMathVectorT3d & xyz); //! \~english Converts Cartesian ECEF coordinates to spherical coordinates. //! \~russian Преобразует декартовы координаты ECEF в сферические координаты. static void convertCartesianToSpherical(const PIMathVectorT3d & xyz, PIMathVectorT3d & tpr); //! \~english Converts Cartesian ECEF coordinates to geodetic coordinates. //! \~russian Преобразует декартовы координаты ECEF в геодезические координаты. static void convertCartesianToGeodetic(const PIMathVectorT3d & xyz, PIMathVectorT3d & llh, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Converts geodetic coordinates to Cartesian ECEF coordinates. //! \~russian Преобразует геодезические координаты в декартовы координаты ECEF. static void convertGeodeticToCartesian(const PIMathVectorT3d & llh, PIMathVectorT3d & xyz, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Converts Cartesian ECEF coordinates to geocentric coordinates. //! \~russian Преобразует декартовы координаты ECEF в геоцентрические координаты. static void convertCartesianToGeocentric(const PIMathVectorT3d & xyz, PIMathVectorT3d & llr); //! \~english Converts geocentric coordinates to Cartesian ECEF coordinates. //! \~russian Преобразует геоцентрические координаты в декартовы координаты ECEF. static void convertGeocentricToCartesian(const PIMathVectorT3d & llr, PIMathVectorT3d & xyz); //! \~english Converts geocentric coordinates to geodetic coordinates. //! \~russian Преобразует геоцентрические координаты в геодезические координаты. static void convertGeocentricToGeodetic(const PIMathVectorT3d & llr, PIMathVectorT3d & llh, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Converts geodetic coordinates to geocentric coordinates. //! \~russian Преобразует геодезические координаты в геоцентрические координаты. static void convertGeodeticToGeocentric(const PIMathVectorT3d & llh, PIMathVectorT3d & llr, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Returns ellipsoid radius at the given geodetic latitude. //! \~russian Возвращает радиус эллипсоида на заданной геодезической широте. static double radiusEarth(double geolat, PIEllipsoidModel ell = PIEllipsoidModel::WGS84Ellipsoid()); //! \~english Returns ellipsoid radius for this position. //! \~russian Возвращает радиус эллипсоида для этой позиции. double radiusEarth() const { PIGeoPosition p(*this); p.transformTo(PIGeoPosition::Geodetic); return PIGeoPosition::radiusEarth((*this)[0], p.el); } //! \~english Returns straight-line range between two positions in meters. //! \~russian Возвращает прямую дальность между двумя позициями в метрах. static double range(const PIGeoPosition & a, const PIGeoPosition & b); //! \~english Returns straight-line range to another position in meters. //! \~russian Возвращает прямую дальность до другой позиции в метрах. double range(const PIGeoPosition & p) const { return range((*this), p); } //! \~english Computes elevation to another position. //! \~russian Вычисляет угол места до другой позиции. double elevation(const PIGeoPosition & p) const; //! \~english Computes elevation using local geodetic vertical. //! \~russian Вычисляет угол места относительно локальной геодезической вертикали. double elevationGeodetic(const PIGeoPosition & p) const; //! \~english Computes azimuth to another position. //! \~russian Вычисляет азимут на другую позицию. double azimuth(const PIGeoPosition & p) const; //! \~english Computes azimuth using local geodetic north-east axes. //! \~russian Вычисляет азимут по локальным геодезическим осям север-восток. double azimuthGeodetic(const PIGeoPosition & p) const; //! \~english Returns meridian radius of curvature for this position. //! \~russian Возвращает радиус кривизны меридиана для этой позиции. double getCurvMeridian() const; //! \~english Returns prime-vertical radius of curvature for this position. //! \~russian Возвращает радиус кривизны первого вертикала для этой позиции. double getCurvPrimeVertical() const; //! \~english Returns the underlying three-component vector in the current system. //! \~russian Возвращает базовый трехкомпонентный вектор в текущей системе. const PIMathVectorT3d & vector() const { return *this; } //! \~english Assigns coordinates from a plain 3D vector without changing metadata. //! \~russian Присваивает координаты из обычного 3D-вектора без изменения метаданных. PIGeoPosition & operator=(const PIMathVectorT3d & v); //! \~english Subtracts another position after converting both operands to Cartesian coordinates. //! \~russian Вычитает другую позицию после перевода обоих операндов в декартовы координаты. PIGeoPosition & operator-=(const PIGeoPosition & right); //! \~english Adds another position after converting both operands to Cartesian coordinates. //! \~russian Складывает другую позицию после перевода обоих операндов в декартовы координаты. PIGeoPosition & operator+=(const PIGeoPosition & right); //! \~english Returns Cartesian difference of two positions. //! \~russian Возвращает декартову разность двух позиций. friend PIGeoPosition operator-(const PIGeoPosition & left, const PIGeoPosition & right); //! \~english Returns Cartesian sum of two positions. //! \~russian Возвращает декартову сумму двух позиций. friend PIGeoPosition operator+(const PIGeoPosition & left, const PIGeoPosition & right); //! \~english Scales a position by a floating-point factor. //! \~russian Масштабирует позицию вещественным коэффициентом. friend PIGeoPosition operator*(const double & scale, const PIGeoPosition & right); //! \~english Scales a position by a floating-point factor. //! \~russian Масштабирует позицию вещественным коэффициентом. friend PIGeoPosition operator*(const PIGeoPosition & left, const double & scale); //! \~english Scales a position by an integer factor. //! \~russian Масштабирует позицию целочисленным коэффициентом. friend PIGeoPosition operator*(const int & scale, const PIGeoPosition & right); //! \~english Scales a position by an integer factor. //! \~russian Масштабирует позицию целочисленным коэффициентом. friend PIGeoPosition operator*(const PIGeoPosition & left, const int & scale); //! \~english Compares two positions using the configured tolerance and ellipsoid model. //! \~russian Сравнивает две позиции с учетом настроенного допуска и модели эллипсоида. bool operator==(const PIGeoPosition & right) const; //! \~english Returns true when positions are not equal. //! \~russian Возвращает true, если позиции не равны. 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; }; //! \~english Subtraction //! \~russian Вычитание //! \details //! \~english Subtracts two positions by converting them to Cartesian coordinates and performing element-wise subtraction. //! \~russian Вычитает две позиции путем преобразования их в декартовы координаты и выполнения поэлементного вычитания. 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; } //! \~english Addition //! \~russian Сложение //! \details //! \~english Adds two positions by converting them to Cartesian coordinates and performing element-wise addition. //! \~russian Складывает две позиции путем преобразования их в декартовы координаты и выполнения поэлементного сложения. 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; } //! \~english Scalar multiplication (double) //! \~russian Умножение на скаляр (double) //! \details //! \~english Multiplies a position by a double scalar value. //! \~russian Умножает позицию на скалярное значение типа double. inline PIGeoPosition operator*(const double & scale, const PIGeoPosition & right) { PIMathVectorT3d tmp(right); tmp *= scale; return PIGeoPosition(tmp); } //! \~english Scalar multiplication (double) //! \~russian Умножение на скаляр (double) //! \details //! \~english Multiplies a position by a double scalar value. //! \~russian Умножает позицию на скалярное значение типа double. inline PIGeoPosition operator*(const PIGeoPosition & left, const double & scale) { return operator*(scale, left); } //! \~english Scalar multiplication (int) //! \~russian Умножение на скаляр (int) //! \details //! \~english Multiplies a position by an integer scalar value. //! \~russian Умножает позицию на скалярное значение типа int. inline PIGeoPosition operator*(const int & scale, const PIGeoPosition & right) { return operator*(double(scale), right); } //! \~english Scalar multiplication (int) //! \~russian Умножение на скаляр (int) //! \details //! \~english Multiplies a position by an integer scalar value. //! \~russian Умножает позицию на скалярное значение типа int. inline PIGeoPosition operator*(const PIGeoPosition & left, const int & scale) { return operator*(double(scale), left); } #endif // PIGEOPOSITION_H