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&quot;. \e ind is interpreted as in DMS::Encode with the additi onal * to 1&quot;. \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&ndash;454 (2002). * J. Geodesy 76, 451&ndash;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


 Geoid.hpp   Geoid.hpp 
/** /**
* \file Geoid.hpp * \file Geoid.hpp
* \brief Header for GeographicLib::Geoid class * \brief Header for GeographicLib::Geoid 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_GEOID_HPP) #if !defined(GEOGRAPHICLIB_GEOID_HPP)
#define GEOGRAPHICLIB_GEOID_HPP "$Id: Geoid.hpp 6910 2010-12-08 22:01:30Z k arney $" #define GEOGRAPHICLIB_GEOID_HPP "$Id: Geoid.hpp 6937 2011-02-01 20:17:13Z k arney $"
#include "GeographicLib/Constants.hpp" #include "GeographicLib/Constants.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
#include <fstream> #include <fstream>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Looking up the height of the geoid * \brief Looking up the height of the geoid
skipping to change at line 405 skipping to change at line 405
Math::real CacheSouth() const throw() { Math::real CacheSouth() const throw() {
return _cache ? 90 - ( _yoffset + _ysize - 1 - _cubic) / _rlatres : 0 ; return _cache ? 90 - ( _yoffset + _ysize - 1 - _cubic) / _rlatres : 0 ;
} }
/** /**
* @return \e a the equatorial radius of the WGS84 ellipsoid (meters). * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
* *
* (The WGS84 value is returned because the supported geoid models are all * (The WGS84 value is returned because the supported geoid models are all
* based on this ellipsoid.) * based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() { return Constants::WGS84_a(); } Math::real MajorRadius() const throw()
{ return Constants::WGS84_a<real>(); }
/** /**
* @return \e r the inverse flattening of the WGS84 ellipsoid. * @return \e r the inverse flattening of the WGS84 ellipsoid.
* *
* (The WGS84 value is returned because the supported geoid models are all * (The WGS84 value is returned because the supported geoid models are all
* based on this ellipsoid.) * based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const throw()
{ return Constants::WGS84_r(); } { return Constants::WGS84_r<real>(); }
///@} ///@}
/** /**
* Return the compile-time default path for the geoid data files. * @return the default path for geoid data files.
*
* This is the value of the environment variable GEOID_PATH, if set,
* otherwise, it is a compile-time default.
**********************************************************************
/
static std::string DefaultGeoidPath();
/**
* @return the default name for the geoid.
*
* This is the value of the environment variable GEOID_NAME, if set,
* otherwise, it is "egm96-5". The Geoid class does not use this funct
ion;
* it is just provided as a convenience for a calling program when
* constructing a Geoid object.
**********************************************************************
/
static std::string DefaultGeoidName();
/**
* <b>DEPRECATED</b> Return the compile-time default path for the geoid
* data files.
********************************************************************** / ********************************************************************** /
static std::string DefaultPath(); static std::string DefaultPath();
/** /**
* Return the value of the environment variable GEOID_PATH. * <b>DEPRECATED</b> Return the value of the environment variable
* GEOID_PATH.
********************************************************************** / ********************************************************************** /
static std::string GeoidPath(); static std::string GeoidPath();
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif #endif
 End of changes. 6 change blocks. 
6 lines changed or deleted 30 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


 LambertConformalConic.hpp   LambertConformalConic.hpp 
/** /**
* \file LambertConformalConic.hpp * \file LambertConformalConic.hpp
* \brief Header for GeographicLib::LambertConformalConic class * \brief Header for GeographicLib::LambertConformalConic 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_LAMBERTCONFORMALCONIC_HPP) #if !defined(GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP)
#define GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP "$Id: LambertConformalConic .hpp 6916 2010-12-20 23:03:47Z karney $" #define GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP "$Id: LambertConformalConic .hpp 6937 2011-02-01 20:17:13Z karney $"
#include "GeographicLib/Constants.hpp" #include "GeographicLib/Constants.hpp"
#include <algorithm> #include <algorithm>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Lambert Conformal Conic Projection * \brief Lambert Conformal Conic Projection
* *
* Implementation taken from the report, * Implementation taken from the report,
skipping to change at line 50 skipping to change at line 51
* scale on the latitude of origin is given by * scale on the latitude of origin is given by
* LambertConformalConic::CentralScale. The case with two distinct stand ard * LambertConformalConic::CentralScale. The case with two distinct stand ard
* parallels where one is a pole is singular and is disallowed. The cent ral * parallels where one is a pole is singular and is disallowed. The cent ral
* meridian (which is a trivial shift of the longitude) is specified as t he * meridian (which is a trivial shift of the longitude) is specified as t he
* \e lon0 argument of the LambertConformalConic::Forward and * \e lon0 argument of the LambertConformalConic::Forward and
* LambertConformalConic::Reverse functions. There is no provision in th is * LambertConformalConic::Reverse functions. There is no provision in th is
* class for specifying a false easting or false northing or a different * class for specifying a false easting or false northing or a different
* latitude of origin. However these are can be simply included by the * latitude of origin. However these are can be simply included by the
* calling function. For example the Pennsylvania South state coordinate * calling function. For example the Pennsylvania South state coordinate
* system (<a href="http://www.spatialreference.org/ref/epsg/3364/"> * system (<a href="http://www.spatialreference.org/ref/epsg/3364/">
* EPSG:3364</a>) is obtained by: \code const double a = * EPSG:3364</a>) is obtained by:
* GeographicLib::Constants::WGS84_a(), r = 298.257222101, // GRS80 lat1 \code
= 39 const double
* + 56/60.0, lat1 = 40 + 58/60.0, // standard parallels k1 = 1, // scale a = GeographicLib::Constants::WGS84_a<double>(),
* lat0 = 39 + 20/60.0, lon0 = 75 + 45/60.0, // origin fe = 600000, fn = r = 298.257222101, // GRS80
* 0; // false easting and northing lat1 = 39 + 56/60.0, lat1 = 40 + 58/60.0, // standard parallels
k1 = 1, // scale
lat0 = 39 + 20/60.0, lon0 = 75 + 45/60.0, // origin
fe = 600000, fn = 0; // false easting and northin
g
// Set up basic projection // Set up basic projection
const GeographicLib::LambertConformalConic PASouth(a, r, lat1, lat2, k1) ; const GeographicLib::LambertConformalConic PASouth(a, r, lat1, lat2, k1) ;
double x0, y0; double x0, y0;
{ {
// Transform origin point // Transform origin point
PASouth.Forward(lon0, lat0, lon0, x0, y0); PASouth.Forward(lon0, lat0, lon0, x0, y0);
x0 -= fe; y0 -= fn; // Combine result with false origin x0 -= fe; y0 -= fn; // Combine result with false origin
} }
double lat, lon, x, y; double lat, lon, x, y;
// Sample conversion from geodetic to PASouth grid // Sample conversion from geodetic to PASouth grid
 End of changes. 3 change blocks. 
11 lines changed or deleted 15 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


 TransverseMercator.hpp   TransverseMercator.hpp 
/** /**
* \file TransverseMercator.hpp * \file TransverseMercator.hpp
* \brief Header for GeographicLib::TransverseMercator class * \brief Header for GeographicLib::TransverseMercator 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_TRANSVERSEMERCATOR_HPP) #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP)
#define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP "$Id: TransverseMercator.hpp 6 905 2010-12-01 21:28:56Z karney $" #define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP "$Id: TransverseMercator.hpp 6 950 2011-02-11 04:09:24Z karney $"
#include "GeographicLib/Constants.hpp" #include "GeographicLib/Constants.hpp"
#if !defined(TM_TX_MAXPOW) #if !defined(TM_TX_MAXPOW)
/** /**
* The order of the series approximation used in TransverseMercator. * The order of the series approximation used in TransverseMercator.
* TM_TX_MAXPOW can be set to any integer in [4, 8]. * TM_TX_MAXPOW can be set to any integer in [4, 8].
**********************************************************************/ **********************************************************************/
#define TM_TX_MAXPOW \ #define TM_TX_MAXPOW \
(GEOGRAPHICLIB_PREC == 1 ? 6 : GEOGRAPHICLIB_PREC == 0 ? 4 : 8) (GEOGRAPHICLIB_PREC == 1 ? 6 : GEOGRAPHICLIB_PREC == 0 ? 4 : 8)
skipping to change at line 36 skipping to change at line 36
/** /**
* \brief Transverse Mercator Projection * \brief Transverse Mercator Projection
* *
* This uses Kr&uuml;ger's method which evaluates the projection and its * This uses Kr&uuml;ger's method which evaluates the projection and its
* inverse in terms of a series. See * inverse in terms of a series. See
* - L. Kr&uuml;ger, * - L. Kr&uuml;ger,
* <a href="http://dx.doi.org/10.2312/GFZ.b103-krueger28"> Konforme * <a href="http://dx.doi.org/10.2312/GFZ.b103-krueger28"> Konforme
* Abbildung des Erdellipsoids in der Ebene</a> (Conformal mapping of the * Abbildung des Erdellipsoids in der Ebene</a> (Conformal mapping of the
* ellipsoidal earth to the plane), Royal Prussian Geodetic Institute, New * ellipsoidal earth to the plane), Royal Prussian Geodetic Institute, New
* Series 52, 172 pp. (1912). * Series 52, 172 pp. (1912).
* - 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>.
* *
* Kr&uuml;ger's method has been extended from 4th to 6th order. The max imum * Kr&uuml;ger's method has been extended from 4th to 6th order. The max imum
* errors is 5 nm (ground distance) for all positions within 35 degrees o f * errors is 5 nm (ground distance) for all positions within 35 degrees o f
* the central meridian. The error in the convergence is 2e-15&quot; and the * the central meridian. The error in the convergence is 2e-15&quot; and the
* relative error in the scale is 6e-12%%. (See \ref tmerrors for the we * relative error in the scale is 6e-12%%. See Sec. 4 of
asel * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for detai
* words.) The speed penalty in going to 6th order is only about 1%. ls.
* The speed penalty in going to 6th order is only about 1%.
* TransverseMercatorExact is an alternative implementation of the projec tion * TransverseMercatorExact is an alternative implementation of the projec tion
* using exact formulas which yield accurate (to 8 nm) results over the * using exact formulas which yield accurate (to 8 nm) results over the
* entire ellipsoid. * entire ellipsoid.
* *
* 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 TransverseMercator::Forward a nd * specified as the \e lon0 argument of the TransverseMercator::Forward a nd
* TransverseMercator::Reverse functions. The latitude of origin is take n to * TransverseMercator::Reverse functions. The latitude of origin is take n to
* be the equator. There is no provision in this class for specifying a * be the equator. There is no provision in this class for specifying a
* false easting or false northing or a different latitude of origin. * false easting or false northing or a different latitude of origin.
 End of changes. 4 change blocks. 
5 lines changed or deleted 12 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&quot;, the relative error in the sca le * error in the convergence is 2e-15&quot;, 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&uuml;ge r * This algorithm is about 4.5 times slower than the 6th-order Kr&uuml;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


 UTMUPS.hpp   UTMUPS.hpp 
/** /**
* \file UTMUPS.hpp * \file UTMUPS.hpp
* \brief Header for GeographicLib::UTMUPS class * \brief Header for GeographicLib::UTMUPS 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_UTMUPS_HPP) #if !defined(GEOGRAPHICLIB_UTMUPS_HPP)
#define GEOGRAPHICLIB_UTMUPS_HPP "$Id: UTMUPS.hpp 6905 2010-12-01 21:28:56Z karney $" #define GEOGRAPHICLIB_UTMUPS_HPP "$Id: UTMUPS.hpp 6937 2011-02-01 20:17:13Z karney $"
#include "GeographicLib/Constants.hpp" #include "GeographicLib/Constants.hpp"
#include <sstream> #include <sstream>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Convert between Geographic coordinates and UTM/UPS * \brief Convert between Geographic coordinates and UTM/UPS
* *
* UTM and UPS are defined * UTM and UPS are defined
skipping to change at line 298 skipping to change at line 298
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return \e a the equatorial radius of the WGS84 ellipsoid (meters). * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
* *
* (The WGS84 value is returned because the UTM and UPS projections are * (The WGS84 value is returned because the UTM and UPS projections are
* based on this ellipsoid.) * based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
static Math::real MajorRadius() throw() { return Constants::WGS84_a(); static Math::real MajorRadius() throw()
} { return Constants::WGS84_a<real>(); }
/** /**
* @return \e r the inverse flattening of the WGS84 ellipsoid. * @return \e r the inverse flattening of the WGS84 ellipsoid.
* *
* (The WGS84 value is returned because the UTM and UPS projections are * (The WGS84 value is returned because the UTM and UPS projections are
* based on this ellipsoid.) * based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
static Math::real InverseFlattening() throw() static Math::real InverseFlattening() throw()
{ return Constants::WGS84_r(); } { return Constants::WGS84_r<real>(); }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif #endif
 End of changes. 4 change blocks. 
5 lines changed or deleted 5 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/