Constants.hpp 16.1 KB
Newer Older
1 2 3 4 5 6 7 8 9
/**
 * \file Constants.hpp
 * \brief Header for GeographicLib::Constants class
 *
 * Copyright (c) Charles Karney (2008-2019) <charles@karney.com> and licensed
 * under the MIT/X11 License.  For more information, see
 * https://geographiclib.sourceforge.io/
 **********************************************************************/

dogmaphobic's avatar
dogmaphobic committed
10
#pragma once
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148

// This will be overwritten by ./configure

#define GEOGRAPHICLIB_VERSION_STRING "1.50"
#define GEOGRAPHICLIB_VERSION_MAJOR 1
#define GEOGRAPHICLIB_VERSION_MINOR 50
#define GEOGRAPHICLIB_VERSION_PATCH 0

// Undefine HAVE_LONG_DOUBLE if this type is unknown to the compiler
#define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 1

// Define WORDS_BIGENDIAN to be 1 if your machine is big endian
/* #undef WORDS_BIGENDIAN */

#include "Math.hpp"

/**
 * @relates GeographicLib::Constants
 * Pack the version components into a single integer.  Users should not rely on
 * this particular packing of the components of the version number; see the
 * documentation for GEOGRAPHICLIB_VERSION, below.
 **********************************************************************/
#define GEOGRAPHICLIB_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c))

/**
 * @relates GeographicLib::Constants
 * The version of GeographicLib as a single integer, packed as MMmmmmpp where
 * MM is the major version, mmmm is the minor version, and pp is the patch
 * level.  Users should not rely on this particular packing of the components
 * of the version number.  Instead they should use a test such as \code
   #if GEOGRAPHICLIB_VERSION >= GEOGRAPHICLIB_VERSION_NUM(1,37,0)
   ...
   #endif
 * \endcode
 **********************************************************************/
#define GEOGRAPHICLIB_VERSION \
 GEOGRAPHICLIB_VERSION_NUM(GEOGRAPHICLIB_VERSION_MAJOR, \
                           GEOGRAPHICLIB_VERSION_MINOR, \
                           GEOGRAPHICLIB_VERSION_PATCH)

/**
 * @relates GeographicLib::Constants
 * Is the C++11 static_assert available?
 **********************************************************************/
#if !defined(GEOGRAPHICLIB_HAS_STATIC_ASSERT)
#  if __cplusplus >= 201103 || defined(__GXX_EXPERIMENTAL_CXX0X__)
#    define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
#  elif defined(_MSC_VER) && _MSC_VER >= 1600
// For reference, here is a table of Visual Studio and _MSC_VER
// correspondences:
//
// _MSC_VER  Visual Studio
//   1100     vc5
//   1200     vc6
//   1300     vc7
//   1310     vc7.1 (2003)
//   1400     vc8   (2005)
//   1500     vc9   (2008)
//   1600     vc10  (2010)
//   1700     vc11  (2012)
//   1800     vc12  (2013) First version of VS to include enough C++11 support
//   1900     vc14  (2015)
//   191[0-9] vc15  (2017)
//   192[0-9] vc16  (2019)
#    define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
#  else
#    define GEOGRAPHICLIB_HAS_STATIC_ASSERT 0
#  endif
#endif

/**
 * @relates GeographicLib::Constants
 * A compile-time assert.  Use C++11 static_assert, if available.
 **********************************************************************/
#if !defined(GEOGRAPHICLIB_STATIC_ASSERT)
#  if GEOGRAPHICLIB_HAS_STATIC_ASSERT
#    define GEOGRAPHICLIB_STATIC_ASSERT static_assert
#  else
#    define GEOGRAPHICLIB_STATIC_ASSERT(cond,reason) \
            { enum{ GEOGRAPHICLIB_STATIC_ASSERT_ENUM = 1/int(cond) }; }
#  endif
#endif

#if defined(_MSC_VER) && defined(GEOGRAPHICLIB_SHARED_LIB) && \
  GEOGRAPHICLIB_SHARED_LIB
