GL Studio C++ Runtime API
gls_map_util.h
Go to the documentation of this file.
1 /*! \file
2  \brief Utility classes for GL Studio Map toolkit.
3 
4  \par Copyright Information
5 
6  Copyright (c) 2016 The DiSTI Corporation.<br>
7  11301 Corporate Blvd; Suite 100<br>
8  Orlando, Florida 32817<br>
9  USA<br>
10  <br>
11  All rights reserved.<br>
12 
13  This Software contains proprietary trade secrets of DiSTI and may not be
14 reproduced, in whole or part, in any form, or by any means of electronic,
15 mechanical, or otherwise, without the written permission of DiSTI. Said
16 permission may be derived through the purchase of applicable DiSTI product
17 licenses which detail the distribution rights of this content and any
18 Derivative Works based on this or other copyrighted DiSTI Software.
19 
20  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26 
27  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34 EXCEED FIVE DOLLARS (US$5.00).
35 
36  The aforementioned terms and restrictions are governed by the laws of the
37 State of Florida and the United States of America.
38 
39 */
40 #ifndef INCLUDED_GLS_MAP_UTIL_H
41 #define INCLUDED_GLS_MAP_UTIL_H
42 
43 #include "vertex.h"
44 
45 #include <cfloat>
46 #include <iostream>
47 
48 //////////////////// Provides support for creating DLLs ////////////////////////
49 #if( defined( GLSGEN_EXPORT_GLSMAPUTIL ) || defined( GLSGEN_IMPORT_GLSMAPUTIL ) || defined( GLS_EXPORT_GENERATED ) || defined( GLS_IMPORT_GENERATED ) ) \
50  && defined( _MSC_VER )
51 # if defined( GLSGEN_EXPORT_GLSMAPUTIL ) || defined( GLS_EXPORT_GENERATED )
52 # define GLSGEN_GLSMAPUTIL_EXPORT __declspec( dllexport )
53 # else
54 # define GLSGEN_GLSMAPUTIL_EXPORT __declspec( dllimport )
55 # endif
56 #else
57 # define GLSGEN_GLSMAPUTIL_EXPORT
58 #endif
59 ///////////////////////////////////////////////////////////////////////////////
60 
61 namespace disti
62 {
63 /** The GeoCoord class encapsulates a location relative to the earth.
64  * It is possible to get and set the value in a number of different
65  * coordinate systems.
66  */
67 class GeoCoord
68 {
69 public:
70  /** The EllipsoidParams class is used to store data about
71  * the reference ellipsoid used for geodetic coordinate conversions.
72  * The GeoCoord methods use the WGS84 reference ellipsoid by default.
73  */
75  {
76  public:
77  EllipsoidParams( double radius, double flattening );
78  void SetEllipsoid( double radius, double flattening );
79 
80  double Radius() const { return _a; }
81  double Flattening() const { return _f; }
82 
83  // The derived parameters are calculated in advance
84  // to speedup conversions.
85  double a() const { return _a; }
86  double f() const { return _f; }
87  double a_sq() const { return _a_sq; }
88  double b() const { return _b; }
89  double b_sq() const { return _b_sq; }
90  double a_sq_over_b() const { return _a_sq_over_b; }
91  double e() const { return _e; }
92  double c1() const { return _c1; }
93  double a_b() const { return _a_b; }
94  double a_sq_sq() const { return _a_sq_sq; }
95  double b_sq_sq() const { return _b_sq_sq; }
96  double two_over_a() const { return _two_over_a; }
97  double two_over_b() const { return _two_over_b; }
98  double two_over_a_sq() const { return _two_over_a_sq; }
99  double two_over_b_sq() const { return _two_over_b_sq; }
100 
101  double e_sq() const { return _e_sq; }
102  double ep_sq() const { return _ep_sq; }
103  double ef() const { return _ef; }
104  double e_sq_to_3() const { return _e_sq_to_3; }
105  double ef_to_3() const { return _ef_to_3; }
106  double ef_to4() const { return _ef_to_4; }
107 
108  double poly1_a() const { return _poly1_a; }
109  double poly2_a() const { return _poly2_a; }
110  double poly3_a() const { return _poly3_a; }
111  double poly4_a() const { return _poly4_a; }
112  double poly5_a() const { return _poly5_a; }
113  double poly1_b() const { return _poly1_b; }
114  double poly2_b() const { return _poly2_b; }
115  double poly3_b() const { return _poly3_b; }
116  double poly4_b() const { return _poly4_b; }
117 
118  protected:
119  // Primary parameters
120  double _a; ///< equatorial radius
121  double _f; ///< flattening (a-b)/a
122 
123  // Derived parameters
124  double _a_sq; ///< radius squared
125  double _b; ///< polar semi-diameter
126  double _b_sq; ///< polar semi-diameter squared
127  double _a_sq_over_b; ///< a*a/b
128  double _e; ///< ellipticity 2f-f*f
129  double _c1; ///< (1-f)*(1-f)
130  double _a_b; ///< (a * b)
131  double _a_sq_sq; ///< (a * a * a * a)
132  double _b_sq_sq; ///< (b * b * b * b)
133  double _two_over_a; ///< (2/a)
134  double _two_over_b; ///< (2/b)
135  double _two_over_a_sq; ///< 2/(a * a)
136  double _two_over_b_sq; ///< 2/(b * b)
137 
138  double _e_sq; ///< eccentricity squared
139  double _ep_sq; ///< e-prime squared
140  double _ef; ///< e-factor
141  double _e_sq_to_3; ///< pow(e_sq,3.0)
142  double _ef_to_3; ///< pow(ef,3.0)
143  double _ef_to_4; ///< pow(ef,4.0)
144 
145  double _poly1_a; ///< 1.0 - _e_sq / 4.0 - 3.0 * _e_sq * _e_sq / 64.0 - 5.0 * _e_sq_to_3 / 256.0
146  double _poly2_a; ///< 3.0 * _ef / 2.0 - 27.0 * _ef_to_3 / 32.0
147  double _poly3_a; ///< 21.0 * _ef * _ef / 16.0 - 55.0 * _ef_to_4 / 32.0
148  double _poly4_a; ///< 151.0 * _ef_to_3 / 96.0
149  double _poly5_a; ///< 1097.0 * _ef_to_4 / 512.0
150  double _poly1_b; ///< 1.0 - (_e_sq / 4.0) - (3.0 * _e_sq * _e_sq) / 64.0 - 5.0 * _e_sq_to_3 / 256.0
151  double _poly2_b; ///< 3.0 * _e_sq / 8.0 + (3.0 * _e_sq * _e_sq) / 32.0 + 45.0 * _e_sq_to_3 / 1024.0
152  double _poly3_b; ///< 15.0 * _e_sq * _e_sq / 256.0 + 45.0 * _e_sq_to_3 / 1024.0
153  double _poly4_b; ///< 35.0 * _e_sq_to_3 / 3072.0
154  };
155 
156  /** Set GeoCoord value in geodetic coordinates
157  * \param lonLatAlt Vector where x = longitude, y = latitude, z = altitude
158  * \param ellipsoid Ellipsoid type
159  */
160  void SetGeodetic( const Vector& lonLatAlt, const EllipsoidParams& ellipsoid = GeoCoord::WGS84 )
161  {
162  SetGeodetic( lonLatAlt.x, lonLatAlt.y, lonLatAlt.z, ellipsoid );
163  }
164 
165  /** Set GeoCoord value in geodetic coordinates
166  * \param longitude Longitude in degrees
167  * \param latitude Latitude in degrees
168  * \param altitude Altitude in meters
169  * \param ellipsoid Ellipsoid type
170  */
171  void SetGeodetic( double longitude, double latitude, double altitude, const EllipsoidParams& ellipsoid = GeoCoord::WGS84 )
172  {
173  if( &ellipsoid == &WGS84 )
174  {
175  _lon = longitude;
176  _lat = latitude;
177  _alt = altitude;
178  _validValues = VAL_GEODETIC_WGS84;
179  }
180  else
181  {
182  SetGeodeticNonWGS84( longitude, latitude, altitude, ellipsoid );
183  }
184  }
185 
186  /** Get GeoCoord value in geodetic coordinates
187  * \param lonLatAlt pointer to a vector to receive the value ( x = longitude, y = latitude, z = altitude )
188  * \param ellipsoid Ellipsoid type
189  */
190  void GetGeodetic( Vector* lonLatAlt, const EllipsoidParams& ellipsoid = GeoCoord::WGS84 ) const
191  {
192  double lon, lat, alt;
193  GetGeodetic( &lon, &lat, &alt, ellipsoid );
194  lonLatAlt->x = float( lon );
195  lonLatAlt->y = float( lat );
196  lonLatAlt->z = float( alt );
197  }
198 
199  /** Get GeoCoord value in geodetic coordinates
200  * \param longitude pointer to a double to receive the longitude in degrees
201  * \param latitude pointer to a double to receive the latitude in degrees
202  * \param altitude pointer to a double to receive the altitude in meters
203  * \param ellipsoid Ellipsoid type
204  */
205  void GetGeodetic( double* longitude, double* latitude, double* altitude, const EllipsoidParams& ellipsoid = GeoCoord::WGS84 ) const
206  {
207  if( &ellipsoid == &WGS84 )
208  {
209  if( !( _validValues & VAL_GEODETIC_WGS84 ) )
210  {
211  UpdateGeodeticWGS84Value();
212  }
213 
214  *longitude = _lon;
215  *latitude = _lat;
216  *altitude = _alt;
217  }
218  else
219  {
220  GetGeodeticNonWGS84( longitude, latitude, altitude, ellipsoid );
221  }
222  }
223 
224  /** Set GeoCoord value in geocentric coordinates
225  * \param value Vector containing new geocentric coordinate in meters */
226  void SetGeocentric( const Vector& value )
227  {
228  SetGeocentric( value.x, value.y, value.z );
229  }
230 
231  /** Set GeoCoord value in geocentric coordinates
232  * \param x New x coordinate value in meters
233  * \param y New y coordinate value in meters
234  * \param z New z coordinate value in meters */
235  void SetGeocentric( double x, double y, double z )
236  {
237  _x = x;
238  _y = y;
239  _z = z;
240  _validValues = VAL_GEOCENTRIC;
241  }
242 
243  /** Get GeoCoord value in geocentric coordinates
244  * \param value pointer to a vector to receive the value */
245  void GetGeocentric( Vector* value ) const
246  {
247  double x, y, z;
248  GetGeocentric( &x, &y, &z );
249  value->x = float( x );
250  value->y = float( y );
251  value->z = float( z );
252  }
253 
254  /** Get GeoCoord value in geocentric coordinates
255  * \param x pointer to a double to receive the x coordinate value
256  * \param y pointer to a double to receive the y coordinate value
257  * \param z pointer to a double to receive the z coordinate value */
258  void GetGeocentric( double* x, double* y, double* z ) const
259  {
260  if( !( _validValues & VAL_GEOCENTRIC ) )
261  {
262  UpdateGeocentricValue();
263  }
264 
265  *x = _x;
266  *y = _y;
267  *z = _z;
268  }
269 
270  /** Determine if two GeoCoords have equivalent values
271  * \param other The GeoCoord to compare to */
272  bool operator==( const GeoCoord& other ) const
273  {
274  if( this->_validValues & VAL_GEODETIC_WGS84 && other._validValues & VAL_GEODETIC_WGS84 )
275  {
276  // Compare Geodetic coords
277  return closeValues( this->_lon, other._lon ) && closeValues( this->_lat, other._lat ) && closeValues( this->_alt, other._alt );
278  }
279  else
280  {
281  // Compare geocentric coords
282 
283  if( !( _validValues & VAL_GEOCENTRIC ) )
284  {
285  UpdateGeocentricValue();
286  }
287 
288  if( !( other._validValues & VAL_GEOCENTRIC ) )
289  {
290  other.UpdateGeocentricValue();
291  }
292 
293  return closeValues( this->_x, other._x ) && closeValues( this->_y, other._y ) && closeValues( this->_z, other._z );
294  }
295  }
296 
297  /** Determine if two GeoCoords do not have equivalent values
298  * \param other The GeoCoord to compare to */
299  bool operator!=( const GeoCoord& other ) const
300  {
301  return !( *this == other );
302  }
303 
304  /** Utility method to convert from geocentric to geodetic coordinates */
305  static void GeocentricToGeodetic( double xp, double yp, double zp,
306  double* lon, double* lat, double* alt,
307  const EllipsoidParams& ellipsoid = GeoCoord::WGS84 );
308 
309  /** Utility method to convert from geodetic to geocentric coordinates */
310  static void GeodeticToGeocentric( double lon, double lat, double alt,
311  double* xp, double* yp, double* zp,
312  const EllipsoidParams& ellipsoid = GeoCoord::WGS84 );
313 
314  static void UTMToGeodetic( const double northing, const double easting,
315  double& lat_degrees, double& lon_degrees );
316 
317  static void UTMToGeodetic( const double northing, const double easting, const int zone, const int latZoneIndex,
318  double& lat_degrees, double& lon_degrees );
319 
320  static void GeodeticToUTM( const double lat_degrees, const double lon_degrees,
321  double& northing, double& easting );
322 
323  static int CalcZone( double lon_radians );
324  static int CalcZoneDeg( double longitude_degrees );
325 
326  static char CalcLatZoneDeg( double lat_degrees );
327  static int CalcLatZoneDegIndex( double lat_degrees );
328 
329  /** Calculate the 'great circle' distance and initial bearing between two points
330  * along the surface of a sphere using the Haversine formula.
331  *
332  * \param coord1 First point
333  * \param coord2 Second point
334  * \param distance Pointer to a double to receive the distance in meters
335  * \param bearing Pointer to a double to receive the initial bearing from coord1 to coord2 in degrees from true north
336  * \param radius (optional) Radius of the sphere. Default value is the average radius of the earth (6372795.477598 meters)
337  */
338  static void GetSphericalDistanceAndBearing( const GeoCoord& coord1, const GeoCoord& coord2,
339  double* distance, double* bearing,
340  const double radius = 6372795.477598 );
341 
342  /** Calculate a new point given the distance and initial bearing from a known origin.
343  * The new point is located on the 'great circle' arc defined by the parameters.
344  *
345  * \param origin The starting point
346  * \param distance Distance to the destination in meters
347  * \param bearing Initial bearing from the origin in degrees from true north
348  * \param destination Pointer to a GeoCoord to receive the destination point
349  * \param radius (optional) Radius of the sphere. Default value is the average radius of the earth (6372795.477598 meters)
350  */
351  static void GetPointAtDistanceAndBearingSpherical( const GeoCoord& origin, double distance,
352  double bearing, GeoCoord* destination,
353  const double radius = 6372795.477598 );
354 
355 protected:
356  static bool closeValues( double lv, double rv )
357  {
358  const double PRECISION( 1e-7 );
359  return ( lv - PRECISION ) <= rv && rv <= ( lv + PRECISION );
360  }
361 
362  void GetGeodeticNonWGS84( double* longitude, double* latitude, double* altitude, const EllipsoidParams& ellipsoid = GeoCoord::WGS84 ) const;
363  void SetGeodeticNonWGS84( double longitude, double latitude, double altitude, const EllipsoidParams& ellipsoid = GeoCoord::WGS84 );
364  void UpdateGeodeticWGS84Value() const;
365  void UpdateGeocentricValue() const;
366 
367  static void CalcFalseNorthEast( double lat_radians );
368  static void CalcLambda0();
369 
370  enum ValueFlags
371  {
372  VAL_GEODETIC_WGS84 = 1,
373  VAL_GEOCENTRIC = 2
374  };
375 
376  mutable unsigned char _validValues;
377 
378  // Geodetic WGS84
379  mutable double _lon;
380  mutable double _lat;
381  mutable double _alt;
382 
383  // Geocentric
384  mutable double _x;
385  mutable double _y;
386  mutable double _z;
387 
388  static double _False_Northing;
389  static double _False_Easting;
390  static double _Zone;
391  static double _Lambda0;
392  static const char _LatZone[ 20 ];
393 
394 public:
395  // Standard ellipsoid parameters
396  static const EllipsoidParams WGS84;
397 };
398 
399 /** GeoCoord stream operator
400  * Accepts the following types of input:
401  * - `<longitude_degrees> <latitude_degrees> <altitude_meters>` (e.g. "-75.0 35.0 1000.0")
402  * - `WGS84 <longitude_degrees> <latitude_degrees> <altitude_meters>` (e.g. "WGS84 -75.0 35.0 1000.0")
403  * - `ECEF <x> <y> <z>` (e.g. "ECEF -5316120.34302 -2236496.88192 -2714391.58968")
404  */
405 GLSGEN_GLSMAPUTIL_EXPORT std::istream& operator>>( std::istream& instr, GeoCoord& coord );
406 
407 /** GeoCoord stream operator
408  * Outputs WGS84 geodetic coordinates:
409  * `<longitude_degrees> <latitude_degrees> <altitude_meters>` (e.g. -75 35 1000)
410  */
411 GLSGEN_GLSMAPUTIL_EXPORT std::ostream& operator<<( std::ostream& outstr, const GeoCoord& coord );
412 
413 /** The GeoRect class represents a lon/lat aligned region on the surface of the earth. */
414 class GeoRect
415 {
416 public:
417  /** ctor - sets the GeoRect to contain nothing */
419  {
420  SetToNull();
421  }
422 
423  GeoRect( double minLongitude, double minLatitude, double maxLongitude, double maxLatitude )
424  {
425  SetRect( minLongitude, minLatitude, maxLongitude, maxLatitude );
426  }
427 
428  /** Set the GeoRect value */
429  void SetRect( double minLongitude, double minLatitude, double maxLongitude, double maxLatitude )
430  {
431  _minLon = minLongitude;
432  _minLat = minLatitude;
433  _maxLon = maxLongitude;
434  _maxLat = maxLatitude;
435  }
436 
437  void MinLongitude( double value ) { _minLon = value; }
438  void MinLatitude( double value ) { _minLat = value; }
439  void MaxLongitude( double value ) { _maxLon = value; }
440  void MaxLatitude( double value ) { _maxLat = value; }
441 
442  double MinLongitude() const { return _minLon; }
443  double MinLatitude() const { return _minLat; }
444  double MaxLongitude() const { return _maxLon; }
445  double MaxLatitude() const { return _maxLat; }
446 
447  /** Determine if a point is in the GeoRect */
448  bool ContainsPoint( const GeoCoord& point ) const
449  {
450  double lon, lat, alt;
451  point.GetGeodetic( &lon, &lat, &alt );
452  return ContainsPoint( lon, lat );
453  }
454 
455  /** Determine if a point is in the GeoRect */
456  bool ContainsPoint( double lon, double lat ) const
457  {
458  return ( lon <= _maxLon && lon >= _minLon && lat <= _maxLat && lat >= _minLat );
459  }
460 
461  /** Set the GeoRect to contain nothing. */
462  void SetToNull()
463  {
464  _minLat = _minLon = DBL_MAX;
465  _maxLat = _maxLon = -DBL_MAX;
466  }
467 
468  /** determine if the GeoRect to contains nothing
469  * \return true if contains nothing else false
470  */
471  bool IsNull() const
472  {
473  return ( ( ( DBL_MAX == _minLat ) && ( DBL_MAX == _minLon ) && ( -DBL_MAX == _maxLat ) && ( -DBL_MAX == _maxLon ) ) || ( ( _minLat > _maxLat ) || ( _minLon > _maxLon ) ) );
474  }
475 
476  /** Set the GeoRect to contain a single point */
477  void SetToPoint( const GeoCoord& point )
478  {
479  double alt;
480  point.GetGeodetic( &_maxLon, &_maxLat, &alt );
481  _minLon = _maxLon;
482  _minLat = _maxLat;
483  }
484 
485  /** Set the GeoRect to contain a single point */
486  void SetToPoint( double lon, double lat )
487  {
488  _minLon = _maxLon = lon;
489  _minLat = _maxLat = lat;
490  }
491 
492  /** Increase the area of the GeoRect as needed to include the given point */
493  void GrowToContainPoint( const GeoCoord& point )
494  {
495  double lon, lat, alt;
496  point.GetGeodetic( &lon, &lat, &alt );
497  GrowToContainPoint( lon, lat );
498  }
499 
500  /** Increase the area of the GeoRect as needed to include the given point */
501  void GrowToContainPoint( double lon, double lat )
502  {
503  if( lon < _minLon )
504  {
505  _minLon = lon;
506  }
507  if( lon > _maxLon )
508  {
509  _maxLon = lon;
510  }
511  if( lat < _minLat )
512  {
513  _minLat = lat;
514  }
515  if( lat > _maxLat )
516  {
517  _maxLat = lat;
518  }
519  }
520 
521  /** Determine if this GeoRect intersects with another GeoRect */
522  bool Intersects( const GeoRect& other ) const
523  {
524  if( ( _minLat > other._maxLat ) || ( _maxLat < other._minLat ) || ( _minLon > other._maxLon ) || ( _maxLon < other._minLon ) )
525  {
526  return false;
527  }
528  else
529  {
530  // Make sure neither rect is null
531  if( _maxLat < _minLat || _maxLon < _minLon || other._maxLat < other._minLat || other._maxLon < other._minLon )
532  {
533  return false;
534  }
535  else
536  {
537  return true;
538  }
539  }
540  }
541 
542  /** Set this GeoRect to the intersection of the two given GeoRect */
543  void SetToIntersection( const GeoRect& rect1, const GeoRect& rect2 )
544  {
545  _minLon = ( rect1._minLon > rect2._minLon ) ? rect1._minLon : rect2._minLon;
546  _minLat = ( rect1._minLat > rect2._minLat ) ? rect1._minLat : rect2._minLat;
547  _maxLon = ( rect1._maxLon < rect2._maxLon ) ? rect1._maxLon : rect2._maxLon;
548  _maxLat = ( rect1._maxLat < rect2._maxLat ) ? rect1._maxLat : rect2._maxLat;
549  }
550 
551  /** Scale the region by moving the edges
552  * inward or outward from the center. */
553  void Scale( const double scaleFactor )
554  {
555  double centerLon = ( _minLon + _maxLon ) / 2.0;
556  double centerLat = ( _minLat + _maxLat ) / 2.0;
557 
558  _minLon = ( _minLon - centerLon ) * scaleFactor + centerLon;
559  _maxLon = ( _maxLon - centerLon ) * scaleFactor + centerLon;
560  _minLat = ( _minLat - centerLat ) * scaleFactor + centerLat;
561  _maxLat = ( _maxLat - centerLat ) * scaleFactor + centerLat;
562  }
563 
564  /** Printer */
565  friend std::ostream& operator<<( std::ostream& os, const GeoRect& r )
566  {
567  return os << "{ { " << r._minLat << ", " << r._minLon << " }, { " << r._maxLat << ", " << r._maxLon << "} }";
568  }
569 
570 protected:
571  double _minLon;
572  double _minLat;
573  double _maxLon;
574  double _maxLat;
575 };
576 
577 /** Fuzzy float equality.
578  * \tparam X A floating-point type
579  * \tparam Y A floating-point type
580  * \tparam Z A floating-point type
581  * \param x A floating-point value
582  * \param y A floating-point value
583  * \param tolerance A floating-point value used to determine how fuzzy equality is.
584  * \note Overloads disti::Equal() from the GLS runtime.
585  */
586 template<class X, class Y, class Z>
587 bool Equal( const X x, const Y y, Z tolerance = Z( 0.001 ) )
588 {
589  return ( ( x - tolerance ) <= y )
590  && ( ( x + tolerance ) >= y );
591 }
592 
593 /** A fuzzy floating-point comparison for GeoRects
594  * \param lhs The left-hand side of the equality comparison
595  * \param rhs The right-hand side of the equality comparison
596  * \param tolerance The tolerance to use for fuzzy equality. Defaults to 1e-8.
597  * \note Overloads disti::Equal() from the GLS runtime.
598  */
599 inline bool Equal( const GeoRect& lhs, const GeoRect& rhs, const double tolerance = 1e-8 )
600 {
601  return Equal( lhs.MinLatitude(), rhs.MinLatitude(), tolerance )
602  && Equal( lhs.MaxLatitude(), rhs.MaxLatitude(), tolerance )
603  && Equal( lhs.MinLongitude(), rhs.MinLongitude(), tolerance )
604  && Equal( lhs.MaxLongitude(), rhs.MaxLongitude(), tolerance );
605 }
606 
607 /** Wrap a lon, lat coordinate to be valid.
608  * \param lon The longitude value to be wrapped
609  * \param lat The latitiude value to be wrapped */
610 inline void WrapCoords( double& lon, double& lat )
611 {
612  if( lat > 90 )
613  {
614  lat = -90 + fmod( lat - 90, 180 );
615  }
616  else if( lat < -90 )
617  {
618  lat = 90 + fmod( lat + 90, 180 );
619  }
620 
621  if( lon > 180.0 )
622  {
623  lon = -180.0 + fmod( lon - 180.0, 360.0 );
624  }
625  else if( lon < -180.0 )
626  {
627  lon = 180.0 + fmod( lon + 180.0, 360.0 );
628  }
629 }
630 
631 /** Wrap for lon, lat coordinates of a GeoRect
632  * \param rect The GeoRect to be wrapped */
633 inline void WrapCoords( GeoRect& rect )
634 {
635  double minLongitude = rect.MinLongitude();
636  double minLatitude = rect.MinLatitude();
637  double maxLongitude = rect.MaxLongitude();
638  double maxLatitude = rect.MaxLatitude();
639 
640  WrapCoords( minLongitude, minLatitude );
641  WrapCoords( maxLongitude, maxLatitude );
642 
643  rect.SetRect( minLongitude, minLatitude, maxLongitude, maxLatitude );
644 }
645 
646 /** Clamp a lon, lat coordinate to be valid.
647  * \param lon The longitude value to be clamped
648  * \param lat The latitiude value to be clamped */
649 inline void ClampCoords( double& lon, double& lat )
650 {
651  if( lat > 90.0 )
652  {
653  lat = 90.0;
654  }
655  else if( lat < -90.0 )
656  {
657  lat = -90.0;
658  }
659 
660  if( lon > 180.0 )
661  {
662  lon = 180.0;
663  }
664  else if( lon < -180.0 )
665  {
666  lon = -180.0;
667  }
668 }
669 
670 /** Clamp for lon, lat coordinates of a GeoRect
671  * \param rect The GeoRect to be clamped */
672 inline void ClampCoords( GeoRect& rect )
673 {
674  double minLongitude = rect.MinLongitude();
675  double minLatitude = rect.MinLatitude();
676  double maxLongitude = rect.MaxLongitude();
677  double maxLatitude = rect.MaxLatitude();
678 
679  ClampCoords( minLongitude, minLatitude );
680  ClampCoords( maxLongitude, maxLatitude );
681 
682  rect.SetRect( minLongitude, minLatitude, maxLongitude, maxLatitude );
683 }
684 
685 /** Initialize the GlsMapToolkit library.
686  * Called by generated code.
687  */
688 void GlsMapToolkitInit( const char* );
689 
690 } // namespace disti
691 
692 #endif
void SetToPoint(const GeoCoord &point)
Definition: gls_map_util.h:477
bool Intersects(const GeoRect &other) const
Definition: gls_map_util.h:522
void SetToPoint(double lon, double lat)
Definition: gls_map_util.h:486
void GrowToContainPoint(double lon, double lat)
Definition: gls_map_util.h:501
double _poly2_a
3.0 * _ef / 2.0 - 27.0 * _ef_to_3 / 32.0
Definition: gls_map_util.h:146
double _a_sq
radius squared
Definition: gls_map_util.h:124
double _poly3_b
15.0 * _e_sq * _e_sq / 256.0 + 45.0 * _e_sq_to_3 / 1024.0
Definition: gls_map_util.h:152
void SetGeocentric(const Vector &value)
Definition: gls_map_util.h:226
double _a_b
(a * b)
Definition: gls_map_util.h:130
double _e_sq
eccentricity squared
Definition: gls_map_util.h:138
void GetGeodetic(Vector *lonLatAlt, const EllipsoidParams &ellipsoid=GeoCoord::WGS84) const
Definition: gls_map_util.h:190
double _b_sq
polar semi-diameter squared
Definition: gls_map_util.h:126
double _poly3_a
21.0 * _ef * _ef / 16.0 - 55.0 * _ef_to_4 / 32.0
Definition: gls_map_util.h:147
double _two_over_a_sq
2/(a * a)
Definition: gls_map_util.h:135
void Scale(const double scaleFactor)
Definition: gls_map_util.h:553
void ClampCoords(double &lon, double &lat)
Definition: gls_map_util.h:649
Definition: gls_map_util.h:414
void GlsMapToolkitInit(const char *)
double _poly5_a
1097.0 * _ef_to_4 / 512.0
Definition: gls_map_util.h:149
bool IsNull() const
Definition: gls_map_util.h:471
static void GetPointAtDistanceAndBearingSpherical(const GeoCoord &origin, double distance, double bearing, GeoCoord *destination, const double radius=6372795.477598)
double _f
flattening (a-b)/a
Definition: gls_map_util.h:121
Definition: gls_map_util.h:67
double _poly1_a
1.0 - _e_sq / 4.0 - 3.0 * _e_sq * _e_sq / 64.0 - 5.0 * _e_sq_to_3 / 256.0
Definition: gls_map_util.h:145
bool ContainsPoint(const GeoCoord &point) const
Definition: gls_map_util.h:448
bool operator!=(const GeoCoord &other) const
Definition: gls_map_util.h:299
void WrapCoords(double &lon, double &lat)
Definition: gls_map_util.h:610
void SetToNull()
Definition: gls_map_util.h:462
std::ostream & operator<<(std::ostream &outstr, const AttributeName &name)
Defines the stream out operator.
void SetToIntersection(const GeoRect &rect1, const GeoRect &rect2)
Definition: gls_map_util.h:543
double _poly1_b
1.0 - (_e_sq / 4.0) - (3.0 * _e_sq * _e_sq) / 64.0 - 5.0 * _e_sq_to_3 / 256.0
Definition: gls_map_util.h:150
double _two_over_b_sq
2/(b * b)
Definition: gls_map_util.h:136
void GetGeocentric(double *x, double *y, double *z) const
Definition: gls_map_util.h:258
void GetGeodetic(double *longitude, double *latitude, double *altitude, const EllipsoidParams &ellipsoid=GeoCoord::WGS84) const
Definition: gls_map_util.h:205
double _e_sq_to_3
pow(e_sq,3.0)
Definition: gls_map_util.h:141
double _ef_to_3
pow(ef,3.0)
Definition: gls_map_util.h:142
Definition: gls_map_util.h:74
double _ep_sq
e-prime squared
Definition: gls_map_util.h:139
bool operator==(const GeoCoord &other) const
Definition: gls_map_util.h:272
double _a_sq_over_b
a*a/b
Definition: gls_map_util.h:127
double _two_over_a
(2/a)
Definition: gls_map_util.h:133
double _ef_to_4
pow(ef,4.0)
Definition: gls_map_util.h:143
The disti::Vertex class. A class for manipulating 3D vertices.
static void GeodeticToGeocentric(double lon, double lat, double alt, double *xp, double *yp, double *zp, const EllipsoidParams &ellipsoid=GeoCoord::WGS84)
double _two_over_b
(2/b)
Definition: gls_map_util.h:134
void SetGeodetic(double longitude, double latitude, double altitude, const EllipsoidParams &ellipsoid=GeoCoord::WGS84)
Definition: gls_map_util.h:171
double _b
polar semi-diameter
Definition: gls_map_util.h:125
void SetGeocentric(double x, double y, double z)
Definition: gls_map_util.h:235
double _b_sq_sq
(b * b * b * b)
Definition: gls_map_util.h:132
static void GetSphericalDistanceAndBearing(const GeoCoord &coord1, const GeoCoord &coord2, double *distance, double *bearing, const double radius=6372795.477598)
bool Equal(T1 x, T2 y, float precision=0.001f)
Definition: util.h:421
friend std::ostream & operator<<(std::ostream &os, const GeoRect &r)
Definition: gls_map_util.h:565
double _a_sq_sq
(a * a * a * a)
Definition: gls_map_util.h:131
void SetRect(double minLongitude, double minLatitude, double maxLongitude, double maxLatitude)
Definition: gls_map_util.h:429
double _c1
(1-f)*(1-f)
Definition: gls_map_util.h:129
GeoRect()
Definition: gls_map_util.h:418
void SetGeodetic(const Vector &lonLatAlt, const EllipsoidParams &ellipsoid=GeoCoord::WGS84)
Definition: gls_map_util.h:160
Definition: vertex.h:84
double _poly4_a
151.0 * _ef_to_3 / 96.0
Definition: gls_map_util.h:148
double _poly2_b
3.0 * _e_sq / 8.0 + (3.0 * _e_sq * _e_sq) / 32.0 + 45.0 * _e_sq_to_3 / 1024.0
Definition: gls_map_util.h:151
bool ContainsPoint(double lon, double lat) const
Definition: gls_map_util.h:456
double _poly4_b
35.0 * _e_sq_to_3 / 3072.0
Definition: gls_map_util.h:153
void GrowToContainPoint(const GeoCoord &point)
Definition: gls_map_util.h:493
double _ef
e-factor
Definition: gls_map_util.h:140
static void GeocentricToGeodetic(double xp, double yp, double zp, double *lon, double *lat, double *alt, const EllipsoidParams &ellipsoid=GeoCoord::WGS84)
Definition: bmpimage.h:46
void GetGeocentric(Vector *value) const
Definition: gls_map_util.h:245
double _a
equatorial radius
Definition: gls_map_util.h:120
double _e
ellipticity 2f-f*f
Definition: gls_map_util.h:128