Marble

GeoDataCoordinates.h
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <[email protected]>
4 // SPDX-FileCopyrightText: 2007-2008 Inge Wallin <[email protected]>
5 // SPDX-FileCopyrightText: 2008 Patrick Spendrin <[email protected]>
6 // SPDX-FileCopyrightText: 2015 Alejandro Garcia Montoro <[email protected]>
7 //
8 
9 
10 #ifndef MARBLE_GEODATACOORDINATES_H
11 #define MARBLE_GEODATACOORDINATES_H
12 
13 #include <QCoreApplication>
14 #include <QMetaType>
15 #include <QVector>
16 
17 #include "geodata_export.h"
18 #include "MarbleGlobal.h"
19 
20 class QString;
21 
22 namespace Marble
23 {
24 
25 class GeoDataCoordinatesPrivate;
26 class Quaternion;
27 
28 /**
29  * @short A 3d point representation
30  *
31  * GeoDataCoordinates is the simple representation of a single three
32  * dimensional point. It can be used all through out marble as the data type
33  * for three dimensional objects. it comprises of a Quaternion for speed issues.
34  * This class was introduced to reflect the difference between a simple 3d point
35  * and the GeoDataGeometry object containing such a point. The latter is a
36  * GeoDataPoint and is simply derived from GeoDataCoordinates.
37  * @see GeoDataPoint
38 */
39 
40 class GEODATA_EXPORT GeoDataCoordinates
41 {
42  Q_DECLARE_TR_FUNCTIONS(GeoDataCoordinates)
43 
44  public:
45  /**
46  * @brief enum used constructor to specify the units used
47  *
48  * Internally we always use radian for mathematical convenience.
49  * However the Marble's interfaces to the outside should default
50  * to degrees.
51  */
52  enum Unit{
53  Radian,
54  Degree
55  };
56 
57  /**
58  * @brief enum used to specify the notation / numerical system
59  *
60  * For degrees there exist two notations:
61  * "Decimal" (base-10) and the "Sexagesimal DMS" (base-60) which is
62  * traditionally used in cartography. Decimal notation
63  * uses floating point numbers to specify parts of a degree. The
64  * Sexagesimal DMS notation uses integer based
65  * Degrees-(Arc)Minutes-(Arc)Seconds to describe parts of a degree.
66  */
67  enum Notation{
68  Decimal, ///< "Decimal" notation (base-10)
69  DMS, ///< "Sexagesimal DMS" notation (base-60)
70  DM, ///< "Sexagesimal DM" notation (base-60)
71  UTM,
72  Astro /// < "RA and DEC" notation (used for astronomical sky coordinates)
73  };
74 
75  /**
76  * @brief The BearingType enum specifies where to measure the bearing
77  * along great circle arcs
78  *
79  * When traveling along a great circle arc defined by the two points
80  * A and B, the bearing varies along the arc. The "InitialBearing" bearing
81  * corresponds to the bearing value at A, the "FinalBearing" bearing to that
82  * at B.
83  */
84  enum BearingType {
85  InitialBearing,
86  FinalBearing
87  };
88 
89  // Type definitions
92 
93  GeoDataCoordinates( const GeoDataCoordinates& other );
94 
95  /**
96  * @brief constructs an invalid instance
97  *
98  * Constructs an invalid instance such that calling isValid()
99  * on it will return @code false @endcode.
100  */
102 
103  /**
104  * @brief create a geocoordinate from longitude and latitude
105  * @param lon longitude
106  * @param lat latitude
107  * @param alt altitude in meters (default: 0)
108  * @param unit units that lon and lat get measured in
109  * (default for Radian: north pole at pi/2, southpole at -pi/2)
110  * @param detail detail (default: 0)
111  */
112  GeoDataCoordinates( qreal lon, qreal lat, qreal alt = 0,
113  GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian,
114  int detail = 0 );
115 
116  virtual ~GeoDataCoordinates();
117 
118  /**
119  * @brief Returns @code true @endcode if the coordinate is valid, @code false @endcode otherwise.
120  * @return whether the coordinate is valid
121  *
122  * A coordinate is valid, if at least one component has been set and the last
123  * assignment was not an invalid GeoDataCoordinates object.
124  */
125  bool isValid() const;
126 
127  /**
128  * @brief (re)set the coordinates in a GeoDataCoordinates object
129  * @param lon longitude
130  * @param lat latitude
131  * @param alt altitude in meters (default: 0)
132  * @param unit units that lon and lat get measured in
133  * (default for Radian: north pole at pi/2, southpole at -pi/2)
134  */
135  void set( qreal lon, qreal lat, qreal alt = 0,
136  GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian );
137 
138  /**
139  * @brief use this function to get the longitude and latitude with one
140  * call - use the unit parameter to switch between Radian and DMS
141  * @param lon longitude
142  * @param lat latitude
143  * @param unit units that lon and lat get measured in
144  * (default for Radian: north pole at pi/2, southpole at -pi/2)
145  */
146  void geoCoordinates(qreal& lon, qreal& lat, GeoDataCoordinates::Unit unit) const;
147  void geoCoordinates(qreal& lon, qreal& lat) const;
148 
149  /**
150  * @brief use this function to get the longitude, latitude and altitude
151  * with one call - use the unit parameter to switch between Radian and DMS
152  * @param lon longitude
153  * @param lat latitude
154  * @param alt altitude in meters
155  * @param unit units that lon and lat get measured in
156  * (default for Radian: north pole at pi/2, southpole at -pi/2)
157  */
158  void geoCoordinates(qreal& lon, qreal& lat, qreal& alt, GeoDataCoordinates::Unit unit) const;
159  void geoCoordinates(qreal& lon, qreal& lat, qreal& alt) const;
160 
161  /**
162  * @brief set the longitude in a GeoDataCoordinates object
163  * @param lon longitude
164  * @param unit units that lon and lat get measured in
165  * (default for Radian: north pole at pi/2, southpole at -pi/2)
166  */
167  void setLongitude( qreal lon,
168  GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian );
169 
170  /**
171  * @brief retrieves the longitude of the GeoDataCoordinates object
172  * use the unit parameter to switch between Radian and DMS
173  * @param unit units that lon and lat get measured in
174  * (default for Radian: north pole at pi/2, southpole at -pi/2)
175  * @return longitude
176  */
177  qreal longitude(GeoDataCoordinates::Unit unit) const;
178  qreal longitude() const;
179 
180  /**
181  * @brief retrieves the latitude of the GeoDataCoordinates object
182  * use the unit parameter to switch between Radian and DMS
183  * @param unit units that lon and lat get measured in
184  * (default for Radian: north pole at pi/2, southpole at -pi/2)
185  * @return latitude
186  */
187  qreal latitude( GeoDataCoordinates::Unit unit ) const;
188  qreal latitude() const;
189 
190  /**
191  * @brief set the longitude in a GeoDataCoordinates object
192  * @param lat longitude
193  * @param unit units that lon and lat get measured in
194  * (default for Radian: north pole at pi/2, southpole at -pi/2)
195  */
196  void setLatitude( qreal lat,
197  GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian );
198 
199  /**
200  * @brief return the altitude of the Point in meters
201  */
202  qreal altitude() const;
203  /**
204  * @brief set the altitude of the Point in meters
205  * @param altitude altitude
206  */
207  void setAltitude( const qreal altitude );
208 
209  /**
210  * @brief retrieves the UTM zone of the GeoDataCoordinates object.
211  * If the point is located on one of the poles (latitude < 80S or
212  * latitude > 84N) there is no UTM zone associated; in this case,
213  * 0 is returned.
214  * @return UTM zone.
215  */
216  int utmZone() const;
217 
218  /**
219  * @brief retrieves the UTM easting of the GeoDataCoordinates object,
220  * in meters.
221  * @return UTM easting
222  */
223  qreal utmEasting() const;
224 
225  /**
226  * @brief retrieves the UTM latitude band of the GeoDataCoordinates object
227  * @return UTM latitude band
228  */
229  QString utmLatitudeBand() const;
230 
231  /**
232  * @brief retrieves the UTM northing of the GeoDataCoordinates object,
233  * in meters
234  * @return UTM northing
235  */
236  qreal utmNorthing() const;
237 
238  /**
239  * @brief return the detail flag
240  * detail range: 0 for most important points, 5 for least important
241  */
242  quint8 detail() const;
243 
244  /**
245  * @brief set the detail flag
246  * @param detail detail
247  */
248  void setDetail(quint8 detail);
249 
250  /**
251  * @brief Rotates one coordinate around another.
252  * @param axis The coordinate that serves as a rotation axis
253  * @param angle Rotation angle
254  * @param unit Unit of the result
255  * @return The coordinate rotated in anticlockwise direction
256  */
257  GeoDataCoordinates rotateAround( const GeoDataCoordinates &axis, qreal angle, Unit unit = Radian ) const;
258 
259  GeoDataCoordinates rotateAround(const Quaternion &rotAxis) const;
260 
261  /**
262  * @brief Returns the bearing (true bearing, the angle between the line defined
263  * by this point and the other and the prime meridian)
264  * @param other The second point that, together with this point, defines a line
265  * @param unit Unit of the result
266  * @param type Type of the bearing
267  * @return The true bearing in the requested unit, not range normalized,
268  * in clockwise direction, with the value 0 corresponding to north
269  */
270  qreal bearing( const GeoDataCoordinates &other, Unit unit = Radian, BearingType type = InitialBearing ) const;
271 
272  /**
273  * @brief Returns the coordinates of the resulting point after moving this point
274  * according to the distance and bearing parameters
275  * @param bearing the same as above
276  * @param distance the distance on a unit sphere
277  */
278  GeoDataCoordinates moveByBearing( qreal bearing, qreal distance ) const;
279 
280  /**
281  * @brief return a Quaternion with the used coordinates
282  */
283  const Quaternion &quaternion() const;
284 
285  /**
286  * @brief slerp (spherical linear) interpolation between this coordinate and the given target coordinate
287  * @param target Destination coordinate
288  * @param t Fraction 0..1 to weight between this and target
289  * @return Interpolated coordinate between this (t<=0.0) and target (t>=1.0)
290  */
291  GeoDataCoordinates interpolate( const GeoDataCoordinates &target, double t ) const;
292 
293  /**
294  * @brief nlerp (normalized linear interpolation) between this coordinates and the given target coordinates
295  * @param target Destination coordinates
296  * @param t Fraction 0..1 to weight between this and target
297  * @return Interpolated coordinate between this (t<=0.0) and target (t>=1.0)
298  */
299  GeoDataCoordinates nlerp(const GeoDataCoordinates &target, double t) const;
300 
301  /**
302  * @brief squad (spherical and quadrangle) interpolation between b and c
303  * @param before First base point
304  * @param target Third base point (second interpolation point)
305  * @param after Fourth base point
306  * @param t Offset between b (t<=0) and c (t>=1)
307  */
308  GeoDataCoordinates interpolate( const GeoDataCoordinates &before, const GeoDataCoordinates &target, const GeoDataCoordinates &after, double t ) const;
309 
310  /**
311  * @brief return whether our coordinates represent a pole
312  * This method can be used to check whether the coordinate equals one of
313  * the poles.
314  */
315  bool isPole( Pole = AnyPole ) const;
316 
317  /**
318  * @brief This method calculates the shortest distance between two points on a sphere.
319  * @brief See: https://en.wikipedia.org/wiki/Great-circle_distance
320  */
321  qreal sphericalDistanceTo(const GeoDataCoordinates &other) const;
322 
323  /**
324  * @brief return Notation of string representation
325  */
326  static GeoDataCoordinates::Notation defaultNotation();
327 
328  /**
329  * @brief set the Notation of the string representation
330  * @param notation Notation
331  */
332  static void setDefaultNotation( GeoDataCoordinates::Notation notation );
333 
334  /**
335  * @brief normalize the longitude to always be -M_PI <= lon <= +M_PI (Radian).
336  * @param lon longitude
337  * @param unit unit of the result
338  */
339  static qreal normalizeLon( qreal lon,
340  GeoDataCoordinates::Unit = GeoDataCoordinates::Radian );
341 
342  /**
343  * @brief normalize latitude to always be in -M_PI / 2. <= lat <= +M_PI / 2 (Radian).
344  * @param lat latitude
345  * @param unit unit of the result
346  */
347  static qreal normalizeLat( qreal lat,
348  GeoDataCoordinates::Unit = GeoDataCoordinates::Radian );
349 
350  /**
351  * @brief normalize both longitude and latitude at the same time
352  * This method normalizes both latitude and longitude, so that the
353  * latitude and the longitude stay within the "usual" range.
354  * NOTE: If the latitude exceeds M_PI/2 (+90.0 deg) or -M_PI/2 (-90.0 deg)
355  * then this will be interpreted as a pole traversion where the point will
356  * end up on the opposite side of the globe. Therefore the longitude will
357  * change by M_PI (180 deg).
358  * If you don't want this behaviour use both normalizeLat() and
359  * normalizeLon() instead.
360  * @param lon the longitude value
361  * @param lat the latitude value
362  * @param unit unit of the result
363  */
364  static void normalizeLonLat( qreal &lon, qreal &lat,
365  GeoDataCoordinates::Unit = GeoDataCoordinates::Radian );
366 
367  /**
368  * @brief try to parse the string into a coordinate pair
369  * @param string the string
370  * @param successful becomes true if the conversion succeeds
371  * @return the geodatacoordinates
372  */
373  static GeoDataCoordinates fromString( const QString &string, bool& successful );
374 
375  /**
376  * @brief return a string representation of the coordinate
377  * this is a convenience function which uses the default notation
378  */
379  QString toString() const;
380 
381  /**
382  * @brief return a string with the notation given by notation
383  *
384  * @param notation set a notation different from the default one
385  * @param precision set the number of digits below degrees.
386  * The precision depends on the current notation:
387  * For Decimal representation the precision is the number of
388  * digits after the decimal point.
389  * In DMS a precision of 1 or 2 shows the arc minutes; a precision
390  * of 3 or 4 will show arc seconds. A precision beyond that will
391  * increase the number of digits after the arc second decimal point.
392  */
393  QString toString( GeoDataCoordinates::Notation notation, int precision = -1 ) const;
394 
395  static QString lonToString( qreal lon, GeoDataCoordinates::Notation notation,
396  GeoDataCoordinates::Unit unit = Radian,
397  int precision = -1,
398  char format = 'f' );
399  /**
400  * @brief return a string representation of longitude of the coordinate
401  * convenience function that uses the default notation
402  */
403  QString lonToString() const;
404 
405  static QString latToString( qreal lat, GeoDataCoordinates::Notation notation,
406  GeoDataCoordinates::Unit unit = Radian,
407  int precision = -1,
408  char format = 'f' );
409  /**
410  * @brief return a string representation of latitude of the coordinate
411  * convenience function that uses the default notation
412  */
413  QString latToString() const;
414 
415  bool operator==(const GeoDataCoordinates &other) const;
416  bool operator!=(const GeoDataCoordinates &other) const;
417 
418  GeoDataCoordinates& operator=( const GeoDataCoordinates &other );
419 
420  /** Serialize the contents of the feature to @p stream. */
421  void pack(QDataStream &stream) const;
422  /** Unserialize the contents of the feature from @p stream. */
423  void unpack(QDataStream &stream);
424 
425  private:
426  void detach();
427 
428  GeoDataCoordinatesPrivate *d;
429 
430  static GeoDataCoordinates::Notation s_notation;
431  static const GeoDataCoordinates null;
432 };
433 
434 GEODATA_EXPORT uint qHash(const GeoDataCoordinates& coordinates );
435 
436 
437 }
438 
439 Q_DECLARE_METATYPE( Marble::GeoDataCoordinates )
440 
441 #endif
Unit
enum used constructor to specify the units used
Any pole.
Definition: MarbleGlobal.h:140
A 3d point representation.
Binds a QML item to a specific geodetic location in screen coordinates.
"Decimal" notation (base-10)
BearingType
The BearingType enum specifies where to measure the bearing along great circle arcs.
PartitionTable::TableType type
KCALENDARCORE_EXPORT uint qHash(const KCalendarCore::Period &key)
Notation
enum used to specify the notation / numerical system
"Sexagesimal DMS" notation (base-60)
"Sexagesimal DM" notation (base-60)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Nov 29 2021 23:11:02 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.