#  if GEOGRAPHICLIB_SHARED_LIB > 1
#    error GEOGRAPHICLIB_SHARED_LIB must be 0 or 1
#  elif defined(GeographicLib_SHARED_EXPORTS)
#    define GEOGRAPHICLIB_EXPORT __declspec(dllexport)
#  else
#    define GEOGRAPHICLIB_EXPORT __declspec(dllimport)
#  endif
#else
#  define GEOGRAPHICLIB_EXPORT
#endif

// Use GEOGRAPHICLIB_DEPRECATED to mark functions, types or variables as
// deprecated.  Code inspired by Apache Subversion's svn_types.h file (via
// MPFR).
#if defined(__GNUC__)
#  if __GNUC__ > 4
#    define GEOGRAPHICLIB_DEPRECATED(msg) __attribute__((deprecated(msg)))
#  else
#    define GEOGRAPHICLIB_DEPRECATED(msg) __attribute__((deprecated))
#  endif
#elif defined(_MSC_VER) && _MSC_VER >= 1300
#  define GEOGRAPHICLIB_DEPRECATED(msg) __declspec(deprecated(msg))
#else
#  define GEOGRAPHICLIB_DEPRECATED(msg)
#endif

#include <stdexcept>
#include <string>

/**
 * \brief Namespace for %GeographicLib
 *
 * All of %GeographicLib is defined within the GeographicLib namespace.  In
 * addition all the header files are included via %GeographicLib/Class.hpp.
 * This minimizes the likelihood of conflicts with other packages.
 **********************************************************************/
namespace GeographicLib {

  /**
   * \brief %Constants needed by %GeographicLib
   *
   * Define constants specifying the WGS84 ellipsoid, the UTM and UPS
   * projections, and various unit conversions.
   *
   * Example of use:
   * \include example-Constants.cpp
   **********************************************************************/
  class GEOGRAPHICLIB_EXPORT Constants {
  private:
    Constants();                // Disable constructor

