swift
coordinategeodetic.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_GEO_COORDINATEGEODETIC_H
7 #define SWIFT_MISC_GEO_COORDINATEGEODETIC_H
8 
9 #include <array>
10 
11 #include <QString>
12 #include <QVector3D>
13 
14 #include "misc/aviation/altitude.h"
15 #include "misc/geo/latitude.h"
16 #include "misc/geo/longitude.h"
17 #include "misc/math/mathutils.h"
18 #include "misc/metaclass.h"
19 #include "misc/pq/angle.h"
20 #include "misc/pq/length.h"
21 #include "misc/pq/units.h"
22 #include "misc/propertyindexref.h"
23 #include "misc/swiftmiscexport.h"
24 #include "misc/valueobject.h"
25 
26 SWIFT_DECLARE_VALUEOBJECT_MIXINS(swift::misc::geo, CCoordinateGeodetic)
27 
28 namespace swift::misc
29 {
30  namespace geo
31  {
39  {
40  public:
43  {
44  IndexLatitude = CPropertyIndexRef::GlobalIndexICoordinateGeodetic,
45  IndexLongitude,
46  IndexLatitudeAsString,
47  IndexLongitudeAsString,
48  IndexGeodeticHeight,
49  IndexGeodeticHeightAsString,
50  IndexNormalVector
51  };
52 
54  ICoordinateGeodetic() = default;
55 
57  virtual ~ICoordinateGeodetic();
58 
61 
64 
66  virtual CLatitude latitude() const = 0;
67 
69  virtual CLongitude longitude() const = 0;
70 
80  virtual const aviation::CAltitude &geodeticHeight() const = 0;
81 
86  virtual QVector3D normalVector() const = 0;
87 
89  virtual std::array<double, 3> normalVectorDouble() const = 0;
90 
92  bool equalNormalVectorDouble(const std::array<double, 3> &otherVector) const;
93 
95  bool equalNormalVectorDouble(const ICoordinateGeodetic &otherCoordinate) const;
96 
98  QString latitudeAsString() const { return this->latitude().toQString(true); }
99 
101  QString longitudeAsString() const { return this->longitude().toQString(true); }
102 
104  QString geodeticHeightAsString() const { return this->geodeticHeight().toQString(true); }
105 
107  bool isGeodeticHeightNull() const { return this->geodeticHeight().isNull(); }
108 
110  bool hasMSLGeodeticHeight() const { return this->geodeticHeight().hasMeanSeaLevelValue(); }
111 
115  virtual bool isNull() const { return this->normalVector().isNull(); }
116 
118  physical_quantities::CLength calculateGreatCircleDistance(const ICoordinateGeodetic &otherCoordinate) const;
119 
121  bool isWithinRange(const ICoordinateGeodetic &otherCoordinate,
122  const physical_quantities::CLength &range) const;
123 
125  physical_quantities::CAngle calculateBearing(const ICoordinateGeodetic &otherCoordinate) const;
126 
128  QVariant propertyByIndex(CPropertyIndexRef index) const;
129 
131  int comparePropertyByIndex(CPropertyIndexRef index, const ICoordinateGeodetic &compareValue) const;
132 
134  QString convertToQString(bool i18n = false) const;
135 
138  bool isNaNVector() const;
139  bool isNaNVectorDouble() const;
140  bool isInfVector() const;
141  bool isInfVectorDouble() const;
142  bool isValidVectorRange() const;
143  static bool isValidVector(const std::array<double, 3> &v);
145 
146  protected:
148  static bool canHandleIndex(CPropertyIndexRef index);
149  };
150 
153  calculateGreatCircleDistance(const ICoordinateGeodetic &coordinate1, const ICoordinateGeodetic &coordinate2);
154 
156  SWIFT_MISC_EXPORT physical_quantities::CAngle calculateBearing(const ICoordinateGeodetic &coordinate1,
157  const ICoordinateGeodetic &coordinate2);
158 
160  SWIFT_MISC_EXPORT double calculateEuclideanDistance(const ICoordinateGeodetic &coordinate1,
161  const ICoordinateGeodetic &coordinate2);
162 
164  SWIFT_MISC_EXPORT double calculateEuclideanDistanceSquared(const ICoordinateGeodetic &coordinate1,
165  const ICoordinateGeodetic &coordinate2);
166 
170  {
171  public:
174  {
175  IndexRelativeDistance = CPropertyIndexRef::GlobalIndexICoordinateWithRelativePosition,
176  IndexRelativeBearing
177  };
178 
180  const physical_quantities::CLength &getRelativeDistance() const { return m_relativeDistance; }
181 
183  void setRelativeDistance(const physical_quantities::CLength &distance) { m_relativeDistance = distance; }
184 
186  const physical_quantities::CAngle &getRelativeBearing() const { return m_relativeBearing; }
187 
189  void setRelativeBearing(const physical_quantities::CAngle &angle) { m_relativeBearing = angle; }
190 
192  bool hasValidRelativeDistance() const { return !m_relativeDistance.isNull(); }
193 
195  bool hasValidRelativeBearing() const { return !m_relativeBearing.isNull(); }
196 
198  physical_quantities::CLength calculcateAndUpdateRelativeDistance(const geo::ICoordinateGeodetic &position);
199 
202  calculcateAndUpdateRelativeDistanceAndBearing(const geo::ICoordinateGeodetic &position);
203 
205  QVariant propertyByIndex(CPropertyIndexRef index) const;
206 
208  void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant);
209 
211  int comparePropertyByIndex(CPropertyIndexRef index,
212  const ICoordinateWithRelativePosition &compareValue) const;
213 
215  QString convertToQString(bool i18n = false) const;
216 
217  protected:
220 
222  static bool canHandleIndex(CPropertyIndexRef index);
223 
224  physical_quantities::CAngle m_relativeBearing { 0, nullptr };
225  physical_quantities::CLength m_relativeDistance { 0, nullptr };
226  };
227 
230  public CValueObject<CCoordinateGeodetic>,
231  public ICoordinateGeodetic
232  {
233  public:
236 
238  CCoordinateGeodetic(const QVector3D &normal)
239  : m_x(static_cast<double>(normal.x())), m_y(static_cast<double>(normal.y())),
240  m_z(static_cast<double>(normal.z()))
241  {}
242 
244  CCoordinateGeodetic(const std::array<double, 3> &normalVector);
245 
247  CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude);
248 
250  CCoordinateGeodetic(const CLatitude &latitude, const CLongitude &longitude,
251  const aviation::CAltitude &geodeticHeight);
252 
254  CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees);
255 
257  CCoordinateGeodetic(double latitudeDegrees, double longitudeDegrees, double heightFeet);
258 
260  CCoordinateGeodetic(const ICoordinateGeodetic &coordinate);
261 
263  CCoordinateGeodetic calculatePosition(const physical_quantities::CLength &distance,
264  const physical_quantities::CAngle &relBearing) const;
265 
267  virtual CLatitude latitude() const override;
268 
270  virtual CLongitude longitude() const override;
271 
273  virtual const aviation::CAltitude &geodeticHeight() const override { return m_geodeticHeight; }
274 
276  virtual QVector3D normalVector() const override;
277 
279  virtual std::array<double, 3> normalVectorDouble() const override;
280 
282  QVariant propertyByIndex(CPropertyIndexRef index) const;
283 
285  void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant);
286 
288  int comparePropertyByIndex(CPropertyIndexRef index, const CCoordinateGeodetic &compareValue) const;
289 
291  CCoordinateGeodetic &switchUnit(const physical_quantities::CLengthUnit &unit);
292 
294  void setLatitude(const CLatitude &latitude);
295 
297  void setLatitudeFromWgs84(const QString &wgs);
298 
300  void setLongitude(const CLongitude &longitude);
301 
303  void setLongitudeFromWgs84(const QString &wgs);
304 
306  void setLatLong(const CLatitude &latitude, const CLongitude &longitude);
307 
309  void setLatLongFromWgs84(const QString &latitude, const QString &longitude);
310 
312  void setGeodeticHeight(const aviation::CAltitude &height) { m_geodeticHeight = height; }
313 
315  void setGeodeticHeightToNull();
316 
318  void setNormalVector(const QVector3D &normal)
319  {
320  m_x = static_cast<double>(normal.x());
321  m_y = static_cast<double>(normal.y());
322  m_z = static_cast<double>(normal.z());
323  }
324 
326  void setNormalVector(double x, double y, double z)
327  {
328  m_x = x;
329  m_y = y;
330  m_z = z;
331  }
332 
334  void setNormalVector(const std::array<double, 3> &normalVector);
335 
337  int clampVector();
338 
340  void setNull()
341  {
342  this->setNormalVector(0, 0, 0);
343  m_geodeticHeight.setNull();
344  }
345 
347  virtual bool isNull() const override
348  {
349  if (m_geodeticHeight.isNull()) { return true; }
352  }
353 
355  static CCoordinateGeodetic fromWgs84(const QString &latitudeWgs84, const QString &longitudeWgs84,
356  const aviation::CAltitude &geodeticHeight = {});
357 
359  static const CCoordinateGeodetic &null();
360 
362  QString convertToQString(bool i18n = false) const;
363 
364  private:
365  // Coordinates are stored using `double` internally and use `double` for most calculations.
366  // They use `double` when converting to and from lat/lon representation.
367  // `QVector3D` is only used for calculating distance and bearing.
368  double m_x = 0;
369  double m_y = 0;
370  double m_z = 0;
371  aviation::CAltitude m_geodeticHeight { 0, nullptr };
372 
374  CCoordinateGeodetic,
375  SWIFT_METAMEMBER(x),
376  SWIFT_METAMEMBER(y),
377  SWIFT_METAMEMBER(z),
378  SWIFT_METAMEMBER(geodeticHeight));
379  };
380  } // namespace geo
381 
383  template <>
384  struct TString<geo::ICoordinateGeodetic>
385  {
386  static QString toQString(const geo::ICoordinateGeodetic &coord) { return coord.convertToQString(); }
387  };
389 } // namespace swift::misc
390 
391 Q_DECLARE_METATYPE(swift::misc::geo::CCoordinateGeodetic)
392 
393 #endif // SWIFT_MISC_GEO_COORDINATEGEODETIC_H
Non-owning reference to a CPropertyIndex with a subset of its features.
Mix of the most commonly used mixin classes.
Definition: valueobject.h:114
Altitude as used in aviation, can be AGL or MSL altitude.
Definition: altitude.h:52
void setNormalVector(double x, double y, double z)
Set normal vector.
CCoordinateGeodetic()
Default constructor (null coordinate)
virtual const aviation::CAltitude & geodeticHeight() const
Height, ellipsoidal or geodetic height (used in GPS)
virtual bool isNull() const
Is null?
void setGeodeticHeight(const aviation::CAltitude &height)
Set height (ellipsoidal or geodetic height)
void setNormalVector(const QVector3D &normal)
Set normal vector.
CCoordinateGeodetic(const QVector3D &normal)
Constructor by normal vector.
Geodetic coordinate, a position in 3D space relative to the reference geoid.
virtual QVector3D normalVector() const =0
Normal vector.
bool hasMSLGeodeticHeight() const
Geodetic height not null and aviation::CAltitude::MeanSeaLevel.
ICoordinateGeodetic(const ICoordinateGeodetic &)=default
Copy constructor.
virtual CLongitude longitude() const =0
Longitude.
virtual std::array< double, 3 > normalVectorDouble() const =0
Normal vector with double precision.
QString longitudeAsString() const
Longitude as string.
virtual bool isNull() const
Is null, means vector x, y, z == 0.
ICoordinateGeodetic & operator=(const ICoordinateGeodetic &)=default
Copy assignment operator.
virtual const aviation::CAltitude & geodeticHeight() const =0
Height, ellipsoidal or geodetic height (used in GPS)
QString latitudeAsString() const
Latitude as string.
QString geodeticHeightAsString() const
Height as string.
bool isGeodeticHeightNull() const
Geodetic height null?
virtual CLatitude latitude() const =0
Latitude.
Interface (actually more an abstract class) of coordinates and relative position to something (normal...
const physical_quantities::CLength & getRelativeDistance() const
Get the distance.
void setRelativeDistance(const physical_quantities::CLength &distance)
Set relative distance.
const physical_quantities::CAngle & getRelativeBearing() const
Get the relative bearing.
void setRelativeBearing(const physical_quantities::CAngle &angle)
Set bearing to own plane.
static bool epsilonZeroLimits(double v)
Epsilon safe zero.
Definition: mathutils.h:48
Physical unit angle (radians, degrees)
Definition: angle.h:23
Physical unit length (length)
Definition: length.h:18
Specialized class for distance units (meter, foot, nautical miles).
Definition: units.h:95
#define SWIFT_METAMEMBER(MEMBER,...)
Macro to define an element within a metaclass.
Definition: metaclass.h:73
#define SWIFT_METACLASS(CLASS,...)
Macro to define a nested metaclass that describes the attributes of its enclosing class.
Definition: metaclass.h:53
Free functions in swift::misc.
#define SWIFT_MISC_EXPORT
Export a class or function from the library.
#define SWIFT_DECLARE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template declaration of mixins for a CValueObject subclass to be placed near the top of the ...
Definition: valueobject.h:65