| Constants.hpp | | Constants.hpp | |
| /** | | /** | |
| * \file Constants.hpp | | * \file Constants.hpp | |
| * \brief Header for GeographicLib::Constants class | | * \brief Header for GeographicLib::Constants class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2008, 2009, 2010, 2011) <charles@karney.co
m> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP) | | #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP) | |
|
| #define GEOGRAPHICLIB_CONSTANTS_HPP "$Id: Constants.hpp 6918 2010-12-21 12:
56:07Z karney $" | | #define GEOGRAPHICLIB_CONSTANTS_HPP "$Id: Constants.hpp 6967 2011-02-19 15:
53:41Z karney $" | |
| | | | |
| /** | | /** | |
| * Are C++0X math functions available? | | * Are C++0X math functions available? | |
| **********************************************************************/ | | **********************************************************************/ | |
| #if !defined(GEOGRAPHICLIB_CPLUSPLUS0X_MATH) | | #if !defined(GEOGRAPHICLIB_CPLUSPLUS0X_MATH) | |
| #if defined(__GXX_EXPERIMENTAL_CXX0X__) | | #if defined(__GXX_EXPERIMENTAL_CXX0X__) | |
| #define GEOGRAPHICLIB_CPLUSPLUS0X_MATH 1 | | #define GEOGRAPHICLIB_CPLUSPLUS0X_MATH 1 | |
| #else | | #else | |
| #define GEOGRAPHICLIB_CPLUSPLUS0X_MATH 0 | | #define GEOGRAPHICLIB_CPLUSPLUS0X_MATH 0 | |
| #endif | | #endif | |
| | | | |
| skipping to change at line 124 | | skipping to change at line 124 | |
| typedef float real; | | typedef float real; | |
| #elif GEOGRAPHICLIB_PREC == 2 | | #elif GEOGRAPHICLIB_PREC == 2 | |
| typedef extended real; | | typedef extended real; | |
| #else | | #else | |
| typedef double real; | | typedef double real; | |
| #endif | | #endif | |
| | | | |
| /** | | /** | |
| * @return \e pi | | * @return \e pi | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real pi() throw() | | template<typename T> | |
| | | static inline T pi() throw() | |
| // good for about 168-bit accuracy | | // good for about 168-bit accuracy | |
|
| { return real(3.1415926535897932384626433832795028841971693993751L); } | | { return T(3.1415926535897932384626433832795028841971693993751L); } | |
| | | /** | |
| | | * A synonym for pi<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline real pi() throw() { return pi<real>(); } | |
| | | /** | |
| | | * <b>DEPRECATED</b> A synonym for pi<extened>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline extended epi() throw() { return pi<extended>(); } | |
| | | | |
| /** | | /** | |
| * @return the number of radians in a degree. | | * @return the number of radians in a degree. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real degree() throw() { return pi() / 180; } | | template<typename T> | |
| | | static inline T degree() throw() { return pi<T>() / T(180); } | |
| | | /** | |
| | | * A synonym for degree<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline real degree() throw() { return degree<real>(); } | |
| | | /** | |
| | | * <b>DEPRECATED</b> A synonym for degree<extened>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline extended edegree() throw() { return degree<extended>(); } | |
| | | | |
| #if defined(DOXYGEN) | | #if defined(DOXYGEN) | |
| /** | | /** | |
| * The hypotenuse function avoiding underflow and overflow. | | * The hypotenuse function avoiding underflow and overflow. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @param[in] y | | * @param[in] y | |
| * @return sqrt(\e x<sup>2</sup> + \e y<sup>2</sup>). | | * @return sqrt(\e x<sup>2</sup> + \e y<sup>2</sup>). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real hypot(real x, real y) throw() { | | template<typename T> | |
| | | static inline T hypot(T x, T y) throw() { | |
| x = std::abs(x); | | x = std::abs(x); | |
| y = std::abs(y); | | y = std::abs(y); | |
|
| real | | T a = std::max(x, y), | |
| a = std::max(x, y), | | | |
| b = std::min(x, y) / a; | | b = std::min(x, y) / a; | |
| return a * std::sqrt(1 + b * b); | | return a * std::sqrt(1 + b * b); | |
| } | | } | |
| #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | | #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | |
|
| static inline real hypot(real x, real y) throw() {return std::hypot(x, | | template<typename T> | |
| y);} | | static inline T hypot(T x, T y) throw() { return std::hypot(x, y); } | |
| #elif defined(_MSC_VER) | | #elif defined(_MSC_VER) | |
| static inline double hypot(double x, double y) throw() | | static inline double hypot(double x, double y) throw() | |
| { return _hypot(x, y); } | | { return _hypot(x, y); } | |
| static inline float hypot(float x, float y) throw() | | static inline float hypot(float x, float y) throw() | |
| { return _hypotf(x, y); } | | { return _hypotf(x, y); } | |
| #if !defined(__NO_LONG_DOUBLE_MATH) | | #if !defined(__NO_LONG_DOUBLE_MATH) | |
| static inline long double hypot(long double x, long double y) throw() | | static inline long double hypot(long double x, long double y) throw() | |
| { return _hypot(x, y); } | | { return _hypot(x, y); } | |
| #endif | | #endif | |
| #else | | #else | |
| | | | |
| skipping to change at line 181 | | skipping to change at line 200 | |
| | | | |
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | | #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | |
| /** | | /** | |
| * exp(\e x) - 1 accurate near \e x = 0. This is taken from | | * exp(\e x) - 1 accurate near \e x = 0. This is taken from | |
| * N. J. Higham, Accuracy and Stability of Numerical Algorithms, 2nd | | * N. J. Higham, Accuracy and Stability of Numerical Algorithms, 2nd | |
| * Edition (SIAM, 2002), Sec 1.14.1, p 19. | | * Edition (SIAM, 2002), Sec 1.14.1, p 19. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return exp(\e x) - 1. | | * @return exp(\e x) - 1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real expm1(real x) throw() { | | template<typename T> | |
| volatile real | | static inline T expm1(T x) throw() { | |
| | | volatile T | |
| y = std::exp(x), | | y = std::exp(x), | |
| z = y - 1; | | z = y - 1; | |
| // The reasoning here is similar to that for log1p. The expression | | // The reasoning here is similar to that for log1p. The expression | |
| // mathematically reduces to exp(x) - 1, and the factor z/log(y) = (y
- | | // mathematically reduces to exp(x) - 1, and the factor z/log(y) = (y
- | |
| // 1)/log(y) is a slowly varying quantity near y = 1 and is accuratel
y | | // 1)/log(y) is a slowly varying quantity near y = 1 and is accuratel
y | |
| // computed. | | // computed. | |
| return std::abs(x) > 1 ? z : z == 0 ? x : x * z / std::log(y); | | return std::abs(x) > 1 ? z : z == 0 ? x : x * z / std::log(y); | |
| } | | } | |
| #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | | #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | |
|
| static inline real expm1(real x) throw() { return std::expm1(x); } | | template<typename T> | |
| | | static inline T expm1(T x) throw() { return std::expm1(x); } | |
| #else | | #else | |
| static inline double expm1(double x) throw() { return ::expm1(x); } | | static inline double expm1(double x) throw() { return ::expm1(x); } | |
| static inline float expm1(float x) throw() { return ::expm1f(x); } | | static inline float expm1(float x) throw() { return ::expm1f(x); } | |
| #if !defined(__NO_LONG_DOUBLE_MATH) | | #if !defined(__NO_LONG_DOUBLE_MATH) | |
| static inline long double expm1(long double x) throw() | | static inline long double expm1(long double x) throw() | |
| { return ::expm1l(x); } | | { return ::expm1l(x); } | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | | #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | |
| | | | |
| skipping to change at line 214 | | skipping to change at line 235 | |
| * log(\e x + 1) accurate near \e x = 0. This is taken See | | * log(\e x + 1) accurate near \e x = 0. This is taken See | |
| * D. Goldberg, | | * D. Goldberg, | |
| * <a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html"> Wha
t | | * <a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html"> Wha
t | |
| * every computer scientist should know about floating-point arithmetic
</a> | | * every computer scientist should know about floating-point arithmetic
</a> | |
| * (1991), Theorem 4. See also, Higham (op. cit.), Answer to Problem 1
.5, | | * (1991), Theorem 4. See also, Higham (op. cit.), Answer to Problem 1
.5, | |
| * p 528. | | * p 528. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return log(\e x + 1). | | * @return log(\e x + 1). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real log1p(real x) throw() { | | template<typename T> | |
| volatile real | | static inline T log1p(T x) throw() { | |
| | | volatile T | |
| y = 1 + x, | | y = 1 + x, | |
| z = y - 1; | | z = y - 1; | |
| // Here's the explanation for this magic: y = 1 + z, exactly, and z | | // Here's the explanation for this magic: y = 1 + z, exactly, and z | |
| // approx x, thus log(y)/z (which is nearly constant near z = 0) retu
rns | | // approx x, thus log(y)/z (which is nearly constant near z = 0) retu
rns | |
| // a good approximation to the true log(1 + x)/x. The multiplication
x * | | // a good approximation to the true log(1 + x)/x. The multiplication
x * | |
| // (log(y)/z) introduces little additional error. | | // (log(y)/z) introduces little additional error. | |
| return z == 0 ? x : x * std::log(y) / z; | | return z == 0 ? x : x * std::log(y) / z; | |
| } | | } | |
| #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | | #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | |
|
| static inline real log1p(real x) throw() { return std::log1p(x); } | | template<typename T> | |
| | | static inline T log1p(T x) throw() { return std::log1p(x); } | |
| #else | | #else | |
| static inline double log1p(double x) throw() { return ::log1p(x); } | | static inline double log1p(double x) throw() { return ::log1p(x); } | |
| static inline float log1p(float x) throw() { return ::log1pf(x); } | | static inline float log1p(float x) throw() { return ::log1pf(x); } | |
| #if !defined(__NO_LONG_DOUBLE_MATH) | | #if !defined(__NO_LONG_DOUBLE_MATH) | |
| static inline long double log1p(long double x) throw() | | static inline long double log1p(long double x) throw() | |
| { return ::log1pl(x); } | | { return ::log1pl(x); } | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | | #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | |
| /** | | /** | |
| * The inverse hyperbolic sine function. This is defined in terms of | | * The inverse hyperbolic sine function. This is defined in terms of | |
| * Math::log1p(\e x) in order to maintain accuracy near \e x = 0. In | | * Math::log1p(\e x) in order to maintain accuracy near \e x = 0. In | |
| * addition, the odd parity of the function is enforced. | | * addition, the odd parity of the function is enforced. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return asinh(\e x). | | * @return asinh(\e x). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real asinh(real x) throw() { | | template<typename T> | |
| real y = std::abs(x); // Enforce odd parity | | static inline T asinh(T x) throw() { | |
| y = log1p(y * (1 + y/(hypot(real(1), y) + 1))); | | T y = std::abs(x); // Enforce odd parity | |
| | | y = log1p(y * (1 + y/(hypot(T(1), y) + 1))); | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
| } | | } | |
| #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | | #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | |
|
| static inline real asinh(real x) throw() { return std::asinh(x); } | | template<typename T> | |
| | | static inline T asinh(T x) throw() { return std::asinh(x); } | |
| #else | | #else | |
| static inline double asinh(double x) throw() { return ::asinh(x); } | | static inline double asinh(double x) throw() { return ::asinh(x); } | |
| static inline float asinh(float x) throw() { return ::asinhf(x); } | | static inline float asinh(float x) throw() { return ::asinhf(x); } | |
| #if !defined(__NO_LONG_DOUBLE_MATH) | | #if !defined(__NO_LONG_DOUBLE_MATH) | |
| static inline long double asinh(long double x) throw() | | static inline long double asinh(long double x) throw() | |
| { return ::asinhl(x); } | | { return ::asinhl(x); } | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | | #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | |
| /** | | /** | |
| * The inverse hyperbolic tangent function. This is defined in terms o
f | | * The inverse hyperbolic tangent function. This is defined in terms o
f | |
| * Math::log1p(\e x) in order to maintain accuracy near \e x = 0. In | | * Math::log1p(\e x) in order to maintain accuracy near \e x = 0. In | |
| * addition, the odd parity of the function is enforced. | | * addition, the odd parity of the function is enforced. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return atanh(\e x). | | * @return atanh(\e x). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real atanh(real x) throw() { | | template<typename T> | |
| real y = std::abs(x); // Enforce odd parity | | static inline T atanh(T x) throw() { | |
| | | T y = std::abs(x); // Enforce odd parity | |
| y = log1p(2 * y/(1 - y))/2; | | y = log1p(2 * y/(1 - y))/2; | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
| } | | } | |
| #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | | #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | |
|
| static inline real atanh(real x) throw() { return std::atanh(x); } | | template<typename T> | |
| | | static inline T atanh(T x) throw() { return std::atanh(x); } | |
| #else | | #else | |
| static inline double atanh(double x) throw() { return ::atanh(x); } | | static inline double atanh(double x) throw() { return ::atanh(x); } | |
| static inline float atanh(float x) throw() { return ::atanhf(x); } | | static inline float atanh(float x) throw() { return ::atanhf(x); } | |
| #if !defined(__NO_LONG_DOUBLE_MATH) | | #if !defined(__NO_LONG_DOUBLE_MATH) | |
| static inline long double atanh(long double x) throw() | | static inline long double atanh(long double x) throw() | |
| { return ::atanhl(x); } | | { return ::atanhl(x); } | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | | #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | |
| /** | | /** | |
| * The cube root function. | | * The cube root function. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return the real cube root of \e x. | | * @return the real cube root of \e x. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real cbrt(real x) throw() { | | template<typename T> | |
| real y = std::pow(std::abs(x), 1/real(3)); // Return the real cube ro | | static inline T cbrt(T x) throw() { | |
| ot | | T y = std::pow(std::abs(x), 1/T(3)); // Return the real cube root | |
| return x < 0 ? -y : y; | | return x < 0 ? -y : y; | |
| } | | } | |
| #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | | #elif GEOGRAPHICLIB_CPLUSPLUS0X_MATH | |
|
| static inline real cbrt(real x) throw() { return std::cbrt(x); } | | template<typename T> | |
| | | static inline T cbrt(T x) throw() { return std::cbrt(x); } | |
| #else | | #else | |
| static inline double cbrt(double x) throw() { return ::cbrt(x); } | | static inline double cbrt(double x) throw() { return ::cbrt(x); } | |
| static inline float cbrt(float x) throw() { return ::cbrtf(x); } | | static inline float cbrt(float x) throw() { return ::cbrtf(x); } | |
| #if !defined(__NO_LONG_DOUBLE_MATH) | | #if !defined(__NO_LONG_DOUBLE_MATH) | |
| static inline long double cbrt(long double x) throw() { return ::cbrtl(
x); } | | static inline long double cbrt(long double x) throw() { return ::cbrtl(
x); } | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| /** | | /** | |
| * Test for finiteness. | | * Test for finiteness. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return true if number is finite, false if NaN or infinite. | | * @return true if number is finite, false if NaN or infinite. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline bool isfinite(real x) throw() { | | template<typename T> | |
| | | static inline bool isfinite(T x) throw() { | |
| #if defined(DOXYGEN) | | #if defined(DOXYGEN) | |
|
| return std::abs(x) <= std::numeric_limits<real>::max(); | | return std::abs(x) <= std::numeric_limits<T>::max(); | |
| #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH) | | #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MATH) | |
| return _finite(x) != 0; | | return _finite(x) != 0; | |
| #else | | #else | |
| return std::isfinite(x); | | return std::isfinite(x); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| /** | | /** | |
| * The NaN (not a number) | | * The NaN (not a number) | |
| * | | * | |
| * @return NaN if available, otherwise return the max real. | | * @return NaN if available, otherwise return the max real. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real NaN() throw() { | | template<typename T> | |
| return std::numeric_limits<real>::has_quiet_NaN ? | | static inline T NaN() throw() { | |
| std::numeric_limits<real>::quiet_NaN() : | | return std::numeric_limits<T>::has_quiet_NaN ? | |
| std::numeric_limits<real>::max(); | | std::numeric_limits<T>::quiet_NaN() : | |
| | | std::numeric_limits<T>::max(); | |
| } | | } | |
|
| | | /** | |
| | | * A synonym for NaN<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline real NaN() throw() { return NaN<real>(); } | |
| | | | |
| /** | | /** | |
| * Test for NaN. | | * Test for NaN. | |
| * | | * | |
| * @param[in] x | | * @param[in] x | |
| * @return true if argument is a NaN. | | * @return true if argument is a NaN. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline bool isnan(real x) throw() { | | template<typename T> | |
| | | static inline bool isnan(T x) throw() { | |
| #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | | #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS0X_MA
TH) | |
| return x != x; | | return x != x; | |
| #else | | #else | |
| return std::isnan(x); | | return std::isnan(x); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Infinity | | * Infinity | |
| * | | * | |
| * @return infinity if available, otherwise return the max real. | | * @return infinity if available, otherwise return the max real. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline real infinity() throw() { | | template<typename T> | |
| return std::numeric_limits<real>::has_infinity ? | | static inline T infinity() throw() { | |
| std::numeric_limits<real>::infinity() : | | return std::numeric_limits<T>::has_infinity ? | |
| std::numeric_limits<real>::max(); | | std::numeric_limits<T>::infinity() : | |
| | | std::numeric_limits<T>::max(); | |
| } | | } | |
|
| | | | |
| /** | | | |
| * @return \e pi in extended precision | | | |
| ********************************************************************** | | | |
| / | | | |
| static inline extended epi() throw() | | | |
| // good for about 168-bit accuracy | | | |
| { return extended(3.1415926535897932384626433832795028841971693993751L) | | | |
| ; } | | | |
| | | | |
| /** | | /** | |
|
| * @return the number of radians in a degree in extended precision. | | * A synonym for infinity<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline extended edegree() throw() { return epi() / 180; } | | static inline real infinity() throw() { return infinity<real>(); } | |
| }; | | }; | |
| | | | |
| /** | | /** | |
| * \brief %Constants needed by %GeographicLib | | * \brief %Constants needed by %GeographicLib | |
| * | | * | |
| * Define constants specifying the WGS84 ellipsoid, the UTM and UPS | | * Define constants specifying the WGS84 ellipsoid, the UTM and UPS | |
| * projections, and various unit conversions. | | * projections, and various unit conversions. | |
| **********************************************************************/ | | **********************************************************************/ | |
| class Constants { | | class Constants { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| Constants(); // Disable constructor | | Constants(); // Disable constructor | |
| | | | |
| public: | | public: | |
| /** | | /** | |
|
| * @return \e pi. This duplicates Math::pi(). | | * <b>DEPRECATED</b> A synonym for Math::pi<real>(). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real pi() throw() { return Math::pi(); } | | static inline Math::real pi() throw() { return Math::pi<real>(); } | |
| /** | | /** | |
|
| * @return the number of radians in a degree. This duplicates | | * A synonym for Math::degree<real>(). | |
| * Math::degree(). | | | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real degree() throw() { return Math::degree(); } | | static inline Math::real degree() throw() { return Math::degree<real>()
; } | |
| /** | | /** | |
| * @return the number of radians in an arcminute. | | * @return the number of radians in an arcminute. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real arcminute() throw() { return Math::degree() / | | static inline Math::real arcminute() throw() | |
| 60; } | | { return Math::degree<real>() / 60; } | |
| /** | | /** | |
| * @return the number of radians in an arcsecond. | | * @return the number of radians in an arcsecond. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real arcsecond() throw() | | static inline Math::real arcsecond() throw() | |
|
| { return Math::degree() / 3600; } | | { return Math::degree<real>() / 3600; } | |
| | | | |
| /** \name Ellipsoid parameters | | /** \name Ellipsoid parameters | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return the equatorial radius of WGS84 ellipsoid | | * @return the equatorial radius of WGS84 ellipsoid | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real WGS84_a() throw() { return 6378137 * meter(); | | template<typename T> | |
| } | | static inline T WGS84_a() throw() { return T(6378137) * meter<T>(); } | |
| | | /** | |
| | | * A synonym for WGS84_a<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real WGS84_a() throw() { return WGS84_a<real>(); } | |
| /** | | /** | |
| * @return the reciprocal flattening of WGS84 ellipsoid | | * @return the reciprocal flattening of WGS84 ellipsoid | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real WGS84_r() throw() { return real(298.257223563L | | template<typename T> | |
| ); } | | static inline T WGS84_r() throw() { | |
| | | // 298.257223563 = 3393 * 87903691 / 1000000000 | |
| | | return (T(3393) * T(87903691)) / T(1000000000); | |
| | | } | |
| | | /** | |
| | | * A synonym for WGS84_r<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real WGS84_r() throw() { return WGS84_r<real>(); } | |
| /** | | /** | |
| * @return the central scale factor for UTM | | * @return the central scale factor for UTM | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real UTM_k0() throw() {return real(0.9996L); } | | template<typename T> | |
| | | static inline T UTM_k0() throw() {return T(9996) / T(10000); } // 0.999 | |
| | | 6 | |
| | | /** | |
| | | * A synonym for UTM_k0<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real UTM_k0() throw() { return UTM_k0<real>(); } | |
| /** | | /** | |
| * @return the central scale factor for UPS | | * @return the central scale factor for UPS | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real UPS_k0() throw() { return real(0.994L); } | | template<typename T> | |
| | | static inline T UPS_k0() throw() { return T(994) / T(1000); } // 0.994 | |
| | | /** | |
| | | * A synonym for UPS_k0<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real UPS_k0() throw() { return UPS_k0<real>(); } | |
| ///@} | | ///@} | |
| | | | |
| /** \name SI units | | /** \name SI units | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return the number of meters in a meter. | | * @return the number of meters in a meter. | |
| * | | * | |
| * This is unity, but this lets the internal system of units be changed
if | | * This is unity, but this lets the internal system of units be changed
if | |
| * necessary. | | * necessary. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real meter() throw() { return real(1); } | | template<typename T> | |
| | | static inline T meter() throw() { return T(1); } | |
| | | /** | |
| | | * A synonym for meter<real>(). | |
| | | ********************************************************************** | |
| | | / | |
| | | static inline Math::real meter() throw() { return meter<real>(); } | |
| /** | | /** | |
| * @return the number of meters in a kilometer. | | * @return the number of meters in a kilometer. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real kilometer() throw() { return 1000 * meter(); } | | static inline Math::real kilometer() throw() | |
| | | { return 1000 * meter<real>(); } | |
| /** | | /** | |
| * @return the number of meters in a nautical mile (approximately 1 arc | | * @return the number of meters in a nautical mile (approximately 1 arc | |
| * minute) | | * minute) | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| static inline Math::real nauticalmile() throw() { return 1852 * meter() | | static inline Math::real nauticalmile() throw() | |
| ; } | | { return 1852 * meter<real>(); } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Anachronistic British units | | /** \name Anachronistic British units | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return the number of meters in an international foot. | | * @return the number of meters in an international foot. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real foot() throw() | | static inline Math::real foot() throw() | |
|
| { return real(0.0254L) * 12 * meter(); } | | { return real(0.0254L) * 12 * meter<real>(); } | |
| /** | | /** | |
| * @return the number of meters in a yard. | | * @return the number of meters in a yard. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real yard() throw() { return 3 * foot(); } | | static inline Math::real yard() throw() { return 3 * foot(); } | |
| /** | | /** | |
| * @return the number of meters in a fathom. | | * @return the number of meters in a fathom. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real fathom() throw() { return 2 * yard(); } | | static inline Math::real fathom() throw() { return 2 * yard(); } | |
| /** | | /** | |
| * @return the number of meters in a chain. | | * @return the number of meters in a chain. | |
| | | | |
| skipping to change at line 481 | | skipping to change at line 540 | |
| static inline Math::real mile() throw() { return 8 * furlong(); } | | static inline Math::real mile() throw() { return 8 * furlong(); } | |
| ///@} | | ///@} | |
| | | | |
| /** \name Anachronistic US units | | /** \name Anachronistic US units | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return the number of meters in a US survey foot. | | * @return the number of meters in a US survey foot. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static inline Math::real surveyfoot() throw() | | static inline Math::real surveyfoot() throw() | |
|
| { return real(1200) / real(3937) * meter(); } | | { return real(1200) / real(3937) * meter<real>(); } | |
| ///@} | | ///@} | |
| }; | | }; | |
| | | | |
| /** | | /** | |
| * \brief %Exception handling for %GeographicLib | | * \brief %Exception handling for %GeographicLib | |
| * | | * | |
| * A class to handle exceptions. It's derived off std::runtime_error so
it | | * A class to handle exceptions. It's derived off std::runtime_error so
it | |
| * can be caught by the usual catch clauses. | | * can be caught by the usual catch clauses. | |
| **********************************************************************/ | | **********************************************************************/ | |
| class GeographicErr : public std::runtime_error { | | class GeographicErr : public std::runtime_error { | |
| | | | |
End of changes. 42 change blocks. |
| 70 lines changed or deleted | | 132 lines changed or added | |
|
| DMS.hpp | | DMS.hpp | |
| /** | | /** | |
| * \file DMS.hpp | | * \file DMS.hpp | |
| * \brief Header for GeographicLib::DMS class | | * \brief Header for GeographicLib::DMS class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2008, 2009, 2010, 2011) <charles@karney.co
m> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_DMS_HPP) | | #if !defined(GEOGRAPHICLIB_DMS_HPP) | |
|
| #define GEOGRAPHICLIB_DMS_HPP "$Id: DMS.hpp 6911 2010-12-09 23:13:55Z karne
y $" | | #define GEOGRAPHICLIB_DMS_HPP "$Id: DMS.hpp 6954 2011-02-16 14:36:56Z karne
y $" | |
| | | | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
| #include <sstream> | | #include <sstream> | |
| #include <iomanip> | | #include <iomanip> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Convert between degrees and %DMS representation. | | * \brief Convert between degrees and %DMS representation. | |
| * | | * | |
| | | | |
| skipping to change at line 130 | | skipping to change at line 130 | |
| * malformed string. No check is performed on the range of the result. | | * malformed string. No check is performed on the range of the result. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real Decode(const std::string& dms, flag& ind); | | static Math::real Decode(const std::string& dms, flag& ind); | |
| | | | |
| /** | | /** | |
| * Convert DMS to an angle. | | * Convert DMS to an angle. | |
| * | | * | |
| * @param[in] d degrees. | | * @param[in] d degrees. | |
| * @param[in] m arc minutes. | | * @param[in] m arc minutes. | |
| * @param[in] s arc seconds. | | * @param[in] s arc seconds. | |
|
| * @return angle (degress) | | * @return angle (degrees) | |
| * | | * | |
| * This does not propagate the sign on \e d to the other components, so | | * This does not propagate the sign on \e d to the other components, so | |
| * -3d20' would need to be represented as - DMS::Decode(3.0, 20.0) or | | * -3d20' would need to be represented as - DMS::Decode(3.0, 20.0) or | |
| * DMS::Decode(-3.0, -20.0). | | * DMS::Decode(-3.0, -20.0). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static Math::real Decode(real d, real m = 0, real s = 0) throw() | | static Math::real Decode(real d, real m = 0, real s = 0) throw() | |
| { return d + (m + s/real(60))/real(60); } | | { return d + (m + s/real(60))/real(60); } | |
| | | | |
| /** | | /** | |
| * Convert a string to a real number. | | * Convert a string to a real number. | |
| | | | |
| skipping to change at line 200 | | skipping to change at line 200 | |
| | | | |
| /** | | /** | |
| * Convert angle (in degrees) into a DMS string. | | * Convert angle (in degrees) into a DMS string. | |
| * | | * | |
| * @param[in] angle input angle (degrees) | | * @param[in] angle input angle (degrees) | |
| * @param[in] trailing DMS::component value indicating the trailing uni
ts | | * @param[in] trailing DMS::component value indicating the trailing uni
ts | |
| * on the string and this is given as a decimal number if necessary. | | * on the string and this is given as a decimal number if necessary. | |
| * @param[in] prec the number of digits after the decimal point for the | | * @param[in] prec the number of digits after the decimal point for the | |
| * trailing component. | | * trailing component. | |
| * @param[in] ind DMS::flag value indicated additional formatting. | | * @param[in] ind DMS::flag value indicated additional formatting. | |
|
| * @return formatting string | | * @return formatted string | |
| * | | * | |
| * The interpretation of \e ind is as follows: | | * The interpretation of \e ind is as follows: | |
| * - ind == DMS::NONE, signed result no leading zeros on degrees except
in | | * - ind == DMS::NONE, signed result no leading zeros on degrees except
in | |
| * the units place, e.g., -8d03'. | | * the units place, e.g., -8d03'. | |
| * - ind == DMS::LATITUDE, trailing N or S hemisphere designator, no si
gn, | | * - ind == DMS::LATITUDE, trailing N or S hemisphere designator, no si
gn, | |
|
| * pad degress to 2 digits, e.g., 08d03'S. | | * pad degrees to 2 digits, e.g., 08d03'S. | |
| * - ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no | | * - ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no | |
|
| * sign, pad degress to 3 digits, e.g., 008d03'W. | | * sign, pad degrees to 3 digits, e.g., 008d03'W. | |
| * - ind == DMS::AZIMUTH, convert to the range [0, 360<sup>o</sup>), no | | * - ind == DMS::AZIMUTH, convert to the range [0, 360<sup>o</sup>), no | |
| * sign, pad degrees to 3 digits, , e.g., 351d57'. | | * sign, pad degrees to 3 digits, , e.g., 351d57'. | |
| * . | | * . | |
| * The integer parts of the minutes and seconds components are always g
iven | | * The integer parts of the minutes and seconds components are always g
iven | |
| * with 2 digits. | | * with 2 digits. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static std::string Encode(real angle, component trailing, unsigned prec
, | | static std::string Encode(real angle, component trailing, unsigned prec
, | |
| flag ind = NONE); | | flag ind = NONE); | |
| | | | |
| /** | | /** | |
| * Convert angle into a DMS string selecting the trailing component | | * Convert angle into a DMS string selecting the trailing component | |
| * based on the precision. | | * based on the precision. | |
| * | | * | |
| * @param[in] angle input angle (degrees) | | * @param[in] angle input angle (degrees) | |
| * @param[in] prec the precision relative to 1 degree. | | * @param[in] prec the precision relative to 1 degree. | |
| * @param[in] ind DMS::flag value indicated additional formatting. | | * @param[in] ind DMS::flag value indicated additional formatting. | |
|
| * @return formatting string | | * @return formatted string | |
| * | | * | |
| * \e prec indicates the precision relative to 1 degree, e.g., \e prec
= 3 | | * \e prec indicates the precision relative to 1 degree, e.g., \e prec
= 3 | |
| * gives a result accurate to 0.1' and \e prec = 4 gives a result accur
ate | | * gives a result accurate to 0.1' and \e prec = 4 gives a result accur
ate | |
| * to 1". \e ind is interpreted as in DMS::Encode with the additi
onal | | * to 1". \e ind is interpreted as in DMS::Encode with the additi
onal | |
| * facility at DMS::NUMBER treats \e angle a number in fixed format wit
h | | * facility at DMS::NUMBER treats \e angle a number in fixed format wit
h | |
| * precision \e prec. | | * precision \e prec. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static std::string Encode(real angle, unsigned prec, flag ind = NONE) { | | static std::string Encode(real angle, unsigned prec, flag ind = NONE) { | |
| if (ind == NUMBER) { | | if (ind == NUMBER) { | |
| if (!Math::isfinite(angle)) | | if (!Math::isfinite(angle)) | |
| | | | |
End of changes. 7 change blocks. |
| 7 lines changed or deleted | | 7 lines changed or added | |
|
| Geocentric.hpp | | Geocentric.hpp | |
| /** | | /** | |
| * \file Geocentric.hpp | | * \file Geocentric.hpp | |
| * \brief Header for GeographicLib::Geocentric class | | * \brief Header for GeographicLib::Geocentric class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2008, 2009, 2010, 2011) <charles@karney.co
m> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEOCENTRIC_HPP) | | #if !defined(GEOGRAPHICLIB_GEOCENTRIC_HPP) | |
|
| #define GEOGRAPHICLIB_GEOCENTRIC_HPP "$Id: Geocentric.hpp 6876 2010-10-18 1
3:47:55Z karney $" | | #define GEOGRAPHICLIB_GEOCENTRIC_HPP "$Id: Geocentric.hpp 6967 2011-02-19 1
5:53:41Z karney $" | |
| | | | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
|
| | | #include <vector> | |
| | | #include <algorithm> | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief %Geocentric coordinates | | * \brief %Geocentric coordinates | |
| * | | * | |
| * Convert between geodetic coordinates latitude = \e lat, longitude = \e | | * Convert between geodetic coordinates latitude = \e lat, longitude = \e | |
| * lon, height = \e h (measured vertically from the surface of the ellips
oid) | | * lon, height = \e h (measured vertically from the surface of the ellips
oid) | |
| * to geocentric coordinates (\e x, \e y, \e z). The origin of geocentri
c | | * to geocentric coordinates (\e x, \e y, \e z). The origin of geocentri
c | |
| * coordinates is at the center of the earth. The \e z axis goes thru th
e | | * coordinates is at the center of the earth. The \e z axis goes thru th
e | |
| * north pole, \e lat = 90<sup>o</sup>. The \e x axis goes thru \e lat =
0, | | * north pole, \e lat = 90<sup>o</sup>. The \e x axis goes thru \e lat =
0, | |
|
| * \e lon = 0. Geocentric coordinates are also known as earth centered, | | * \e lon = 0. %Geocentric coordinates are also known as earth centered, | |
| * earth fixed (ECEF) coordinates. | | * earth fixed (ECEF) coordinates. | |
| * | | * | |
| * The conversion from geographic to geocentric coordinates is | | * The conversion from geographic to geocentric coordinates is | |
| * straightforward. For the reverse transformation we use | | * straightforward. For the reverse transformation we use | |
| * - H. Vermeille, | | * - H. Vermeille, | |
| * <a href="http://dx.doi.org/10.1007/s00190-002-0273-6"> Direct | | * <a href="http://dx.doi.org/10.1007/s00190-002-0273-6"> Direct | |
| * transformation from geocentric coordinates to geodetic coordinates</
a>, | | * transformation from geocentric coordinates to geodetic coordinates</
a>, | |
| * J. Geodesy 76, 451–454 (2002). | | * J. Geodesy 76, 451–454 (2002). | |
| * . | | * . | |
| * Several changes have been made to ensure that the method returns accur
ate | | * Several changes have been made to ensure that the method returns accur
ate | |
|
| * results for all finite inputs (even if \e h is infinite). See | | * results for all finite inputs (even if \e h is infinite). The changes | |
| * \ref geocentric for details. | | are | |
| | | * described in Appendix B of | |
| | | * - C. F. F. Karney, | |
| | | * <a href="http://arxiv.org/abs/1102.1215">Geodesics | |
| | | * on an ellipsoid of revolution</a>, | |
| | | * Feb. 2011; | |
| | | * preprint | |
| | | * <a href="http://arxiv.org/abs/1102.1215">arxiv:1102.1215</a>. | |
| | | * . | |
| | | * See \ref geocentric for more information. | |
| * | | * | |
| * The errors in these routines are close to round-off. Specifically, fo
r | | * The errors in these routines are close to round-off. Specifically, fo
r | |
| * points within 5000 km of the surface of the ellipsoid (either inside o
r | | * points within 5000 km of the surface of the ellipsoid (either inside o
r | |
| * outside the ellipsoid), the error is bounded by 7 nm for the WGS84 | | * outside the ellipsoid), the error is bounded by 7 nm for the WGS84 | |
| * ellipsoid. See \ref geocentric for further information on the errors. | | * ellipsoid. See \ref geocentric for further information on the errors. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class Geocentric { | | class Geocentric { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| | | friend class LocalCartesian; | |
| | | static const size_t dim = 3, dim2 = dim * dim; | |
| const real _a, _r, _f, _e2, _e2m, _e2a, _e4a, _maxrad; | | const real _a, _r, _f, _e2, _e2m, _e2a, _e4a, _maxrad; | |
| static inline real sq(real x) throw() { return x * x; } | | static inline real sq(real x) throw() { return x * x; } | |
|
| | | // Actually this can be static because it doesn't depend on the ellipso | |
| | | id. | |
| | | // But let's be more general than that. | |
| | | void Rotation(real sphi, real cphi, real slam, real clam, | |
| | | real M[dim2]) const throw(); | |
| | | void IntForward(real lat, real lon, real h, real& x, real& y, real& z, | |
| | | real M[dim2]) const throw(); | |
| | | void IntReverse(real x, real y, real z, real& lat, real& lon, real& h, | |
| | | real M[dim2]) const throw(); | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor for a ellipsoid with | | * Constructor for a ellipsoid with | |
| * | | * | |
| * @param[in] a equatorial radius (meters) | | * @param[in] a equatorial radius (meters) | |
| * @param[in] r reciprocal flattening. Setting \e r = 0 implies \e r =
inf | | * @param[in] r reciprocal flattening. Setting \e r = 0 implies \e r =
inf | |
| * or flattening = 0 (i.e., a sphere). Negative \e r indicates a pro
late | | * or flattening = 0 (i.e., a sphere). Negative \e r indicates a pro
late | |
| * ellipsoid. | | * ellipsoid. | |
| * | | * | |
| | | | |
| skipping to change at line 79 | | skipping to change at line 99 | |
| * @param[in] lon longitude of point (degrees). | | * @param[in] lon longitude of point (degrees). | |
| * @param[in] h height of point above the ellipsoid (meters). | | * @param[in] h height of point above the ellipsoid (meters). | |
| * @param[out] x geocentric coordinate (meters). | | * @param[out] x geocentric coordinate (meters). | |
| * @param[out] y geocentric coordinate (meters). | | * @param[out] y geocentric coordinate (meters). | |
| * @param[out] z geocentric coordinate (meters). | | * @param[out] z geocentric coordinate (meters). | |
| * | | * | |
| * \e lat should be in the range [-90, 90]; \e lon and \e lon0 should b
e in | | * \e lat should be in the range [-90, 90]; \e lon and \e lon0 should b
e in | |
| * the range [-180, 360]. | | * the range [-180, 360]. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Forward(real lat, real lon, real h, real& x, real& y, real& z) | | void Forward(real lat, real lon, real h, real& x, real& y, real& z) | |
|
| const throw(); | | const throw() { | |
| | | IntForward(lat, lon, h, x, y, z, NULL); | |
| | | } | |
| | | | |
| | | /** | |
| | | * Convert from geodetic to geocentric coordinates and return rotation | |
| | | * matrix. | |
| | | * | |
| | | * @param[in] lat latitude of point (degrees). | |
| | | * @param[in] lon longitude of point (degrees). | |
| | | * @param[in] h height of point above the ellipsoid (meters). | |
| | | * @param[out] x geocentric coordinate (meters). | |
| | | * @param[out] y geocentric coordinate (meters). | |
| | | * @param[out] z geocentric coordinate (meters). | |
| | | * @param[out] M if the length of the vector is 9, fill with the rotati | |
| | | on | |
| | | * matrix in row-major order. | |
| | | * | |
| | | * Pre-multiplying a unit vector in local cartesian coordinates (east, | |
| | | * north, up) by \e M transforms the vector to geocentric coordinates. | |
| | | ********************************************************************** | |
| | | / | |
| | | void Forward(real lat, real lon, real h, real& x, real& y, real& z, | |
| | | std::vector<real>& M) | |
| | | const throw() { | |
| | | real t[dim2]; | |
| | | IntForward(lat, lon, h, x, y, z, t); | |
| | | if (M.end() == M.begin() + dim2) | |
| | | copy(t, t + dim2, M.begin()); | |
| | | } | |
| | | | |
| /** | | /** | |
| * Convert from geocentric to geodetic to coordinates. | | * Convert from geocentric to geodetic to coordinates. | |
| * | | * | |
| * @param[in] x geocentric coordinate (meters). | | * @param[in] x geocentric coordinate (meters). | |
| * @param[in] y geocentric coordinate (meters). | | * @param[in] y geocentric coordinate (meters). | |
| * @param[in] z geocentric coordinate (meters). | | * @param[in] z geocentric coordinate (meters). | |
| * @param[out] lat latitude of point (degrees). | | * @param[out] lat latitude of point (degrees). | |
| * @param[out] lon longitude of point (degrees). | | * @param[out] lon longitude of point (degrees). | |
| * @param[out] h height of point above the ellipsoid (meters). | | * @param[out] h height of point above the ellipsoid (meters). | |
| | | | |
| skipping to change at line 101 | | skipping to change at line 148 | |
| * In general there are multiple solutions and the result which maximiz
es | | * In general there are multiple solutions and the result which maximiz
es | |
| * \e h is returned. If there are still multiple solutions with differ
ent | | * \e h is returned. If there are still multiple solutions with differ
ent | |
| * latitutes (applies only if \e z = 0), then the solution with \e lat
> 0 | | * latitutes (applies only if \e z = 0), then the solution with \e lat
> 0 | |
| * is returned. If there are still multiple solutions with different | | * is returned. If there are still multiple solutions with different | |
| * longitudes (applies only if \e x = \e y = 0) then \e lon = 0 is | | * longitudes (applies only if \e x = \e y = 0) then \e lon = 0 is | |
| * returned. The value of \e h returned satisfies \e h >= - \e a (1 -
\e | | * returned. The value of \e h returned satisfies \e h >= - \e a (1 -
\e | |
| * e<sup>2</sup>) / sqrt(1 - \e e<sup>2</sup> sin<sup>2</sup>\e lat).
The | | * e<sup>2</sup>) / sqrt(1 - \e e<sup>2</sup> sin<sup>2</sup>\e lat).
The | |
| * value of \e lon returned is in the range [-180, 180). | | * value of \e lon returned is in the range [-180, 180). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Reverse(real x, real y, real z, real& lat, real& lon, real& h) | | void Reverse(real x, real y, real z, real& lat, real& lon, real& h) | |
|
| const throw(); | | const throw() { | |
| | | IntReverse(x, y, z, lat, lon, h, NULL); | |
| | | } | |
| | | | |
| | | /** | |
| | | * Convert from geocentric to geodetic to coordinates. | |
| | | * | |
| | | * @param[in] x geocentric coordinate (meters). | |
| | | * @param[in] y geocentric coordinate (meters). | |
| | | * @param[in] z geocentric coordinate (meters). | |
| | | * @param[out] lat latitude of point (degrees). | |
| | | * @param[out] lon longitude of point (degrees). | |
| | | * @param[out] h height of point above the ellipsoid (meters). | |
| | | * @param[out] M if the length of the vector is 9, fill with the rotati | |
| | | on | |
| | | * matrix in row-major order. | |
| | | * | |
| | | * Pre-multiplying a unit vector in geocentric coordinates by the trans | |
| | | pose | |
| | | * of \e M transforms the vector to local cartesian coordinates (east, | |
| | | * north, up). | |
| | | ********************************************************************** | |
| | | / | |
| | | void Reverse(real x, real y, real z, real& lat, real& lon, real& h, | |
| | | std::vector<real>& M) | |
| | | const throw() { | |
| | | real t[dim2]; | |
| | | IntReverse(x, y, z, lat, lon, h, t); | |
| | | if (M.end() == M.begin() + dim2) | |
| | | copy(t, t + dim2, M.begin()); | |
| | | } | |
| | | | |
| /** \name Inspector functions | | /** \name Inspector functions | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return \e a the equatorial radius of the ellipsoid (meters). This
is | | * @return \e a the equatorial radius of the ellipsoid (meters). This
is | |
| * the value used in the constructor. | | * the value used in the constructor. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const throw() { return _a; } | | Math::real MajorRadius() const throw() { return _a; } | |
| | | | |
| | | | |
End of changes. 9 change blocks. |
| 7 lines changed or deleted | | 88 lines changed or added | |
|
| Geodesic.hpp | | Geodesic.hpp | |
| /** | | /** | |
| * \file Geodesic.hpp | | * \file Geodesic.hpp | |
| * \brief Header for GeographicLib::Geodesic class | | * \brief Header for GeographicLib::Geodesic class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2009, 2010, 2011) <charles@karney.com> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEODESIC_HPP) | | #if !defined(GEOGRAPHICLIB_GEODESIC_HPP) | |
|
| #define GEOGRAPHICLIB_GEODESIC_HPP "$Id: Geodesic.hpp 6876 2010-10-18 13:47
:55Z karney $" | | #define GEOGRAPHICLIB_GEODESIC_HPP "$Id: Geodesic.hpp 6950 2011-02-11 04:09
:24Z karney $" | |
| | | | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
| | | | |
| #if !defined(GEOD_ORD) | | #if !defined(GEOD_ORD) | |
| /** | | /** | |
| * The order of the expansions used by Geodesic. | | * The order of the expansions used by Geodesic. | |
| **********************************************************************/ | | **********************************************************************/ | |
| #define GEOD_ORD (GEOGRAPHICLIB_PREC == 1 ? 6 : GEOGRAPHICLIB_PREC == 0 ? 3
: 7) | | #define GEOD_ORD (GEOGRAPHICLIB_PREC == 1 ? 6 : GEOGRAPHICLIB_PREC == 0 ? 3
: 7) | |
| #endif | | #endif | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| class GeodesicLine; | | class GeodesicLine; | |
| | | | |
| /** | | /** | |
| * \brief %Geodesic calculations | | * \brief %Geodesic calculations | |
| * | | * | |
|
| | | | |
| * The shortest path between two points on a ellipsoid at (\e lat1, \e lo
n1) | | * The shortest path between two points on a ellipsoid at (\e lat1, \e lo
n1) | |
| * and (\e lat2, \e lon2) is called the geodesic. Its length is \e s12 a
nd | | * and (\e lat2, \e lon2) is called the geodesic. Its length is \e s12 a
nd | |
| * the geodesic from point 1 to point 2 has azimuths \e azi1 and \e azi2
at | | * the geodesic from point 1 to point 2 has azimuths \e azi1 and \e azi2
at | |
| * the two end points. (The azimuth is the heading measured clockwise fr
om | | * the two end points. (The azimuth is the heading measured clockwise fr
om | |
| * north. \e azi2 is the "forward" azimuth, i.e., the heading that takes
you | | * north. \e azi2 is the "forward" azimuth, i.e., the heading that takes
you | |
| * beyond point 2 not back to point 1.) | | * beyond point 2 not back to point 1.) | |
| * | | * | |
| * Given \e lat1, \e lon1, \e azi1, and \e s12, we can determine \e lat2,
\e | | * Given \e lat1, \e lon1, \e azi1, and \e s12, we can determine \e lat2,
\e | |
| * lon2, and \e azi2. This is the \e direct geodesic problem and its | | * lon2, and \e azi2. This is the \e direct geodesic problem and its | |
| * solution is given by the function Geodesic::Direct. (If \e s12 is | | * solution is given by the function Geodesic::Direct. (If \e s12 is | |
| | | | |
| skipping to change at line 92 | | skipping to change at line 93 | |
| * polygon. | | * polygon. | |
| * | | * | |
| * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and | | * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and | |
| * Geodesic::Inverse allow these quantities to be returned. In addition | | * Geodesic::Inverse allow these quantities to be returned. In addition | |
| * there are general functions Geodesic::GenDirect, and Geodesic::GenInve
rse | | * there are general functions Geodesic::GenDirect, and Geodesic::GenInve
rse | |
| * which allow an arbitrary set of results to be computed. | | * which allow an arbitrary set of results to be computed. | |
| * | | * | |
| * Additional functionality if provided by the GeodesicLine class, which | | * Additional functionality if provided by the GeodesicLine class, which | |
| * allows a sequence of points along a geodesic to be computed. | | * allows a sequence of points along a geodesic to be computed. | |
| * | | * | |
|
| * The calculations are accurate to better than 15 nm. (See \ref geoderr | | * The calculations are accurate to better than 15 nm. See Sec. 9 of | |
| ors | | * <a href="http://arxiv.org/abs/1102.1215">arXiv:1102.1215</a> for detai | |
| * for details.) | | ls. | |
| * | | * | |
|
| | | * The algorithms are described in | |
| | | * - C. F. F. Karney, | |
| | | * <a href="http://arxiv.org/abs/1102.1215">Geodesics | |
| | | * on an ellipsoid of revolution</a>, | |
| | | * Feb. 2011; | |
| | | * preprint | |
| | | * <a href="http://arxiv.org/abs/1102.1215">arXiv:1102.1215</a>. | |
| | | * . | |
| * For more information on geodesics see \ref geodesic. | | * For more information on geodesics see \ref geodesic. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class Geodesic { | | class Geodesic { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class GeodesicLine; | | friend class GeodesicLine; | |
| static const int nA1 = GEOD_ORD, nC1 = GEOD_ORD, nC1p = GEOD_ORD, | | static const int nA1 = GEOD_ORD, nC1 = GEOD_ORD, nC1p = GEOD_ORD, | |
| nA2 = GEOD_ORD, nC2 = GEOD_ORD, | | nA2 = GEOD_ORD, nC2 = GEOD_ORD, | |
| nA3 = GEOD_ORD, nA3x = nA3, | | nA3 = GEOD_ORD, nA3x = nA3, | |
| | | | |
| skipping to change at line 765 | | skipping to change at line 774 | |
| * (infinite inverse flattening). | | * (infinite inverse flattening). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real InverseFlattening() const throw() { return _r; } | | Math::real InverseFlattening() const throw() { return _r; } | |
| | | | |
| /** | | /** | |
| * @return total area of ellipsoid in meters<sup>2</sup>. The area of
a | | * @return total area of ellipsoid in meters<sup>2</sup>. The area of
a | |
| * polygon encircling a pole can be found by adding | | * polygon encircling a pole can be found by adding | |
| * Geodesic::EllipsoidArea()/2 to the sum of \e S12 for each side of
the | | * Geodesic::EllipsoidArea()/2 to the sum of \e S12 for each side of
the | |
| * polygon. | | * polygon. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
|
| Math::real EllipsoidArea() const throw() { return 4 * Math::pi() * _c2; | | Math::real EllipsoidArea() const throw() | |
| } | | { return 4 * Math::pi<real>() * _c2; } | |
| ///@} | | ///@} | |
| | | | |
| /** | | /** | |
| * A global instantiation of Geodesic with the parameters for the WGS84 | | * A global instantiation of Geodesic with the parameters for the WGS84 | |
| * ellipsoid. | | * ellipsoid. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| static const Geodesic WGS84; | | static const Geodesic WGS84; | |
| | | | |
| /** \name Deprecated function. | | /** \name Deprecated function. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| | | | |
End of changes. 6 change blocks. |
| 7 lines changed or deleted | | 16 lines changed or added | |
|
| GeodesicLine.hpp | | GeodesicLine.hpp | |
| /** | | /** | |
| * \file GeodesicLine.hpp | | * \file GeodesicLine.hpp | |
| * \brief Header for GeographicLib::GeodesicLine class | | * \brief Header for GeographicLib::GeodesicLine class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2009, 2010, 2011) <charles@karney.com> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP) | | #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP) | |
|
| #define GEOGRAPHICLIB_GEODESICLINE_HPP "$Id: GeodesicLine.hpp 6875 2010-10-
02 19:31:54Z karney $" | | #define GEOGRAPHICLIB_GEODESICLINE_HPP "$Id: GeodesicLine.hpp 6950 2011-02-
11 04:09:24Z karney $" | |
| | | | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
| #include "GeographicLib/Geodesic.hpp" | | #include "GeographicLib/Geodesic.hpp" | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief A geodesic line. | | * \brief A geodesic line. | |
| * | | * | |
| * GeodesicLine facilitates the determination of a series of points on a | | * GeodesicLine facilitates the determination of a series of points on a | |
| | | | |
| skipping to change at line 64 | | skipping to change at line 64 | |
| } | | } | |
| \endcode | | \endcode | |
| * The default copy constructor and assignment operators work with this | | * The default copy constructor and assignment operators work with this | |
| * class, so that, for example, the previous example could start | | * class, so that, for example, the previous example could start | |
| \code | | \code | |
| GeographicLib::GeodesicLine l; | | GeographicLib::GeodesicLine l; | |
| l = g.Line(lat1, lon1, azi1); | | l = g.Line(lat1, lon1, azi1); | |
| \endcode | | \endcode | |
| * Similarly, a vector can be used to hold GeodesicLine objects. | | * Similarly, a vector can be used to hold GeodesicLine objects. | |
| * | | * | |
|
| * The calculations are accurate to better than 12 nm. (See \ref geoderr | | * The calculations are accurate to better than 15 nm. See Sec. 9 of | |
| ors | | * <a href="http://arxiv.org/abs/1102.1215">arXiv:1102.1215</a> for detai | |
| * for details.) | | ls. | |
| | | * | |
| | | * The algorithms are described in | |
| | | * - C. F. F. Karney, | |
| | | * <a href="http://arxiv.org/abs/1102.1215">Geodesics | |
| | | * on an ellipsoid of revolution</a>, | |
| | | * Feb. 2011; | |
| | | * preprint | |
| | | * <a href="http://arxiv.org/abs/1102.1215">arXiv:1102.1215</a>. | |
| | | * . | |
| | | * For more information on geodesics see \ref geodesic. | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class GeodesicLine { | | class GeodesicLine { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
| friend class Geodesic; | | friend class Geodesic; | |
| static const int nC1 = Geodesic::nC1, nC1p = Geodesic::nC1p, | | static const int nC1 = Geodesic::nC1, nC1p = Geodesic::nC1p, | |
| nC2 = Geodesic::nC2, nC3 = Geodesic::nC3, nC4 = Geodesic::nC4; | | nC2 = Geodesic::nC2, nC3 = Geodesic::nC3, nC4 = Geodesic::nC4; | |
| | | | |
| real _lat1, _lon1, _azi1; | | real _lat1, _lon1, _azi1; | |
| | | | |
| skipping to change at line 540 | | skipping to change at line 550 | |
| /** | | /** | |
| * @return \e azi1 the azimuth (degrees) of the geodesic line at point
1. | | * @return \e azi1 the azimuth (degrees) of the geodesic line at point
1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real Azimuth() const throw() { return Init() ? _azi1 : 0; } | | Math::real Azimuth() const throw() { return Init() ? _azi1 : 0; } | |
| | | | |
| /** | | /** | |
| * @return \e azi0 the azimuth (degrees) of the geodesic line as it cro
sses | | * @return \e azi0 the azimuth (degrees) of the geodesic line as it cro
sses | |
| * the equator in a northward direction. | | * the equator in a northward direction. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialAzimuth() const throw() { | | Math::real EquatorialAzimuth() const throw() { | |
|
| return Init() ? atan2(_salp0, _calp0) / Math::degree() : 0; | | return Init() ? atan2(_salp0, _calp0) / Math::degree<real>() : 0; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a1 the arc length (degrees) between the northward equator
ial | | * @return \e a1 the arc length (degrees) between the northward equator
ial | |
| * crossing and point 1. | | * crossing and point 1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real EquatorialArc() const throw() { | | Math::real EquatorialArc() const throw() { | |
|
| return Init() ? atan2(_ssig1, _csig1) / Math::degree() : 0; | | return Init() ? atan2(_ssig1, _csig1) / Math::degree<real>() : 0; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * @return \e a the equatorial radius of the ellipsoid (meters). This
is | | * @return \e a the equatorial radius of the ellipsoid (meters). This
is | |
| * the value inherited from the Geodesic object used in the construct
or. | | * the value inherited from the Geodesic object used in the construct
or. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real MajorRadius() const throw() { return Init() ? _a : 0; } | | Math::real MajorRadius() const throw() { return Init() ? _a : 0; } | |
| | | | |
| /** | | /** | |
| * @return \e r the inverse flattening of the ellipsoid. This is the | | * @return \e r the inverse flattening of the ellipsoid. This is the | |
| | | | |
End of changes. 5 change blocks. |
| 7 lines changed or deleted | | 17 lines changed or added | |
|
| Gnomonic.hpp | | Gnomonic.hpp | |
| /** | | /** | |
| * \file Gnomonic.hpp | | * \file Gnomonic.hpp | |
| * \brief Header for GeographicLib::Gnomonic class | | * \brief Header for GeographicLib::Gnomonic class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2010) <charles@karney.com> and licensed un | | * Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licen | |
| der | | sed | |
| * the LGPL. For more information, see http://geographiclib.sourceforge.ne | | * under the LGPL. For more information, see | |
| t/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_GNOMONIC_HPP) | | #if !defined(GEOGRAPHICLIB_GNOMONIC_HPP) | |
|
| #define GEOGRAPHICLIB_GNOMONIC_HPP "$Id: Gnomonic.hpp 6911 2010-12-09 23:13
:55Z karney $" | | #define GEOGRAPHICLIB_GNOMONIC_HPP "$Id: Gnomonic.hpp 6968 2011-02-19 15:58
:56Z karney $" | |
| | | | |
| #include "GeographicLib/Geodesic.hpp" | | #include "GeographicLib/Geodesic.hpp" | |
| #include "GeographicLib/GeodesicLine.hpp" | | #include "GeographicLib/GeodesicLine.hpp" | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief %Gnomonic Projection. | | * \brief %Gnomonic Projection. | |
| * | | * | |
| * %Gnomonic projection centered at an arbitrary position \e C on the | | * %Gnomonic projection centered at an arbitrary position \e C on the | |
|
| * ellipsoid. The projection of \e P is defined as follows: compute the | | * ellipsoid. This projection is derived in Section 13 of | |
| | | * - C. F. F. Karney, | |
| | | * <a href="http://arxiv.org/abs/1102.1215">Geodesics | |
| | | * on an ellipsoid of revolution</a>, | |
| | | * Feb. 2011; | |
| | | * preprint | |
| | | * <a href="http://arxiv.org/abs/1102.1215">arxiv:1102.1215</a>. | |
| | | * . | |
| | | * The projection of \e P is defined as follows: compute the | |
| * geodesic line from \e C to \e P; compute the reduced length \e m12, | | * geodesic line from \e C to \e P; compute the reduced length \e m12, | |
| * geodesic scale \e M12, and \e rho = \e m12/\e M12; finally \e x = \e r
ho | | * geodesic scale \e M12, and \e rho = \e m12/\e M12; finally \e x = \e r
ho | |
| * sin \e azi1; \e y = \e rho cos \e azi1, where \e azi1 is the azimuth o
f | | * sin \e azi1; \e y = \e rho cos \e azi1, where \e azi1 is the azimuth o
f | |
|
| * the geodesic at \e C. The Forward and Reverse methods also return the | | * the geodesic at \e C. The Gnomonic::Forward and Gnomonic::Reverse met | |
| * azimuth \e azi of the geodesic at \e P and reciprocal scale \e rk in t | | hods | |
| he | | * also return the azimuth \e azi of the geodesic at \e P and reciprocal | |
| * azimuthal direction. The scale in the radial direction if 1/\e | | * scale \e rk in the azimuthal direction. The scale in the radial direc | |
| * rk<sup>2</sup>. | | tion | |
| | | * if 1/\e rk<sup>2</sup>. | |
| * | | * | |
| * For a sphere, \e rho is reduces to \e a tan(\e s12/\e a), where \e s12
is | | * For a sphere, \e rho is reduces to \e a tan(\e s12/\e a), where \e s12
is | |
| * the length of the geodesic from \e C to \e P, and the gnomonic project
ion | | * the length of the geodesic from \e C to \e P, and the gnomonic project
ion | |
| * has the property that all geodesics appear as straight lines. For an | | * has the property that all geodesics appear as straight lines. For an | |
| * ellipsoid, this property holds only for geodesics interesting the cent
ers. | | * ellipsoid, this property holds only for geodesics interesting the cent
ers. | |
| * However geodesic segments close to the center are approximately straig
ht. | | * However geodesic segments close to the center are approximately straig
ht. | |
| * | | * | |
| * Consider a geodesic segment of length \e l. Let \e T be the point on
the | | * Consider a geodesic segment of length \e l. Let \e T be the point on
the | |
| * geodesic (extended if necessary) closest to \e C the center of the | | * geodesic (extended if necessary) closest to \e C the center of the | |
| * projection and \e t be the distance \e CT. To lowest order, the maxim
um | | * projection and \e t be the distance \e CT. To lowest order, the maxim
um | |
| | | | |
| skipping to change at line 65 | | skipping to change at line 74 | |
| * The conversions all take place using a Geodesic object (by default | | * The conversions all take place using a Geodesic object (by default | |
| * Geodesic::WGS84). For more information on geodesics see \ref geodesic
. | | * Geodesic::WGS84). For more information on geodesics see \ref geodesic
. | |
| * | | * | |
| * <b>CAUTION:</b> The definition of this projection for a sphere is | | * <b>CAUTION:</b> The definition of this projection for a sphere is | |
| * standard. However, there is no standard for how it should be extended
to | | * standard. However, there is no standard for how it should be extended
to | |
| * an ellipsoid. The choices are: | | * an ellipsoid. The choices are: | |
| * - Declare that the projection is undefined for an ellipsoid. | | * - Declare that the projection is undefined for an ellipsoid. | |
| * - Project to a tangent plane from the center of the ellipsoid. This | | * - Project to a tangent plane from the center of the ellipsoid. This | |
| * causes great ellipses to appear as straight lines in the projection; | | * causes great ellipses to appear as straight lines in the projection; | |
| * i.e., it generalizes the spherical great circle to a great ellipse. | | * i.e., it generalizes the spherical great circle to a great ellipse. | |
|
| * This was proposed by Roy Williams, Geometry of Navigation (Horwood, | | * This was proposed by independently by Bowring and Williams in 1997. | |
| * Chichester, 1998). | | | |
| * - Project to the conformal sphere with the constant of integration cho
sen | | * - Project to the conformal sphere with the constant of integration cho
sen | |
| * so that the values of the latitude match for the center point and | | * so that the values of the latitude match for the center point and | |
| * perform a central projection onto the plane tangent to the conformal | | * perform a central projection onto the plane tangent to the conformal | |
| * sphere at the center point. This causes normal sections through the | | * sphere at the center point. This causes normal sections through the | |
| * center point to appear as straight lines in the projection; i.e., it | | * center point to appear as straight lines in the projection; i.e., it | |
| * generalizes the spherical great circle to a normal section. This wa
s | | * generalizes the spherical great circle to a normal section. This wa
s | |
| * proposed by I. G. Letoval'tsev, Generalization of the %Gnomonic | | * proposed by I. G. Letoval'tsev, Generalization of the %Gnomonic | |
| * Projection for a Spheroid and the Principal Geodetic Problems Involv
ed | | * Projection for a Spheroid and the Principal Geodetic Problems Involv
ed | |
| * in the Alignment of Surface Routes, Geodesy and Aerophotography (5), | | * in the Alignment of Surface Routes, Geodesy and Aerophotography (5), | |
| * 271-274 (1963). | | * 271-274 (1963). | |
| | | | |
End of changes. 5 change blocks. |
| 13 lines changed or deleted | | 21 lines changed or added | |
|
| LocalCartesian.hpp | | LocalCartesian.hpp | |
| /** | | /** | |
| * \file LocalCartesian.hpp | | * \file LocalCartesian.hpp | |
| * \brief Header for GeographicLib::LocalCartesian class | | * \brief Header for GeographicLib::LocalCartesian class | |
| * | | * | |
| * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_LOCALCARTESIAN_HPP) | | #if !defined(GEOGRAPHICLIB_LOCALCARTESIAN_HPP) | |
|
| #define GEOGRAPHICLIB_LOCALCARTESIAN_HPP "$Id: LocalCartesian.hpp 6867 2010
-09-11 13:04:26Z karney $" | | #define GEOGRAPHICLIB_LOCALCARTESIAN_HPP "$Id: LocalCartesian.hpp 6952 2011
-02-14 20:26:44Z karney $" | |
| | | | |
| #include "GeographicLib/Geocentric.hpp" | | #include "GeographicLib/Geocentric.hpp" | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief Local Cartesian coordinates | | * \brief Local Cartesian coordinates | |
| * | | * | |
| * Convert between geodetic coordinates latitude = \e lat, longitude = \e | | * Convert between geodetic coordinates latitude = \e lat, longitude = \e | |
| | | | |
| skipping to change at line 35 | | skipping to change at line 35 | |
| * = \e h0. The \e z axis is normal to the ellipsoid; the \e y axis point
s | | * = \e h0. The \e z axis is normal to the ellipsoid; the \e y axis point
s | |
| * due north. The plane \e z = - \e h0 is tangent to the ellipsoid. | | * due north. The plane \e z = - \e h0 is tangent to the ellipsoid. | |
| * | | * | |
| * The conversions all take place via geocentric coordinates using a | | * The conversions all take place via geocentric coordinates using a | |
| * Geocentric object (by default Geocentric::WGS84). | | * Geocentric object (by default Geocentric::WGS84). | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| class LocalCartesian { | | class LocalCartesian { | |
| private: | | private: | |
| typedef Math::real real; | | typedef Math::real real; | |
|
| | | static const size_t dim = 3, dim2 = dim * dim; | |
| const Geocentric _earth; | | const Geocentric _earth; | |
| real _lat0, _lon0, _h0; | | real _lat0, _lon0, _h0; | |
|
| real _x0, _y0, _z0, | | real _x0, _y0, _z0, _r[dim2]; | |
| _rxx, _rxy, _rxz, | | void IntForward(real lat, real lon, real h, real& x, real& y, real& z, | |
| _ryx, _ryy, _ryz, | | real M[dim2]) const throw(); | |
| _rzx, _rzy, _rzz; | | void IntReverse(real x, real y, real z, real& lat, real& lon, real& h, | |
| | | real M[dim2]) const throw(); | |
| | | void MatrixMultiply(real M[dim2]) const throw(); | |
| public: | | public: | |
| | | | |
| /** | | /** | |
| * Constructor setting the origin. | | * Constructor setting the origin. | |
| * | | * | |
| * @param[in] lat0 latitude at origin (degrees). | | * @param[in] lat0 latitude at origin (degrees). | |
| * @param[in] lon0 longitude at origin (degrees). | | * @param[in] lon0 longitude at origin (degrees). | |
| * @param[in] h0 height above ellipsoid at origin (meters); default 0. | | * @param[in] h0 height above ellipsoid at origin (meters); default 0. | |
| * @param[in] earth Geocentric object for the transformation; default | | * @param[in] earth Geocentric object for the transformation; default | |
| * Geocentric::WGS84. | | * Geocentric::WGS84. | |
| | | | |
| skipping to change at line 94 | | skipping to change at line 97 | |
| * @param[in] lon longitude of point (degrees). | | * @param[in] lon longitude of point (degrees). | |
| * @param[in] h height of point above the ellipsoid (meters). | | * @param[in] h height of point above the ellipsoid (meters). | |
| * @param[out] x local cartesian coordinate (meters). | | * @param[out] x local cartesian coordinate (meters). | |
| * @param[out] y local cartesian coordinate (meters). | | * @param[out] y local cartesian coordinate (meters). | |
| * @param[out] z local cartesian coordinate (meters). | | * @param[out] z local cartesian coordinate (meters). | |
| * | | * | |
| * \e lat should be in the range [-90, 90]; \e lon and \e lon0 should b
e in | | * \e lat should be in the range [-90, 90]; \e lon and \e lon0 should b
e in | |
| * the range [-180, 360]. | | * the range [-180, 360]. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Forward(real lat, real lon, real h, real& x, real& y, real& z) | | void Forward(real lat, real lon, real h, real& x, real& y, real& z) | |
|
| const throw(); | | const throw() { | |
| | | IntForward(lat, lon, h, x, y, z, NULL); | |
| | | } | |
| | | | |
| /** | | /** | |
|
| * Convert from local cartesian to geodetic to coordinates. | | * Convert from geodetic to local cartesian coordinates and return rota | |
| | | tion | |
| | | * matrix. | |
| | | * | |
| | | * @param[in] lat latitude of point (degrees). | |
| | | * @param[in] lon longitude of point (degrees). | |
| | | * @param[in] h height of point above the ellipsoid (meters). | |
| | | * @param[out] x local cartesian coordinate (meters). | |
| | | * @param[out] y local cartesian coordinate (meters). | |
| | | * @param[out] z local cartesian coordinate (meters). | |
| | | * @param[out] M if the length of the vector is 9, fill with the rotati | |
| | | on | |
| | | * matrix in row-major order. | |
| | | * | |
| | | * Pre-multiplying a unit vector in local cartesian coordinates at (lat | |
| | | , | |
| | | * lon, h) by \e M transforms the vector to local cartesian coordinates | |
| | | at | |
| | | * (lat0, lon0, h0). | |
| | | ********************************************************************** | |
| | | / | |
| | | void Forward(real lat, real lon, real h, real& x, real& y, real& z, | |
| | | std::vector<real>& M) | |
| | | const throw() { | |
| | | real t[dim2]; | |
| | | IntForward(lat, lon, h, x, y, z, t); | |
| | | if (M.end() == M.begin() + dim2) | |
| | | copy(t, t + dim2, M.begin()); | |
| | | } | |
| | | | |
| | | /** | |
| | | * Convert from local cartesian to geodetic coordinates. | |
| * | | * | |
| * @param[in] x local cartesian coordinate (meters). | | * @param[in] x local cartesian coordinate (meters). | |
| * @param[in] y local cartesian coordinate (meters). | | * @param[in] y local cartesian coordinate (meters). | |
| * @param[in] z local cartesian coordinate (meters). | | * @param[in] z local cartesian coordinate (meters). | |
| * @param[out] lat latitude of point (degrees). | | * @param[out] lat latitude of point (degrees). | |
| * @param[out] lon longitude of point (degrees). | | * @param[out] lon longitude of point (degrees). | |
| * @param[out] h height of point above the ellipsoid (meters). | | * @param[out] h height of point above the ellipsoid (meters). | |
| * | | * | |
| * The value of \e lon returned is in the range [-180, 180). | | * The value of \e lon returned is in the range [-180, 180). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| void Reverse(real x, real y, real z, real& lat, real& lon, real& h) | | void Reverse(real x, real y, real z, real& lat, real& lon, real& h) | |
|
| const throw(); | | const throw() { | |
| | | IntReverse(x, y, z, lat, lon, h, NULL); | |
| | | } | |
| | | | |
| | | /** | |
| | | * Convert from local cartesian to geodetic coordinates and return rota | |
| | | tion | |
| | | * matrix. | |
| | | * | |
| | | * @param[in] x local cartesian coordinate (meters). | |
| | | * @param[in] y local cartesian coordinate (meters). | |
| | | * @param[in] z local cartesian coordinate (meters). | |
| | | * @param[out] lat latitude of point (degrees). | |
| | | * @param[out] lon longitude of point (degrees). | |
| | | * @param[out] h height of point above the ellipsoid (meters). | |
| | | * @param[out] M if the length of the vector is 9, fill with the rotati | |
| | | on | |
| | | * matrix in row-major order. | |
| | | * | |
| | | * Pre-multiplying a unit vector in local cartesian coordinates at (lat | |
| | | 0, | |
| | | * lon0, h0) by the transpose of \e M transforms the vector to local | |
| | | * cartesian coordinates at (lat, lon, h). | |
| | | ********************************************************************** | |
| | | / | |
| | | void Reverse(real x, real y, real z, real& lat, real& lon, real& h, | |
| | | std::vector<real>& M) | |
| | | const throw() { | |
| | | real t[dim2]; | |
| | | IntReverse(x, y, z, lat, lon, h, t); | |
| | | if (M.end() == M.begin() + dim2) | |
| | | copy(t, t + dim2, M.begin()); | |
| | | } | |
| | | | |
| /** \name Inspector functions | | /** \name Inspector functions | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| ///@{ | | ///@{ | |
| /** | | /** | |
| * @return latitude of the origin (degrees). | | * @return latitude of the origin (degrees). | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| Math::real LatitudeOrigin() const throw() { return _lat0; } | | Math::real LatitudeOrigin() const throw() { return _lat0; } | |
| | | | |
| /** | | /** | |
| | | | |
End of changes. 6 change blocks. |
| 8 lines changed or deleted | | 76 lines changed or added | |
|
| TransverseMercatorExact.hpp | | TransverseMercatorExact.hpp | |
| /** | | /** | |
| * \file TransverseMercatorExact.hpp | | * \file TransverseMercatorExact.hpp | |
| * \brief Header for GeographicLib::TransverseMercatorExact class | | * \brief Header for GeographicLib::TransverseMercatorExact class | |
| * | | * | |
|
| * Copyright (c) Charles Karney (2008, 2009, 2010) <charles@karney.com> | | * Copyright (c) Charles Karney (2008, 2009, 2010, 2011) <charles@karney.co
m> | |
| * and licensed under the LGPL. For more information, see | | * and licensed under the LGPL. For more information, see | |
| * http://geographiclib.sourceforge.net/ | | * http://geographiclib.sourceforge.net/ | |
| **********************************************************************/ | | **********************************************************************/ | |
| | | | |
| #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP) | | #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP) | |
|
| #define GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP "$Id: TransverseMercatorE
xact.hpp 6905 2010-12-01 21:28:56Z karney $" | | #define GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP "$Id: TransverseMercatorE
xact.hpp 6950 2011-02-11 04:09:24Z karney $" | |
| | | | |
| #include "GeographicLib/Constants.hpp" | | #include "GeographicLib/Constants.hpp" | |
| #include "GeographicLib/EllipticFunction.hpp" | | #include "GeographicLib/EllipticFunction.hpp" | |
| | | | |
| namespace GeographicLib { | | namespace GeographicLib { | |
| | | | |
| /** | | /** | |
| * \brief An exact implementation of the Transverse Mercator Projection | | * \brief An exact implementation of the Transverse Mercator Projection | |
| * | | * | |
| * Implementation of the Transverse Mercator Projection given in | | * Implementation of the Transverse Mercator Projection given in | |
| * - L. P. Lee, | | * - L. P. Lee, | |
| * <a href="http://dx.doi.org/10.3138/X687-1574-4325-WM62"> Conformal | | * <a href="http://dx.doi.org/10.3138/X687-1574-4325-WM62"> Conformal | |
| * Projections Based On Jacobian Elliptic Functions</a>, Part V of | | * Projections Based On Jacobian Elliptic Functions</a>, Part V of | |
| * Conformal Projections Based on Elliptic Functions, | | * Conformal Projections Based on Elliptic Functions, | |
| * (B. V. Gutsell, Toronto, 1976), 128pp., | | * (B. V. Gutsell, Toronto, 1976), 128pp., | |
| * ISBN: 0919870163 | | * ISBN: 0919870163 | |
| * (also appeared as: | | * (also appeared as: | |
| * Monograph 16, Suppl. No. 1 to Canadian Cartographer, Vol 13). | | * Monograph 16, Suppl. No. 1 to Canadian Cartographer, Vol 13). | |
|
| | | * - C. F. F. Karney, | |
| | | * <a href="http://dx.doi.org/10.1007/s00190-011-0445-3"> | |
| | | * Transverse Mercator with an accuracy of a few nanometers,</a> | |
| | | * J. Geodesy (2011); | |
| | | * preprint | |
| | | * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>. | |
| * | | * | |
|
| * This method gives the correct results for forward and reverse | | * Lee's gives the correct results for forward and reverse | |
| * transformations subject to the branch cut rules (see the description o
f | | * transformations subject to the branch cut rules (see the description o
f | |
| * the \e extendp argument to the constructor). The maximum error is abo
ut 8 | | * the \e extendp argument to the constructor). The maximum error is abo
ut 8 | |
| * nm (ground distance) for the forward and reverse transformations. The | | * nm (ground distance) for the forward and reverse transformations. The | |
| * error in the convergence is 2e-15", the relative error in the sca
le | | * error in the convergence is 2e-15", the relative error in the sca
le | |
|
| * is 7e-12%%. (See \ref tmerrors for the weasel words.) The method is | | * is 7e-12%%. See Sec. 3 of | |
| * "exact" in the sense that the errors are close to the round-off limit | | * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for detai | |
| and | | ls. | |
| * that no changes are needed in the algorithms for them to be used with | | * The method is "exact" in the sense that the errors are close to the | |
| * reals of a higher precision. Thus the errors using long double (with | | * round-off limit and that no changes are needed in the algorithms for t | |
| a | | hem | |
| * 64-bit fraction) are about 2000 times smaller than using double (with | | * to be used with reals of a higher precision. Thus the errors using lo | |
| a | | ng | |
| * 53-bit fraction). | | * double (with a 64-bit fraction) are about 2000 times smaller than usin | |
| | | g | |
| | | * double (with a 53-bit fraction). | |
| * | | * | |
| * This algorithm is about 4.5 times slower than the 6th-order Krüge
r | | * This algorithm is about 4.5 times slower than the 6th-order Krüge
r | |
| * method, TransverseMercator, taking about 11 us for a combined forward
and | | * method, TransverseMercator, taking about 11 us for a combined forward
and | |
| * reverse projection on a 2.66 GHz Intel machine (g++, version 4.3.0, -O
3). | | * reverse projection on a 2.66 GHz Intel machine (g++, version 4.3.0, -O
3). | |
| * | | * | |
| * The ellipsoid parameters and the central scale are set in the construc
tor. | | * The ellipsoid parameters and the central scale are set in the construc
tor. | |
| * The central meridian (which is a trivial shift of the longitude) is | | * The central meridian (which is a trivial shift of the longitude) is | |
| * specified as the \e lon0 argument of the TransverseMercatorExact::Forw
ard | | * specified as the \e lon0 argument of the TransverseMercatorExact::Forw
ard | |
| * and TransverseMercatorExact::Reverse functions. The latitude of origi
n is | | * and TransverseMercatorExact::Reverse functions. The latitude of origi
n is | |
| * taken to be the equator. See the documentation on TransverseMercator
for | | * taken to be the equator. See the documentation on TransverseMercator
for | |
| | | | |
| skipping to change at line 142 | | skipping to change at line 149 | |
| * domains of \e lat, \e lon, \e x, and \e y are restricted to | | * domains of \e lat, \e lon, \e x, and \e y are restricted to | |
| * - the union of | | * - the union of | |
| * - \e lat in [0, 90] and \e lon - \e lon0 in [0, 90] | | * - \e lat in [0, 90] and \e lon - \e lon0 in [0, 90] | |
| * - \e lat in (-90, 0] and \e lon - \e lon0 in [90 (1 - \e e), 90] | | * - \e lat in (-90, 0] and \e lon - \e lon0 in [90 (1 - \e e), 90] | |
| * - the union of | | * - the union of | |
| * - \e x/(\e k0 \e a) in [0, inf) and | | * - \e x/(\e k0 \e a) in [0, inf) and | |
| * \e y/(\e k0 \e a) in [0, E(\e e^2)] | | * \e y/(\e k0 \e a) in [0, E(\e e^2)] | |
| * - \e x/(\e k0 \e a) in [K(1 - \e e^2) - E(1 - \e e^2), inf) and | | * - \e x/(\e k0 \e a) in [K(1 - \e e^2) - E(1 - \e e^2), inf) and | |
| * \e y/(\e k0 \e a) in (-inf, 0] | | * \e y/(\e k0 \e a) in (-inf, 0] | |
| * . | | * . | |
|
| * See \ref extend for a full discussion of the treatment of the branch | | * See Sec. 5 of | |
| * cut. | | * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for a f | |
| | | ull | |
| | | * discussion of the treatment of the branch cut. | |
| * | | * | |
| * The method will work for all ellipsoids used in terrestial geodesy.
The | | * The method will work for all ellipsoids used in terrestial geodesy.
The | |
| * method cannot be applied directly to the case of a sphere (\e r = in
f) | | * method cannot be applied directly to the case of a sphere (\e r = in
f) | |
| * because some the constants characterizing this method diverge in tha
t | | * because some the constants characterizing this method diverge in tha
t | |
| * limit, and in practise, \e r should be smaller than about | | * limit, and in practise, \e r should be smaller than about | |
| * 1/numeric_limits< real >::%epsilon(). However, TransverseMercator | | * 1/numeric_limits< real >::%epsilon(). However, TransverseMercator | |
| * treats the sphere exactly. An exception is thrown if either axis of
the | | * treats the sphere exactly. An exception is thrown if either axis of
the | |
| * ellipsoid or \e k0 is not positive or if \e r < 1. | | * ellipsoid or \e k0 is not positive or if \e r < 1. | |
| **********************************************************************
/ | | **********************************************************************
/ | |
| TransverseMercatorExact(real a, real r, real k0, bool extendp = false); | | TransverseMercatorExact(real a, real r, real k0, bool extendp = false); | |
| | | | |
End of changes. 6 change blocks. |
| 14 lines changed or deleted | | 24 lines changed or added | |
|