  public:
    /**
dogmaphobic's avatar
dogmaphobic committed
149
     * A synonym for Math::degree<double>().
150
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
151
    static double degree() { return Math::degree(); }
152 153 154
    /**
     * @return the number of radians in an arcminute.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
155
    static double arcminute()
156 157 158 159
    { return Math::degree() / 60; }
    /**
     * @return the number of radians in an arcsecond.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
160
    static double arcsecond()
161 162 163 164 165 166 167 168 169 170 171 172
    { return Math::degree() / 3600; }

    /** \name Ellipsoid parameters
     **********************************************************************/
    ///@{
    /**
     * @tparam T the type of the returned value.
     * @return the equatorial radius of WGS84 ellipsoid (6378137 m).
     **********************************************************************/
    template<typename T> static T WGS84_a()
    { return 6378137 * meter<T>(); }
    /**
dogmaphobic's avatar
dogmaphobic committed
173
     * A synonym for WGS84_a<double>().
174
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
175
    static double WGS84_a() { return WGS84_a<double>(); }
176 177 178 179 180 181 182 183 184 185 186
    /**
     * @tparam T the type of the returned value.
     * @return the flattening of WGS84 ellipsoid (1/298.257223563).
     **********************************************************************/
    template<typename T> static T WGS84_f() {
      // Evaluating this as 1000000000 / T(298257223563LL) reduces the
      // round-off error by about 10%.  However, expressing the flattening as
      // 1/298.257223563 is well ingrained.
      return 1 / ( T(298257223563LL) / 1000000000 );
    }
    /**
dogmaphobic's avatar
dogmaphobic committed
187
     * A synonym for WGS84_f<double>().
188
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
189
    static double WGS84_f() { return WGS84_f<double>(); }
190 191 192 193 194 195 196 197
    /**
     * @tparam T the type of the returned value.
     * @return the gravitational constant of the WGS84 ellipsoid, \e GM, in
     *   m<sup>3</sup> s<sup>&minus;2</sup>.
     **********************************************************************/
    template<typename T> static T WGS84_GM()
    { return T(3986004) * 100000000 + 41800000; }
    /**
dogmaphobic's avatar
dogmaphobic committed
198
     * A synonym for WGS84_GM<double>().
199
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
200
    static double WGS84_GM() { return WGS84_GM<double>(); }
201 202 203 204 205 206 207 208
    /**
     * @tparam T the type of the returned value.
     * @return the angular velocity of the WGS84 ellipsoid, &omega;, in rad
     *   s<sup>&minus;1</sup>.
     **********************************************************************/
    template<typename T> static T WGS84_omega()
    { return 7292115 / (T(1000000) * 100000); }
    /**
dogmaphobic's avatar
dogmaphobic committed
209
     * A synonym for WGS84_omega<double>().
210
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
211
    static double WGS84_omega() { return WGS84_omega<double>(); }
212 213 214 215 216 217 218
    /**
     * @tparam T the type of the returned value.
     * @return the equatorial radius of GRS80 ellipsoid, \e a, in m.
     **********************************************************************/
    template<typename T> static T GRS80_a()
    { return 6378137 * meter<T>(); }
    /**
dogmaphobic's avatar
dogmaphobic committed
219
     * A synonym for GRS80_a<double>().
220
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
221
    static double GRS80_a() { return GRS80_a<double>(); }
222 223 224 225 226 227 228 229
    /**
     * @tparam T the type of the returned value.
     * @return the gravitational constant of the GRS80 ellipsoid, \e GM, in
     *   m<sup>3</sup> s<sup>&minus;2</sup>.
     **********************************************************************/
    template<typename T> static T GRS80_GM()
    { return T(3986005) * 100000000; }
    /**
dogmaphobic's avatar
dogmaphobic committed
230
     * A synonym for GRS80_GM<double>().
231
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
232
    static double GRS80_GM() { return GRS80_GM<double>(); }
233 234 235 236 237 238 239
    /**
     * @tparam T the type of the returned value.
     * @return the angular velocity of the GRS80 ellipsoid, &omega;, in rad
     *   s<sup>&minus;1</sup>.
     *
     * This is about 2 &pi; 366.25 / (365.25 &times; 24 &times; 3600) rad
     * s<sup>&minus;1</sup>.  365.25 is the number of days in a Julian year and
dogmaphobic's avatar
dogmaphobic committed
240
     * 365.35/366.25 converts from solar days to sidedouble days.  Using the
241 242 243 244 245 246 247
     * number of days in a Gregorian year (365.2425) results in a worse
     * approximation (because the Gregorian year includes the precession of the
     * earth's axis).
     **********************************************************************/
    template<typename T> static T GRS80_omega()
    { return 7292115 / (T(1000000) * 100000); }
    /**
dogmaphobic's avatar
dogmaphobic committed
248
     * A synonym for GRS80_omega<double>().
249
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
250
    static double GRS80_omega() { return GRS80_omega<double>(); }
251 252 253 254 255 256 257 258
    /**
     * @tparam T the type of the returned value.
     * @return the dynamical form factor of the GRS80 ellipsoid,
     *   <i>J</i><sub>2</sub>.
     **********************************************************************/
    template<typename T> static T GRS80_J2()
    { return T(108263) / 100000000; }
    /**
dogmaphobic's avatar
dogmaphobic committed
259
     * A synonym for GRS80_J2<double>().
260
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
261
    static double GRS80_J2() { return GRS80_J2<double>(); }
262 263 264 265 266 267 268
    /**
     * @tparam T the type of the returned value.
     * @return the central scale factor for UTM (0.9996).
     **********************************************************************/
    template<typename T> static T UTM_k0()
    {return T(9996) / 10000; }
    /**
dogmaphobic's avatar
dogmaphobic committed
269
     * A synonym for UTM_k0<double>().
270
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
271
    static double UTM_k0() { return UTM_k0<double>(); }
272 273 274 275 276 277 278
    /**
     * @tparam T the type of the returned value.
     * @return the central scale factor for UPS (0.994).
     **********************************************************************/
    template<typename T> static T UPS_k0()
    { return T(994) / 1000; }
    /**
dogmaphobic's avatar
dogmaphobic committed
279
     * A synonym for UPS_k0<double>().
280
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
281
    static double UPS_k0() { return UPS_k0<double>(); }
282 283 284 285 286 287 288 289 290 291 292 293 294 295
    ///@}

    /** \name SI units
     **********************************************************************/
    ///@{
    /**
     * @tparam T the type of the returned value.
     * @return the number of meters in a meter.
     *
     * This is unity, but this lets the internal system of units be changed if
     * necessary.
     **********************************************************************/
    template<typename T> static T meter() { return T(1); }
    /**
dogmaphobic's avatar
dogmaphobic committed
296
     * A synonym for meter<double>().
297
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
298
    static double meter() { return meter<double>(); }
299 300 301
    /**
     * @return the number of meters in a kilometer.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
302 303
    static double kilometer()
    { return 1000 * meter<double>(); }
304 305 306 307
    /**
     * @return the number of meters in a nautical mile (approximately 1 arc
     *   minute)
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
308 309
    static double nauticalmile()
    { return 1852 * meter<double>(); }
310 311 312 313 314 315 316 317 318

    /**
     * @tparam T the type of the returned value.
     * @return the number of square meters in a square meter.
     *
     * This is unity, but this lets the internal system of units be changed if
     * necessary.
     **********************************************************************/
    template<typename T> static T square_meter()
dogmaphobic's avatar
dogmaphobic committed
319
    { return meter<double>() * meter<double>(); }
320
    /**
dogmaphobic's avatar
dogmaphobic committed
321
     * A synonym for square_meter<double>().
322
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
323 324
    static double square_meter()
    { return square_meter<double>(); }
325 326 327
    /**
     * @return the number of square meters in a hectare.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
328 329
    static double hectare()
    { return 10000 * square_meter<double>(); }
330 331 332
    /**
     * @return the number of square meters in a square kilometer.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
333
    static double square_kilometer()
334 335 336 337
    { return kilometer() * kilometer(); }
    /**
     * @return the number of square meters in a square nautical mile.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
338
    static double square_nauticalmile()
339 340 341 342 343 344 345 346 347
    { return nauticalmile() * nauticalmile(); }
    ///@}

    /** \name Anachronistic British units
     **********************************************************************/
    ///@{
    /**
     * @return the number of meters in an international foot.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
348 349
    static double foot()
    { return double(254 * 12) / 10000 * meter<double>(); }
350 351 352
    /**
     * @return the number of meters in a yard.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
353
    static double yard() { return 3 * foot(); }
354 355 356
    /**
     * @return the number of meters in a fathom.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
357
    static double fathom() { return 2 * yard(); }
358 359 360
    /**
     * @return the number of meters in a chain.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
361
    static double chain() { return 22 * yard(); }
362 363 364
    /**
     * @return the number of meters in a furlong.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
365
    static double furlong() { return 10 * chain(); }
366 367 368
    /**
     * @return the number of meters in a statute mile.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
369
    static double mile() { return 8 * furlong(); }
370 371 372
    /**
     * @return the number of square meters in an acre.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
373
    static double acre() { return chain() * furlong(); }
374 375 376
    /**
     * @return the number of square meters in a square statute mile.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
377
    static double square_mile() { return mile() * mile(); }
378 379 380 381 382 383 384 385
    ///@}

    /** \name Anachronistic US units
     **********************************************************************/
    ///@{
    /**
     * @return the number of meters in a US survey foot.
     **********************************************************************/
dogmaphobic's avatar
dogmaphobic committed
386 387
    static double surveyfoot()
    { return double(1200) / 3937 * meter<double>(); }
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
    ///@}
  };

  /**
   * \brief Exception handling for %GeographicLib
   *
   * A class to handle exceptions.  It's derived from std::runtime_error so it
   * can be caught by the usual catch clauses.
   *
   * Example of use:
   * \include example-GeographicErr.cpp
   **********************************************************************/
  class GeographicErr : public std::runtime_error {
  public:

    /**
     * Constructor
     *
     * @param[in] msg a string message, which is accessible in the catch
     *   clause via what().
     **********************************************************************/
    GeographicErr(const std::string& msg) : std::runtime_error(msg) {}
  };

} // namespace GeographicLib