Accumulator.hpp   Accumulator.hpp 
skipping to change at line 46 skipping to change at line 46
* Example of use: * Example of use:
* \include example-Accumulator.cpp * \include example-Accumulator.cpp
**********************************************************************/ **********************************************************************/
template<typename T = Math::real> template<typename T = Math::real>
class GEOGRAPHICLIB_EXPORT Accumulator { class GEOGRAPHICLIB_EXPORT Accumulator {
private: private:
// _s + _t accumulators for the sum. // _s + _t accumulators for the sum.
T _s, _t; T _s, _t;
// Same as Math::sum, but requires abs(u) >= abs(v). This isn't curren tly // Same as Math::sum, but requires abs(u) >= abs(v). This isn't curren tly
// used. // used.
static inline T fastsum(T u, T v, T& t) throw() { static inline T fastsum(T u, T v, T& t) {
volatile T s = u + v; volatile T s = u + v;
volatile T vp = s - u; volatile T vp = s - u;
t = v - vp; t = v - vp;
return s; return s;
} }
void Add(T y) throw() { void Add(T y) {
// Here's Shewchuk's solution... // Here's Shewchuk's solution...
T u; // hold exact sum as [s, t, u] T u; // hold exact sum as [s, t, u]
y = Math::sum(y, _t, u); // Accumulate starting at least significan t end y = Math::sum(y, _t, u); // Accumulate starting at least significan t end
_s = Math::sum(y, _s, _t); _s = Math::sum(y, _s, _t);
// Start is _s, _t decreasing and non-adjacent. Sum is now (s + t + u) // Start is _s, _t decreasing and non-adjacent. Sum is now (s + t + u)
// exactly with s, t, u non-adjacent and in decreasing order (except for // exactly with s, t, u non-adjacent and in decreasing order (except for
// possible zeros). The following code tries to normalize the result . // possible zeros). The following code tries to normalize the result .
// Ideally, we want _s = round(s+t+u) and _u = round(s+t+u - _s). Th e // Ideally, we want _s = round(s+t+u) and _u = round(s+t+u - _s). Th e
// following does an approximate job (and maintains the decreasing // following does an approximate job (and maintains the decreasing
// non-adjacent property). Here are two "failures" using 3-bit float s: // non-adjacent property). Here are two "failures" using 3-bit float s:
skipping to change at line 89 skipping to change at line 89
// with 3-bit floats: // with 3-bit floats:
// //
// [128, 16] + 1 -> [160, -16] -- 160 = round(145). // [128, 16] + 1 -> [160, -16] -- 160 = round(145).
// But [160, 0] - 16 -> [128, 16] -- 128 = round(144). // But [160, 0] - 16 -> [128, 16] -- 128 = round(144).
// //
if (_s == 0) // This implies t == 0, if (_s == 0) // This implies t == 0,
_s = u; // so result is u _s = u; // so result is u
else else
_t += u; // otherwise just accumulate u to t. _t += u; // otherwise just accumulate u to t.
} }
T Sum(T y) const throw() { T Sum(T y) const {
Accumulator a(*this); Accumulator a(*this);
a.Add(y); a.Add(y);
return a._s; return a._s;
} }
public: public:
/** /**
* Construct from a \e T. This is not declared explicit, so that you c an * Construct from a \e T. This is not declared explicit, so that you c an
* write <code>Accumulator<double> a = 5;</code>. * write <code>Accumulator<double> a = 5;</code>.
* *
* @param[in] y set \e sum = \e y. * @param[in] y set \e sum = \e y.
********************************************************************** / ********************************************************************** /
Accumulator(T y = T(0)) throw() : _s(y), _t(0) { Accumulator(T y = T(0)) : _s(y), _t(0) {
STATIC_ASSERT(!std::numeric_limits<T>::is_integer, STATIC_ASSERT(!std::numeric_limits<T>::is_integer,
"Accumulator type is not floating point"); "Accumulator type is not floating point");
} }
/** /**
* Set the accumulator to a number. * Set the accumulator to a number.
* *
* @param[in] y set \e sum = \e y. * @param[in] y set \e sum = \e y.
********************************************************************** / ********************************************************************** /
Accumulator& operator=(T y) throw() { _s = y; _t = 0; return *this; } Accumulator& operator=(T y) { _s = y; _t = 0; return *this; }
/** /**
* Return the value held in the accumulator. * Return the value held in the accumulator.
* *
* @return \e sum. * @return \e sum.
********************************************************************** / ********************************************************************** /
T operator()() const throw() { return _s; } T operator()() const { return _s; }
/** /**
* Return the result of adding a number to \e sum (but don't change \e sum). * Return the result of adding a number to \e sum (but don't change \e sum).
* *
* @param[in] y the number to be added to the sum. * @param[in] y the number to be added to the sum.
* @return \e sum + \e y. * @return \e sum + \e y.
********************************************************************** / ********************************************************************** /
T operator()(T y) const throw() { return Sum(y); } T operator()(T y) const { return Sum(y); }
/** /**
* Add a number to the accumulator. * Add a number to the accumulator.
* *
* @param[in] y set \e sum += \e y. * @param[in] y set \e sum += \e y.
********************************************************************** / ********************************************************************** /
Accumulator& operator+=(T y) throw() { Add(y); return *this; } Accumulator& operator+=(T y) { Add(y); return *this; }
/** /**
* Subtract a number from the accumulator. * Subtract a number from the accumulator.
* *
* @param[in] y set \e sum -= \e y. * @param[in] y set \e sum -= \e y.
********************************************************************** / ********************************************************************** /
Accumulator& operator-=(T y) throw() { Add(-y); return *this; } Accumulator& operator-=(T y) { Add(-y); return *this; }
/** /**
* Multiply accumulator by an integer. To avoid loss of accuracy, use only * Multiply accumulator by an integer. To avoid loss of accuracy, use only
* integers such that \e n &times; \e T is exactly representable as a \ e T * integers such that \e n &times; \e T is exactly representable as a \ e T
* (i.e., &plusmn; powers of two). Use \e n = &minus;1 to negate \e su m. * (i.e., &plusmn; powers of two). Use \e n = &minus;1 to negate \e su m.
* *
* @param[in] n set \e sum *= \e n. * @param[in] n set \e sum *= \e n.
********************************************************************** / ********************************************************************** /
Accumulator& operator*=(int n) throw() { _s *= n; _t *= n; return *this ; } Accumulator& operator*=(int n) { _s *= n; _t *= n; return *this; }
/** /**
* Test equality of an Accumulator with a number. * Test equality of an Accumulator with a number.
********************************************************************** / ********************************************************************** /
bool operator==(T y) const throw() { return _s == y; } bool operator==(T y) const { return _s == y; }
/** /**
* Test inequality of an Accumulator with a number. * Test inequality of an Accumulator with a number.
********************************************************************** / ********************************************************************** /
bool operator!=(T y) const throw() { return _s != y; } bool operator!=(T y) const { return _s != y; }
/** /**
* Less operator on an Accumulator and a number. * Less operator on an Accumulator and a number.
********************************************************************** / ********************************************************************** /
bool operator<(T y) const throw() { return _s < y; } bool operator<(T y) const { return _s < y; }
/** /**
* Less or equal operator on an Accumulator and a number. * Less or equal operator on an Accumulator and a number.
********************************************************************** / ********************************************************************** /
bool operator<=(T y) const throw() { return _s <= y; } bool operator<=(T y) const { return _s <= y; }
/** /**
* Greater operator on an Accumulator and a number. * Greater operator on an Accumulator and a number.
********************************************************************** / ********************************************************************** /
bool operator>(T y) const throw() { return _s > y; } bool operator>(T y) const { return _s > y; }
/** /**
* Greater or equal operator on an Accumulator and a number. * Greater or equal operator on an Accumulator and a number.
********************************************************************** / ********************************************************************** /
bool operator>=(T y) const throw() { return _s >= y; } bool operator>=(T y) const { return _s >= y; }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_ACCUMULATOR_HPP #endif // GEOGRAPHICLIB_ACCUMULATOR_HPP
 End of changes. 16 change blocks. 
16 lines changed or deleted 16 lines changed or added


 AlbersEqualArea.hpp   AlbersEqualArea.hpp 
skipping to change at line 74 skipping to change at line 74
real _sign, _lat0, _k0; real _sign, _lat0, _k0;
real _n0, _m02, _nrho0, _k2, _txi0, _scxi0, _sxi0; real _n0, _m02, _nrho0, _k2, _txi0, _scxi0, _sxi0;
static const real eps_; static const real eps_;
static const real epsx_; static const real epsx_;
static const real epsx2_; static const real epsx2_;
static const real tol_; static const real tol_;
static const real tol0_; static const real tol0_;
static const real ahypover_; static const real ahypover_;
static const int numit_ = 5; // Newton iterations in Reverse static const int numit_ = 5; // Newton iterations in Reverse
static const int numit0_ = 20; // Newton iterations in Init static const int numit0_ = 20; // Newton iterations in Init
static inline real hyp(real x) throw() { return Math::hypot(real(1), x) ; } static inline real hyp(real x) { return Math::hypot(real(1), x); }
// atanh( e * x)/ e if f > 0 // atanh( e * x)/ e if f > 0
// atan (sqrt(-e2) * x)/sqrt(-e2) if f < 0 // atan (sqrt(-e2) * x)/sqrt(-e2) if f < 0
// x if f = 0 // x if f = 0
inline real atanhee(real x) const throw() { inline real atanhee(real x) const {
return _f > 0 ? Math::atanh(_e * x)/_e : return _f > 0 ? Math::atanh(_e * x)/_e :
// We only invoke atanhee in txif for positive latitude. Then x is // We only invoke atanhee in txif for positive latitude. Then x is
// only negative for very prolate ellipsoids (_b/_a >= sqrt(2)) and we // only negative for very prolate ellipsoids (_b/_a >= sqrt(2)) and we
// still need to return a positive result in this case; hence the n eed // still need to return a positive result in this case; hence the n eed
// for the call to atan2. // for the call to atan2.
(_f < 0 ? (std::atan2(_e * std::abs(x), x < 0 ? -1 : 1)/_e) : x); (_f < 0 ? (std::atan2(_e * std::abs(x), x < 0 ? -1 : 1)/_e) : x);
} }
// return atanh(sqrt(x))/sqrt(x) - 1, accurate for small x // return atanh(sqrt(x))/sqrt(x) - 1, accurate for small x
static real atanhxm1(real x) throw(); static real atanhxm1(real x);
// Divided differences // Divided differences
// Definition: Df(x,y) = (f(x)-f(y))/(x-y) // Definition: Df(x,y) = (f(x)-f(y))/(x-y)
// See: // See:
// W. M. Kahan and R. J. Fateman, // W. M. Kahan and R. J. Fateman,
// Symbolic computation of divided differences, // Symbolic computation of divided differences,
// SIGSAM Bull. 33(3), 7-28 (1999) // SIGSAM Bull. 33(3), 7-28 (1999)
// http://dx.doi.org/10.1145/334714.334716 // http://dx.doi.org/10.1145/334714.334716
// http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf
// //
// General rules // General rules
// h(x) = f(g(x)): Dh(x,y) = Df(g(x),g(y))*Dg(x,y) // h(x) = f(g(x)): Dh(x,y) = Df(g(x),g(y))*Dg(x,y)
// h(x) = f(x)*g(x): // h(x) = f(x)*g(x):
// Dh(x,y) = Df(x,y)*g(x) + Dg(x,y)*f(y) // Dh(x,y) = Df(x,y)*g(x) + Dg(x,y)*f(y)
// = Df(x,y)*g(y) + Dg(x,y)*f(x) // = Df(x,y)*g(y) + Dg(x,y)*f(x)
// = Df(x,y)*(g(x)+g(y))/2 + Dg(x,y)*(f(x)+f(y))/2 // = Df(x,y)*(g(x)+g(y))/2 + Dg(x,y)*(f(x)+f(y))/2
// //
// sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^ 2)) // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^ 2))
static inline real Dsn(real x, real y, real sx, real sy) throw() { static inline real Dsn(real x, real y, real sx, real sy) {
// sx = x/hyp(x) // sx = x/hyp(x)
real t = x * y; real t = x * y;
return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) : return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) :
(x - y != 0 ? (sx - sy) / (x - y) : 1); (x - y != 0 ? (sx - sy) / (x - y) : 1);
} }
// Datanhee(x,y) = atanhee((x-y)/(1-e^2*x*y))/(x-y) // Datanhee(x,y) = atanhee((x-y)/(1-e^2*x*y))/(x-y)
inline real Datanhee(real x, real y) const throw() { inline real Datanhee(real x, real y) const {
real t = x - y, d = 1 - _e2 * x * y; real t = x - y, d = 1 - _e2 * x * y;
return t != 0 ? atanhee(t / d) / t : 1 / d; return t != 0 ? atanhee(t / d) / t : 1 / d;
} }
// DDatanhee(x,y) = (Datanhee(1,y) - Datanhee(1,x))/(y-x) // DDatanhee(x,y) = (Datanhee(1,y) - Datanhee(1,x))/(y-x)
real DDatanhee(real x, real y) const throw(); real DDatanhee(real x, real y) const;
void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1) thro void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1);
w(); real txif(real tphi) const;
real txif(real tphi) const throw(); real tphif(real txi) const;
real tphif(real txi) const throw();
friend class Ellipsoid; // For access to txif, tphif, etc. friend class Ellipsoid; // For access to txif, tphif, etc.
public: public:
/** /**
* Constructor with a single standard parallel. * Constructor with a single standard parallel.
* *
* @param[in] a equatorial radius of ellipsoid (meters). * @param[in] a equatorial radius of ellipsoid (meters).
* @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re. * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re.
* Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing
skipping to change at line 222 skipping to change at line 222
* scale is the 1/\e k. * scale is the 1/\e k.
* *
* The latitude origin is given by AlbersEqualArea::LatitudeOrigin(). No * The latitude origin is given by AlbersEqualArea::LatitudeOrigin(). No
* false easting or northing is added and \e lat should be in the range * false easting or northing is added and \e lat should be in the range
* [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
* range [&minus;540&deg;, 540&deg;). The values of \e x and \e y * range [&minus;540&deg;, 540&deg;). The values of \e x and \e y
* returned for points which project to infinity (i.e., one or both of the * returned for points which project to infinity (i.e., one or both of the
* poles) will be large but finite. * poles) will be large but finite.
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y, real& gamma, real& k) const throw(); real& x, real& y, real& gamma, real& k) const;
/** /**
* Reverse projection, from Lambert conformal conic to geographic. * Reverse projection, from Lambert conformal conic to geographic.
* *
* @param[in] lon0 central meridian longitude (degrees). * @param[in] lon0 central meridian longitude (degrees).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
skipping to change at line 245 skipping to change at line 245
* *
* The latitude origin is given by AlbersEqualArea::LatitudeOrigin(). No * The latitude origin is given by AlbersEqualArea::LatitudeOrigin(). No
* false easting or northing is added. \e lon0 should be in the range * false easting or northing is added. \e lon0 should be in the range
* [&minus;540&deg;, 540&deg;). The value of \e lon returned is in * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
* the range [&minus;180&deg;, 180&deg;). The value of \e lat * the range [&minus;180&deg;, 180&deg;). The value of \e lat
* returned is in the range [&minus;90&deg;, 90&deg;]. If the * returned is in the range [&minus;90&deg;, 90&deg;]. If the
* input point is outside the legal projected space the nearest pole is * input point is outside the legal projected space the nearest pole is
* returned. * returned.
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon, real& gamma, real& k) const throw(); real& lat, real& lon, real& gamma, real& k) const;
/** /**
* AlbersEqualArea::Forward without returning the convergence and * AlbersEqualArea::Forward without returning the convergence and
* scale. * scale.
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real gamma, k; real gamma, k;
Forward(lon0, lat, lon, x, y, gamma, k); Forward(lon0, lat, lon, x, y, gamma, k);
} }
/** /**
* AlbersEqualArea::Reverse without returning the convergence and * AlbersEqualArea::Reverse without returning the convergence and
* scale. * scale.
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real gamma, k; real gamma, k;
Reverse(lon0, x, y, lat, lon, gamma, k); Reverse(lon0, x, y, lat, lon, gamma, k);
} }
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value use d in * @return \e f the flattening of the ellipsoid. This is the value use d in
* the constructor. * the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* @return latitude of the origin for the projection (degrees). * @return latitude of the origin for the projection (degrees).
* *
* This is the latitude of minimum azimuthal scale and equals the \e st dlat * This is the latitude of minimum azimuthal scale and equals the \e st dlat
* in the 1-parallel constructor and lies between \e stdlat1 and \e std lat2 * in the 1-parallel constructor and lies between \e stdlat1 and \e std lat2
* in the 2-parallel constructors. * in the 2-parallel constructors.
********************************************************************** / ********************************************************************** /
Math::real OriginLatitude() const throw() { return _lat0; } Math::real OriginLatitude() const { return _lat0; }
/** /**
* @return central scale for the projection. This is the azimuthal sca le * @return central scale for the projection. This is the azimuthal sca le
* on the latitude of origin. * on the latitude of origin.
********************************************************************** / ********************************************************************** /
Math::real CentralScale() const throw() { return _k0; } Math::real CentralScale() const { return _k0; }
///@} ///@}
/** /**
* A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e
* stdlat = 0, and \e k0 = 1. This degenerates to the cylindrical equa l * stdlat = 0, and \e k0 = 1. This degenerates to the cylindrical equa l
* area projection. * area projection.
********************************************************************** / ********************************************************************** /
static const AlbersEqualArea CylindricalEqualArea; static const AlbersEqualArea CylindricalEqualArea;
/** /**
 End of changes. 15 change blocks. 
19 lines changed or deleted 18 lines changed or added


 AzimuthalEquidistant.hpp   AzimuthalEquidistant.hpp 
skipping to change at line 56 skipping to change at line 56
static const real eps_; static const real eps_;
public: public:
/** /**
* Constructor for AzimuthalEquidistant. * Constructor for AzimuthalEquidistant.
* *
* @param[in] earth the Geodesic object to use for geodesic calculation s. * @param[in] earth the Geodesic object to use for geodesic calculation s.
* By default this uses the WGS84 ellipsoid. * By default this uses the WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
explicit AzimuthalEquidistant(const Geodesic& earth = Geodesic::WGS84) explicit AzimuthalEquidistant(const Geodesic& earth = Geodesic::WGS84)
throw() : _earth(earth) {} : _earth(earth) {}
/** /**
* Forward projection, from geographic to azimuthal equidistant. * Forward projection, from geographic to azimuthal equidistant.
* *
* @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lat0 latitude of center point of projection (degrees).
* @param[in] lon0 longitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees).
* @param[in] lat latitude of point (degrees). * @param[in] lat latitude of point (degrees).
* @param[in] lon longitude of point (degrees). * @param[in] lon longitude of point (degrees).
* @param[out] x easting of point (meters). * @param[out] x easting of point (meters).
* @param[out] y northing of point (meters). * @param[out] y northing of point (meters).
skipping to change at line 79 skipping to change at line 79
* *
* \e lat0 and \e lat should be in the range [&minus;90&deg;, * \e lat0 and \e lat should be in the range [&minus;90&deg;,
* 90&deg;] and \e lon0 and \e lon should be in the range * 90&deg;] and \e lon0 and \e lon should be in the range
* [&minus;540&deg;, 540&deg;). The scale of the projection is 1 * [&minus;540&deg;, 540&deg;). The scale of the projection is 1
* in the "radial" direction, \e azi clockwise from true north, and is 1/\e * in the "radial" direction, \e azi clockwise from true north, and is 1/\e
* rk in the direction perpendicular to this. A call to Forward follow ed * rk in the direction perpendicular to this. A call to Forward follow ed
* by a call to Reverse will return the original (\e lat, \e lon) (to * by a call to Reverse will return the original (\e lat, \e lon) (to
* within roundoff). * within roundoff).
********************************************************************** / ********************************************************************** /
void Forward(real lat0, real lon0, real lat, real lon, void Forward(real lat0, real lon0, real lat, real lon,
real& x, real& y, real& azi, real& rk) const throw(); real& x, real& y, real& azi, real& rk) const;
/** /**
* Reverse projection, from azimuthal equidistant to geographic. * Reverse projection, from azimuthal equidistant to geographic.
* *
* @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lat0 latitude of center point of projection (degrees).
* @param[in] lon0 longitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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).
skipping to change at line 104 skipping to change at line 104
* lon0 should be in the range [&minus;540&deg;, 540&deg;). \e lat * lon0 should be in the range [&minus;540&deg;, 540&deg;). \e lat
* will be in the range [&minus;90&deg;, 90&deg;] and \e lon will * will be in the range [&minus;90&deg;, 90&deg;] and \e lon will
* be in the range [&minus;180&deg;, 180&deg;). The scale of the * be in the range [&minus;180&deg;, 180&deg;). The scale of the
* projection is 1 in the "radial" direction, \e azi clockwise from tru e * projection is 1 in the "radial" direction, \e azi clockwise from tru e
* north, and is 1/\e rk in the direction perpendicular to this. A cal l to * north, and is 1/\e rk in the direction perpendicular to this. A cal l to
* Reverse followed by a call to Forward will return the original (\e x , \e * Reverse followed by a call to Forward will return the original (\e x , \e
* y) (to roundoff) only if the geodesic to (\e x, \e y) is a shortest * y) (to roundoff) only if the geodesic to (\e x, \e y) is a shortest
* path. * path.
********************************************************************** / ********************************************************************** /
void Reverse(real lat0, real lon0, real x, real y, void Reverse(real lat0, real lon0, real x, real y,
real& lat, real& lon, real& azi, real& rk) const throw(); real& lat, real& lon, real& azi, real& rk) const;
/** /**
* AzimuthalEquidistant::Forward without returning the azimuth and scal e. * AzimuthalEquidistant::Forward without returning the azimuth and scal e.
********************************************************************** / ********************************************************************** /
void Forward(real lat0, real lon0, real lat, real lon, void Forward(real lat0, real lon0, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real azi, rk; real azi, rk;
Forward(lat0, lon0, lat, lon, x, y, azi, rk); Forward(lat0, lon0, lat, lon, x, y, azi, rk);
} }
/** /**
* AzimuthalEquidistant::Reverse without returning the azimuth and scal e. * AzimuthalEquidistant::Reverse without returning the azimuth and scal e.
********************************************************************** / ********************************************************************** /
void Reverse(real lat0, real lon0, real x, real y, void Reverse(real lat0, real lon0, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real azi, rk; real azi, rk;
Reverse(lat0, lon0, x, y, lat, lon, azi, rk); Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
} }
/** \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 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 _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geodesic object used in the constructor. * inherited from the Geodesic object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return _earth.InverseFlattening(); } { return _earth.InverseFlattening(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_AZIMUTHALEQUIDISTANT_HPP #endif // GEOGRAPHICLIB_AZIMUTHALEQUIDISTANT_HPP
 End of changes. 8 change blocks. 
8 lines changed or deleted 8 lines changed or added


 CassiniSoldner.hpp   CassiniSoldner.hpp 
skipping to change at line 80 skipping to change at line 80
private: private:
typedef Math::real real; typedef Math::real real;
Geodesic _earth; Geodesic _earth;
GeodesicLine _meridian; GeodesicLine _meridian;
real _sbet0, _cbet0; real _sbet0, _cbet0;
static const real eps1_; static const real eps1_;
static const real tiny_; static const real tiny_;
static const unsigned maxit_ = 10; static const unsigned maxit_ = 10;
// The following private helper functions are copied from Geodesic. // The following private helper functions are copied from Geodesic.
static inline real AngRound(real x) throw() { static inline real AngRound(real x) {
// The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^ 57 // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^ 57
// for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi s // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi s
// is about 1000 times more resolution than we get with angles around 90 // is about 1000 times more resolution than we get with angles around 90
// degrees.) We use this to avoid having to deal with near singular // degrees.) We use this to avoid having to deal with near singular
// cases when x is non-zero but tiny (e.g., 1.0e-200). // cases when x is non-zero but tiny (e.g., 1.0e-200).
const real z = 1/real(16); const real z = 1/real(16);
volatile real y = std::abs(x); volatile real y = std::abs(x);
// The compiler mustn't "simplify" z - (z - y) to y // The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y; y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y; return x < 0 ? -y : y;
} }
static inline void SinCosNorm(real& sinx, real& cosx) throw() { static inline void SinCosNorm(real& sinx, real& cosx) {
real r = Math::hypot(sinx, cosx); real r = Math::hypot(sinx, cosx);
sinx /= r; sinx /= r;
cosx /= r; cosx /= r;
} }
public: public:
/** /**
* Constructor for CassiniSoldner. * Constructor for CassiniSoldner.
* *
* @param[in] earth the Geodesic object to use for geodesic calculation s. * @param[in] earth the Geodesic object to use for geodesic calculation s.
* By default this uses the WGS84 ellipsoid. * By default this uses the WGS84 ellipsoid.
* *
* This constructor makes an "uninitialized" object. Call Reset to set the * This constructor makes an "uninitialized" object. Call Reset to set the
* central latitude and longitude, prior to calling Forward and Reverse . * central latitude and longitude, prior to calling Forward and Reverse .
********************************************************************** / ********************************************************************** /
explicit CassiniSoldner(const Geodesic& earth = Geodesic::WGS84) throw( ) explicit CassiniSoldner(const Geodesic& earth = Geodesic::WGS84)
: _earth(earth) {} : _earth(earth) {}
/** /**
* Constructor for CassiniSoldner specifying a center point. * Constructor for CassiniSoldner specifying a center point.
* *
* @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lat0 latitude of center point of projection (degrees).
* @param[in] lon0 longitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees).
* @param[in] earth the Geodesic object to use for geodesic calculation s. * @param[in] earth the Geodesic object to use for geodesic calculation s.
* By default this uses the WGS84 ellipsoid. * By default this uses the WGS84 ellipsoid.
* *
* \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
* lon0 should be in the range [&minus;540&deg;, 540&deg;). * lon0 should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
CassiniSoldner(real lat0, real lon0, CassiniSoldner(real lat0, real lon0,
const Geodesic& earth = Geodesic::WGS84) throw() const Geodesic& earth = Geodesic::WGS84)
: _earth(earth) { : _earth(earth) {
Reset(lat0, lon0); Reset(lat0, lon0);
} }
/** /**
* Set the central point of the projection * Set the central point of the projection
* *
* @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lat0 latitude of center point of projection (degrees).
* @param[in] lon0 longitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees).
* *
* \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
* lon0 should be in the range [&minus;540&deg;, 540&deg;). * lon0 should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void Reset(real lat0, real lon0) throw(); void Reset(real lat0, real lon0);
/** /**
* Forward projection, from geographic to Cassini-Soldner. * Forward projection, from geographic to Cassini-Soldner.
* *
* @param[in] lat latitude of point (degrees). * @param[in] lat latitude of point (degrees).
* @param[in] lon longitude of point (degrees). * @param[in] lon longitude of point (degrees).
* @param[out] x easting of point (meters). * @param[out] x easting of point (meters).
* @param[out] y northing of point (meters). * @param[out] y northing of point (meters).
* @param[out] azi azimuth of easting direction at point (degrees). * @param[out] azi azimuth of easting direction at point (degrees).
* @param[out] rk reciprocal of azimuthal northing scale at point. * @param[out] rk reciprocal of azimuthal northing scale at point.
* *
* \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
* lon should be in the range [&minus;540&deg;, 540&deg;). A call * lon should be in the range [&minus;540&deg;, 540&deg;). A call
* to Forward followed by a call to Reverse will return the original (\ e * to Forward followed by a call to Reverse will return the original (\ e
* lat, \e lon) (to within roundoff). The routine does nothing if the * lat, \e lon) (to within roundoff). The routine does nothing if the
* origin has not been set. * origin has not been set.
********************************************************************** / ********************************************************************** /
void Forward(real lat, real lon, void Forward(real lat, real lon,
real& x, real& y, real& azi, real& rk) const throw(); real& x, real& y, real& azi, real& rk) const;
/** /**
* Reverse projection, from Cassini-Soldner to geographic. * Reverse projection, from Cassini-Soldner to geographic.
* *
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] azi azimuth of easting direction at point (degrees). * @param[out] azi azimuth of easting direction at point (degrees).
* @param[out] rk reciprocal of azimuthal northing scale at point. * @param[out] rk reciprocal of azimuthal northing scale at point.
* *
* A call to Reverse followed by a call to Forward will return the orig inal * A call to Reverse followed by a call to Forward will return the orig inal
* (\e x, \e y) (to within roundoff), provided that \e x and \e y are * (\e x, \e y) (to within roundoff), provided that \e x and \e y are
* sufficiently small not to "wrap around" the earth. The routine does * sufficiently small not to "wrap around" the earth. The routine does
* nothing if the origin has not been set. * nothing if the origin has not been set.
********************************************************************** / ********************************************************************** /
void Reverse(real x, real y, void Reverse(real x, real y,
real& lat, real& lon, real& azi, real& rk) const throw(); real& lat, real& lon, real& azi, real& rk) const;
/** /**
* CassiniSoldner::Forward without returning the azimuth and scale. * CassiniSoldner::Forward without returning the azimuth and scale.
********************************************************************** / ********************************************************************** /
void Forward(real lat, real lon, void Forward(real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real azi, rk; real azi, rk;
Forward(lat, lon, x, y, azi, rk); Forward(lat, lon, x, y, azi, rk);
} }
/** /**
* CassiniSoldner::Reverse without returning the azimuth and scale. * CassiniSoldner::Reverse without returning the azimuth and scale.
********************************************************************** / ********************************************************************** /
void Reverse(real x, real y, void Reverse(real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real azi, rk; real azi, rk;
Reverse(x, y, lat, lon, azi, rk); Reverse(x, y, lat, lon, azi, rk);
} }
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _meridian.Init(); } bool Init() const { return _meridian.Init(); }
/** /**
* @return \e lat0 the latitude of origin (degrees). * @return \e lat0 the latitude of origin (degrees).
********************************************************************** / ********************************************************************** /
Math::real LatitudeOrigin() const throw() Math::real LatitudeOrigin() const
{ return _meridian.Latitude(); } { return _meridian.Latitude(); }
/** /**
* @return \e lon0 the longitude of origin (degrees). * @return \e lon0 the longitude of origin (degrees).
********************************************************************** / ********************************************************************** /
Math::real LongitudeOrigin() const throw() Math::real LongitudeOrigin() const
{ return _meridian.Longitude(); } { return _meridian.Longitude(); }
/** /**
* @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 _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geodesic object used in the constructor. * inherited from the Geodesic object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return _earth.InverseFlattening(); } { return _earth.InverseFlattening(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_CASSINISOLDNER_HPP #endif // GEOGRAPHICLIB_CASSINISOLDNER_HPP
 End of changes. 15 change blocks. 
15 lines changed or deleted 15 lines changed or added


 CircularEngine.hpp   CircularEngine.hpp 
skipping to change at line 67 skipping to change at line 67
SCHMIDT = SphericalEngine::SCHMIDT, SCHMIDT = SphericalEngine::SCHMIDT,
}; };
int _M; int _M;
bool _gradp; bool _gradp;
unsigned _norm; unsigned _norm;
real _a, _r, _u, _t; real _a, _r, _u, _t;
std::vector<real> _wc, _ws, _wrc, _wrs, _wtc, _wts; std::vector<real> _wc, _ws, _wrc, _wrs, _wtc, _wts;
real _q, _uq, _uq2; real _q, _uq, _uq2;
Math::real Value(bool gradp, real cl, real sl, Math::real Value(bool gradp, real cl, real sl,
real& gradx, real& grady, real& gradz) const throw(); real& gradx, real& grady, real& gradz) const;
static inline void cossin(real x, real& cosx, real& sinx) { static inline void cossin(real x, real& cosx, real& sinx) {
x = x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); x = x >= 180 ? x - 360 : (x < -180 ? x + 360 : x);
real xi = x * Math::degree<real>(); real xi = x * Math::degree<real>();
cosx = std::abs(x) == 90 ? 0 : cos(xi); cosx = std::abs(x) == 90 ? 0 : cos(xi);
sinx = x == -180 ? 0 : sin(xi); sinx = x == -180 ? 0 : sin(xi);
} }
friend class SphericalEngine; friend class SphericalEngine;
friend class GravityCircle; // Access to cossin friend class GravityCircle; // Access to cossin
skipping to change at line 137 skipping to change at line 137
* Evaluate the sum for a particular longitude given in terms of its * Evaluate the sum for a particular longitude given in terms of its
* cosine and sine. * cosine and sine.
* *
* @param[in] coslon the cosine of the longitude. * @param[in] coslon the cosine of the longitude.
* @param[in] sinlon the sine of the longitude. * @param[in] sinlon the sine of the longitude.
* @return \e V the value of the sum. * @return \e V the value of the sum.
* *
* The arguments must satisfy <i>coslon</i><sup>2</sup> + * The arguments must satisfy <i>coslon</i><sup>2</sup> +
* <i>sinlon</i><sup>2</sup> = 1. * <i>sinlon</i><sup>2</sup> = 1.
********************************************************************** / ********************************************************************** /
Math::real operator()(real coslon, real sinlon) const throw() { Math::real operator()(real coslon, real sinlon) const {
real dummy; real dummy;
return Value(false, coslon, sinlon, dummy, dummy, dummy); return Value(false, coslon, sinlon, dummy, dummy, dummy);
} }
/** /**
* Evaluate the sum for a particular longitude. * Evaluate the sum for a particular longitude.
* *
* @param[in] lon the longitude (degrees). * @param[in] lon the longitude (degrees).
* @return \e V the value of the sum. * @return \e V the value of the sum.
********************************************************************** / ********************************************************************** /
Math::real operator()(real lon) const throw() { Math::real operator()(real lon) const {
real coslon, sinlon; real coslon, sinlon;
cossin(lon, coslon, sinlon); cossin(lon, coslon, sinlon);
return (*this)(coslon, sinlon); return (*this)(coslon, sinlon);
} }
/** /**
* Evaluate the sum and its gradient for a particular longitude given i n * Evaluate the sum and its gradient for a particular longitude given i n
* terms of its cosine and sine. * terms of its cosine and sine.
* *
* @param[in] coslon the cosine of the longitude. * @param[in] coslon the cosine of the longitude.
skipping to change at line 172 skipping to change at line 172
* @param[out] gradz \e z component of the gradient. * @param[out] gradz \e z component of the gradient.
* @return \e V the value of the sum. * @return \e V the value of the sum.
* *
* The gradients will only be computed if the CircularEngine object was * The gradients will only be computed if the CircularEngine object was
* created with this capability (e.g., via \e gradp = true in * created with this capability (e.g., via \e gradp = true in
* SphericalHarmonic::Circle). If not, \e gradx, etc., will not be * SphericalHarmonic::Circle). If not, \e gradx, etc., will not be
* touched. The arguments must satisfy <i>coslon</i><sup>2</sup> + * touched. The arguments must satisfy <i>coslon</i><sup>2</sup> +
* <i>sinlon</i><sup>2</sup> = 1. * <i>sinlon</i><sup>2</sup> = 1.
********************************************************************** / ********************************************************************** /
Math::real operator()(real coslon, real sinlon, Math::real operator()(real coslon, real sinlon,
real& gradx, real& grady, real& gradz) const thro w() { real& gradx, real& grady, real& gradz) const {
return Value(true, coslon, sinlon, gradx, grady, gradz); return Value(true, coslon, sinlon, gradx, grady, gradz);
} }
/** /**
* Evaluate the sum and its gradient for a particular longitude. * Evaluate the sum and its gradient for a particular longitude.
* *
* @param[in] lon the longitude (degrees). * @param[in] lon the longitude (degrees).
* @param[out] gradx \e x component of the gradient. * @param[out] gradx \e x component of the gradient.
* @param[out] grady \e y component of the gradient. * @param[out] grady \e y component of the gradient.
* @param[out] gradz \e z component of the gradient. * @param[out] gradz \e z component of the gradient.
* @return \e V the value of the sum. * @return \e V the value of the sum.
* *
* The gradients will only be computed if the CircularEngine object was * The gradients will only be computed if the CircularEngine object was
* created with this capability (e.g., via \e gradp = true in * created with this capability (e.g., via \e gradp = true in
* SphericalHarmonic::Circle). If not, \e gradx, etc., will not be * SphericalHarmonic::Circle). If not, \e gradx, etc., will not be
* touched. * touched.
********************************************************************** / ********************************************************************** /
Math::real operator()(real lon, Math::real operator()(real lon,
real& gradx, real& grady, real& gradz) const thro w() { real& gradx, real& grady, real& gradz) const {
real coslon, sinlon; real coslon, sinlon;
cossin(lon, coslon, sinlon); cossin(lon, coslon, sinlon);
return (*this)(coslon, sinlon, gradx, grady, gradz); return (*this)(coslon, sinlon, gradx, grady, gradz);
} }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning (pop) # pragma warning (pop)
 End of changes. 5 change blocks. 
5 lines changed or deleted 5 lines changed or added


 Config.h   Config.h 
#define GEOGRAPHICLIB_VERSION_MAJOR 1 #define GEOGRAPHICLIB_VERSION_MAJOR 1
#define GEOGRAPHICLIB_VERSION_MINOR 35 #define GEOGRAPHICLIB_VERSION_MINOR 36
#define GEOGRAPHICLIB_VERSION_PATCH 0 #define GEOGRAPHICLIB_VERSION_PATCH 0
#define HAVE_LONG_DOUBLE 1 #define HAVE_LONG_DOUBLE 1
#define GEOGRAPHICLIB_VERSION_STRING "1.35" #define GEOGRAPHICLIB_VERSION_STRING "1.36"
/* # undef WORDS_BIGENDIAN */ /* # undef WORDS_BIGENDIAN */
 End of changes. 2 change blocks. 
2 lines changed or deleted 2 lines changed or added


 Constants.hpp   Constants.hpp 
skipping to change at line 86 skipping to change at line 86
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT Constants { class GEOGRAPHICLIB_EXPORT Constants {
private: private:
typedef Math::real real; typedef Math::real real;
Constants(); // Disable constructor Constants(); // Disable constructor
public: public:
/** /**
* A synonym for Math::degree<real>(). * A synonym for Math::degree<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real degree() throw() { return Math::degree<real>() ; } static inline Math::real degree() { 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() static inline Math::real arcminute()
{ return Math::degree<real>() / 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()
{ return Math::degree<real>() / 3600; } { return Math::degree<real>() / 3600; }
/** \name Ellipsoid parameters /** \name Ellipsoid parameters
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the equatorial radius of WGS84 ellipsoid (6378137 m). * @return the equatorial radius of WGS84 ellipsoid (6378137 m).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_a() throw() template<typename T> static inline T WGS84_a()
{ return T(6378137) * meter<T>(); } { return T(6378137) * meter<T>(); }
/** /**
* A synonym for WGS84_a<real>(). * A synonym for WGS84_a<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real WGS84_a() throw() { return WGS84_a<real>(); } static inline Math::real WGS84_a() { return WGS84_a<real>(); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the flattening of WGS84 ellipsoid (1/298.257223563). * @return the flattening of WGS84 ellipsoid (1/298.257223563).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_f() throw() template<typename T> static inline T WGS84_f()
{ return T(1) / ( T(298) + T(257223563) / T(1000000000) ); } { return T(1) / ( T(298) + T(257223563) / T(1000000000) ); }
/** /**
* A synonym for WGS84_f<real>(). * A synonym for WGS84_f<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real WGS84_f() throw() { return WGS84_f<real>(); } static inline Math::real WGS84_f() { return WGS84_f<real>(); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the gravitational constant of the WGS84 ellipsoid, \e GM, in * @return the gravitational constant of the WGS84 ellipsoid, \e GM, in
* m<sup>3</sup> s<sup>&minus;2</sup>. * m<sup>3</sup> s<sup>&minus;2</sup>.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_GM() throw() template<typename T> static inline T WGS84_GM()
{ return T(3986004) * T(100000000) + T(41800000); } { return T(3986004) * T(100000000) + T(41800000); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the angular velocity of the WGS84 ellipsoid, &omega;, in rad * @return the angular velocity of the WGS84 ellipsoid, &omega;, in rad
* s<sup>&minus;1</sup>. * s<sup>&minus;1</sup>.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_omega() throw() template<typename T> static inline T WGS84_omega()
{ return T(7292115) / (T(1000000) * T(100000)); } { return T(7292115) / (T(1000000) * T(100000)); }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return the reciprocal flattening of WGS84 ellipsoid. * @return the reciprocal flattening of WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_r() throw() template<typename T> static inline T WGS84_r()
{ return 1/WGS84_f<T>(); } { return 1/WGS84_f<T>(); }
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* A synonym for WGS84_r<real>(). * A synonym for WGS84_r<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real WGS84_r() throw() { return WGS84_r<real>(); } static inline Math::real WGS84_r() { return WGS84_r<real>(); }
/// \endcond /// \endcond
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the equatorial radius of GRS80 ellipsoid, \e a, in m. * @return the equatorial radius of GRS80 ellipsoid, \e a, in m.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T GRS80_a() throw() template<typename T> static inline T GRS80_a()
{ return T(6378137); } { return T(6378137); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the gravitational constant of the GRS80 ellipsoid, \e GM, in * @return the gravitational constant of the GRS80 ellipsoid, \e GM, in
* m<sup>3</sup> s<sup>&minus;2</sup>. * m<sup>3</sup> s<sup>&minus;2</sup>.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T GRS80_GM() throw() template<typename T> static inline T GRS80_GM()
{ return T(3986005) * T(100000000); } { return T(3986005) * T(100000000); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the angular velocity of the GRS80 ellipsoid, &omega;, in rad * @return the angular velocity of the GRS80 ellipsoid, &omega;, in rad
* s<sup>&minus;1</sup>. * s<sup>&minus;1</sup>.
* *
* This is about 2 &pi; 366.25 / (365.25 &times; 24 &times; 3600) rad * This is about 2 &pi; 366.25 / (365.25 &times; 24 &times; 3600) rad
* s<sup>&minus;1</sup>. 365.25 is the number of days in a Julian year and * s<sup>&minus;1</sup>. 365.25 is the number of days in a Julian year and
* 365.35/366.25 converts from solar days to sidereal days. Using the * 365.35/366.25 converts from solar days to sidereal days. Using the
* number of days in a Gregorian year (365.2425) results in a worse * number of days in a Gregorian year (365.2425) results in a worse
* approximation (because the Gregorian year includes the precession of the * approximation (because the Gregorian year includes the precession of the
* earth's axis). * earth's axis).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T GRS80_omega() throw() template<typename T> static inline T GRS80_omega()
{ return T(7292115) / (T(1000000) * T(100000)); } { return T(7292115) / (T(1000000) * T(100000)); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the dynamical form factor of the GRS80 ellipsoid, * @return the dynamical form factor of the GRS80 ellipsoid,
* <i>J</i><sub>2</sub>. * <i>J</i><sub>2</sub>.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T GRS80_J2() throw() template<typename T> static inline T GRS80_J2()
{ return T(108263) / T(100000000); } { return T(108263) / T(100000000); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the central scale factor for UTM (0.9996). * @return the central scale factor for UTM (0.9996).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T UTM_k0() throw() template<typename T> static inline T UTM_k0()
{return T(9996) / T(10000); } {return T(9996) / T(10000); }
/** /**
* A synonym for UTM_k0<real>(). * A synonym for UTM_k0<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real UTM_k0() throw() { return UTM_k0<real>(); } static inline Math::real UTM_k0() { return UTM_k0<real>(); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the central scale factor for UPS (0.994). * @return the central scale factor for UPS (0.994).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T UPS_k0() throw() template<typename T> static inline T UPS_k0()
{ return T(994) / T(1000); } { return T(994) / T(1000); }
/** /**
* A synonym for UPS_k0<real>(). * A synonym for UPS_k0<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real UPS_k0() throw() { return UPS_k0<real>(); } static inline Math::real UPS_k0() { return UPS_k0<real>(); }
///@} ///@}
/** \name SI units /** \name SI units
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @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.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T meter() throw() { return T(1); } template<typename T> static inline T meter() { return T(1); }
/** /**
* A synonym for meter<real>(). * A synonym for meter<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real meter() throw() { return meter<real>(); } static inline Math::real meter() { 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() static inline Math::real kilometer()
{ return 1000 * meter<real>(); } { 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() static inline Math::real nauticalmile()
{ return 1852 * meter<real>(); } { return 1852 * meter<real>(); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the number of square meters in a square meter. * @return the number of square meters in a square 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.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T square_meter() throw() template<typename T> static inline T square_meter()
{ return meter<real>() * meter<real>(); } { return meter<real>() * meter<real>(); }
/** /**
* A synonym for square_meter<real>(). * A synonym for square_meter<real>().
********************************************************************** / ********************************************************************** /
static inline Math::real square_meter() throw() static inline Math::real square_meter()
{ return square_meter<real>(); } { return square_meter<real>(); }
/** /**
* @return the number of square meters in a hectare. * @return the number of square meters in a hectare.
********************************************************************** / ********************************************************************** /
static inline Math::real hectare() throw() static inline Math::real hectare()
{ return 10000 * square_meter<real>(); } { return 10000 * square_meter<real>(); }
/** /**
* @return the number of square meters in a square kilometer. * @return the number of square meters in a square kilometer.
********************************************************************** / ********************************************************************** /
static inline Math::real square_kilometer() throw() static inline Math::real square_kilometer()
{ return kilometer() * kilometer(); } { return kilometer() * kilometer(); }
/** /**
* @return the number of square meters in a square nautical mile. * @return the number of square meters in a square nautical mile.
********************************************************************** / ********************************************************************** /
static inline Math::real square_nauticalmile() throw() static inline Math::real square_nauticalmile()
{ return nauticalmile() * nauticalmile(); } { return nauticalmile() * nauticalmile(); }
///@} ///@}
/** \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()
{ return real(0.0254L) * 12 * meter<real>(); } { 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() { 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() { return 2 * yard(); }
/** /**
* @return the number of meters in a chain. * @return the number of meters in a chain.
********************************************************************** / ********************************************************************** /
static inline Math::real chain() throw() { return 22 * yard(); } static inline Math::real chain() { return 22 * yard(); }
/** /**
* @return the number of meters in a furlong. * @return the number of meters in a furlong.
********************************************************************** / ********************************************************************** /
static inline Math::real furlong() throw() { return 10 * chain(); } static inline Math::real furlong() { return 10 * chain(); }
/** /**
* @return the number of meters in a statute mile. * @return the number of meters in a statute mile.
********************************************************************** / ********************************************************************** /
static inline Math::real mile() throw() { return 8 * furlong(); } static inline Math::real mile() { return 8 * furlong(); }
/** /**
* @return the number of square meters in an acre. * @return the number of square meters in an acre.
********************************************************************** / ********************************************************************** /
static inline Math::real acre() throw() { return chain() * furlong(); } static inline Math::real acre() { return chain() * furlong(); }
/** /**
* @return the number of square meters in a square statute mile. * @return the number of square meters in a square statute mile.
********************************************************************** / ********************************************************************** /
static inline Math::real square_mile() throw() { return mile() * mile() ; } static inline Math::real square_mile() { return mile() * mile(); }
///@} ///@}
/** \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()
{ return real(1200) / real(3937) * meter<real>(); } { 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 from std::runtime_error so it * A class to handle exceptions. It's derived from std::runtime_error so it
* can be caught by the usual catch clauses. * can be caught by the usual catch clauses.
* *
 End of changes. 37 change blocks. 
37 lines changed or deleted 37 lines changed or added


 DMS.hpp   DMS.hpp 
skipping to change at line 193 skipping to change at line 193
* *
* @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 (degrees) * @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)
{ return d + (m + s/real(60))/real(60); } { return d + (m + s/real(60))/real(60); }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> (use Utility::num, instead). * <b>DEPRECATED</b> (use Utility::num, instead).
* Convert a string to a real number. * Convert a string to a real number.
* *
* @param[in] str string input. * @param[in] str string input.
* @exception GeographicErr if \e str is malformed. * @exception GeographicErr if \e str is malformed.
* @return decoded number. * @return decoded number.
skipping to change at line 343 skipping to change at line 343
ind, dmssep); ind, dmssep);
} }
/** /**
* Split angle into degrees and minutes * Split angle into degrees and minutes
* *
* @param[in] ang angle (degrees) * @param[in] ang angle (degrees)
* @param[out] d degrees (an integer returned as a real) * @param[out] d degrees (an integer returned as a real)
* @param[out] m arc minutes. * @param[out] m arc minutes.
********************************************************************** / ********************************************************************** /
static void Encode(real ang, real& d, real& m) throw() { static void Encode(real ang, real& d, real& m) {
d = int(ang); m = 60 * (ang - d); d = int(ang); m = 60 * (ang - d);
} }
/** /**
* Split angle into degrees and minutes and seconds. * Split angle into degrees and minutes and seconds.
* *
* @param[in] ang angle (degrees) * @param[in] ang angle (degrees)
* @param[out] d degrees (an integer returned as a real) * @param[out] d degrees (an integer returned as a real)
* @param[out] m arc minutes (an integer returned as a real) * @param[out] m arc minutes (an integer returned as a real)
* @param[out] s arc seconds. * @param[out] s arc seconds.
********************************************************************** / ********************************************************************** /
static void Encode(real ang, real& d, real& m, real& s) throw() { static void Encode(real ang, real& d, real& m, real& s) {
d = int(ang); ang = 60 * (ang - d); d = int(ang); ang = 60 * (ang - d);
m = int(ang); s = 60 * (ang - m); m = int(ang); s = 60 * (ang - m);
} }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning (pop) # pragma warning (pop)
 End of changes. 3 change blocks. 
3 lines changed or deleted 3 lines changed or added


 Ellipsoid.hpp   Ellipsoid.hpp 
skipping to change at line 48 skipping to change at line 48
class GEOGRAPHICLIB_EXPORT Ellipsoid { class GEOGRAPHICLIB_EXPORT Ellipsoid {
private: private:
typedef Math::real real; typedef Math::real real;
static const int numit_ = 10; static const int numit_ = 10;
static const real stol_; static const real stol_;
real _a, _f, _f1, _f12, _e2, _e12, _n, _b; real _a, _f, _f1, _f12, _e2, _e12, _n, _b;
TransverseMercator _tm; TransverseMercator _tm;
EllipticFunction _ell; EllipticFunction _ell;
AlbersEqualArea _au; AlbersEqualArea _au;
static real tand(real x) throw() { static real tand(real x) {
return return
std::abs(x) == real(90) ? (x < 0 ? std::abs(x) == real(90) ? (x < 0 ?
- TransverseMercator::overflow_ - TransverseMercator::overflow_
: TransverseMercator::overflow_) : : TransverseMercator::overflow_) :
std::tan(x * Math::degree<real>()); std::tan(x * Math::degree<real>());
} }
static real atand(real x) throw() static real atand(real x)
{ return std::atan(x) / Math::degree<real>(); } { return std::atan(x) / Math::degree<real>(); }
public: public:
/** \name Constructor /** \name Constructor
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Constructor for a ellipsoid with * Constructor for a ellipsoid with
* *
skipping to change at line 84 skipping to change at line 84
///@} ///@}
/** \name %Ellipsoid dimensions. /** \name %Ellipsoid dimensions.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @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 { return _a; }
/** /**
* @return \e b the polar semi-axis (meters). * @return \e b the polar semi-axis (meters).
********************************************************************** / ********************************************************************** /
Math::real MinorRadius() const throw() { return _b; } Math::real MinorRadius() const { return _b; }
/** /**
* @return \e L the distance between the equator and a pole along a * @return \e L the distance between the equator and a pole along a
* meridian (meters). For a sphere \e L = (&pi;/2) \e a. The radius * meridian (meters). For a sphere \e L = (&pi;/2) \e a. The radius
* of a sphere with the same meridian length is \e L / (&pi;/2). * of a sphere with the same meridian length is \e L / (&pi;/2).
********************************************************************** / ********************************************************************** /
Math::real QuarterMeridian() const throw(); Math::real QuarterMeridian() const;
/** /**
* @return \e A the total area of the ellipsoid (meters<sup>2</sup>). For * @return \e A the total area of the ellipsoid (meters<sup>2</sup>). For
* a sphere \e A = 4&pi; <i>a</i><sup>2</sup>. The radius of a spher e * a sphere \e A = 4&pi; <i>a</i><sup>2</sup>. The radius of a spher e
* with the same area is sqrt(\e A / (4&pi;)). * with the same area is sqrt(\e A / (4&pi;)).
********************************************************************** / ********************************************************************** /
Math::real Area() const throw(); Math::real Area() const;
/** /**
* @return \e V the total volume of the ellipsoid (meters<sup>3</sup>). * @return \e V the total volume of the ellipsoid (meters<sup>3</sup>).
* For a sphere \e V = (4&pi; / 3) <i>a</i><sup>3</sup>. The radius of * For a sphere \e V = (4&pi; / 3) <i>a</i><sup>3</sup>. The radius of
* a sphere with the same volume is cbrt(\e V / (4&pi;/3)). * a sphere with the same volume is cbrt(\e V / (4&pi;/3)).
********************************************************************** / ********************************************************************** /
Math::real Volume() const throw() Math::real Volume() const
{ return (4 * Math::pi<real>()) * Math::sq(_a) * _b / 3; } { return (4 * Math::pi<real>()) * Math::sq(_a) * _b / 3; }
///@} ///@}
/** \name %Ellipsoid shape /** \name %Ellipsoid shape
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return \e f = (\e a &minus; \e b) / \e a, the flattening of the * @return \e f = (\e a &minus; \e b) / \e a, the flattening of the
* ellipsoid. This is the value used in the constructor. This is ze ro, * ellipsoid. This is the value used in the constructor. This is ze ro,
* positive, or negative for a sphere, oblate ellipsoid, or prolate * positive, or negative for a sphere, oblate ellipsoid, or prolate
* ellipsoid. * ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/** /**
* @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening o f * @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening o f
* the ellipsoid. This is zero, positive, or negative for a sphere, * the ellipsoid. This is zero, positive, or negative for a sphere,
* oblate ellipsoid, or prolate ellipsoid. * oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real SecondFlattening() const throw() { return _f / (1 - _f); } Math::real SecondFlattening() const { return _f / (1 - _f); }
/** /**
* @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third flatte ning * @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third flatte ning
* of the ellipsoid. This is zero, positive, or negative for a spher e, * of the ellipsoid. This is zero, positive, or negative for a spher e,
* oblate ellipsoid, or prolate ellipsoid. * oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real ThirdFlattening() const throw() { return _n; } Math::real ThirdFlattening() const { return _n; }
/** /**
* @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity squ ared * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity squ ared
* of the ellipsoid. This is zero, positive, or negative for a spher e, * of the ellipsoid. This is zero, positive, or negative for a spher e,
* oblate ellipsoid, or prolate ellipsoid. * oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real EccentricitySq() const throw() { return _e2; } Math::real EccentricitySq() const { return _e2; }
/** /**
* @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric ity * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric ity
* squared of the ellipsoid. This is zero, positive, or negative for a * squared of the ellipsoid. This is zero, positive, or negative for a
* sphere, oblate ellipsoid, or prolate ellipsoid. * sphere, oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real SecondEccentricitySq() const throw() { return _e12; } Math::real SecondEccentricitySq() const { return _e12; }
/** /**
* @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</su p>), * <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</su p>),
* the third eccentricity squared of the ellipsoid. This is zero, * the third eccentricity squared of the ellipsoid. This is zero,
* positive, or negative for a sphere, oblate ellipsoid, or prolate * positive, or negative for a sphere, oblate ellipsoid, or prolate
* ellipsoid. * ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real ThirdEccentricitySq() const throw() { return _e2 / (2 - _e2) ; } Math::real ThirdEccentricitySq() const { return _e2 / (2 - _e2); }
///@} ///@}
/** \name Latitude conversion. /** \name Latitude conversion.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &beta; the parametric latitude (degrees). * @return &beta; the parametric latitude (degrees).
* *
skipping to change at line 190 skipping to change at line 190
* - \e R = \e a cos &beta; * - \e R = \e a cos &beta;
* - \e Z = \e b sin &beta; * - \e Z = \e b sin &beta;
* . * .
* where \e a and \e b are the equatorial radius and the polar semi-axi s. * where \e a and \e b are the equatorial radius and the polar semi-axi s.
* For a sphere &beta; = &phi;. * For a sphere &beta; = &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &beta; lies in [&minus;90&deg;, 90&deg;]. * &beta; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real ParametricLatitude(real phi) const throw(); Math::real ParametricLatitude(real phi) const;
/** /**
* @param[in] beta the parametric latitude (degrees). * @param[in] beta the parametric latitude (degrees).
* @return &phi; the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* &beta; must lie in the range [&minus;90&deg;, 90&deg;]; the * &beta; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &phi; lies in [&minus;90&deg;, 90&deg;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseParametricLatitude(real beta) const throw(); Math::real InverseParametricLatitude(real beta) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &theta; the geocentric latitude (degrees). * @return &theta; the geocentric latitude (degrees).
* *
* The geocentric latitude, &theta;, is the angle beween the equatorial * The geocentric latitude, &theta;, is the angle beween the equatorial
* plane and a line between the center of the ellipsoid and a point on the * plane and a line between the center of the ellipsoid and a point on the
* ellipsoid. For a sphere &theta; = &phi;. * ellipsoid. For a sphere &theta; = &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &theta; lies in [&minus;90&deg;, 90&deg;]. * &theta; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real GeocentricLatitude(real phi) const throw(); Math::real GeocentricLatitude(real phi) const;
/** /**
* @param[in] theta the geocentric latitude (degrees). * @param[in] theta the geocentric latitude (degrees).
* @return &phi; the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* &theta; must lie in the range [&minus;90&deg;, 90&deg;]; the * &theta; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &phi; lies in [&minus;90&deg;, 90&deg;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseGeocentricLatitude(real theta) const throw(); Math::real InverseGeocentricLatitude(real theta) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &mu; the rectifying latitude (degrees). * @return &mu; the rectifying latitude (degrees).
* *
* The rectifying latitude, &mu;, has the property that the distance al ong * The rectifying latitude, &mu;, has the property that the distance al ong
* a meridian of the ellipsoid between two points with rectifying latit udes * a meridian of the ellipsoid between two points with rectifying latit udes
* &mu;<sub>1</sub> and &mu;<sub>2</sub> is equal to * &mu;<sub>1</sub> and &mu;<sub>2</sub> is equal to
* (&mu;<sub>2</sub> - &mu;<sub>1</sub>) \e L / 90&deg;, * (&mu;<sub>2</sub> - &mu;<sub>1</sub>) \e L / 90&deg;,
* where \e L = QuarterMeridian(). For a sphere &mu; = &phi;. * where \e L = QuarterMeridian(). For a sphere &mu; = &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &mu; lies in [&minus;90&deg;, 90&deg;]. * &mu; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real RectifyingLatitude(real phi) const throw(); Math::real RectifyingLatitude(real phi) const;
/** /**
* @param[in] mu the rectifying latitude (degrees). * @param[in] mu the rectifying latitude (degrees).
* @return &phi; the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* &mu; must lie in the range [&minus;90&deg;, 90&deg;]; the * &mu; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &phi; lies in [&minus;90&deg;, 90&deg;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseRectifyingLatitude(real mu) const throw(); Math::real InverseRectifyingLatitude(real mu) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &xi; the authalic latitude (degrees). * @return &xi; the authalic latitude (degrees).
* *
* The authalic latitude, &xi;, has the property that the area of the * The authalic latitude, &xi;, has the property that the area of the
* ellipsoid between two circles with authalic latitudes * ellipsoid between two circles with authalic latitudes
* &xi;<sub>1</sub> and &xi;<sub>2</sub> is equal to (sin * &xi;<sub>1</sub> and &xi;<sub>2</sub> is equal to (sin
* &xi;<sub>2</sub> - sin &xi;<sub>1</sub>) \e A / 2, where \e A * &xi;<sub>2</sub> - sin &xi;<sub>1</sub>) \e A / 2, where \e A
* = Area(). For a sphere &xi; = &phi;. * = Area(). For a sphere &xi; = &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &xi; lies in [&minus;90&deg;, 90&deg;]. * &xi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real AuthalicLatitude(real phi) const throw(); Math::real AuthalicLatitude(real phi) const;
/** /**
* @param[in] xi the authalic latitude (degrees). * @param[in] xi the authalic latitude (degrees).
* @return &phi; the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* &xi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &xi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &phi; lies in [&minus;90&deg;, 90&deg;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseAuthalicLatitude(real xi) const throw(); Math::real InverseAuthalicLatitude(real xi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &chi; the conformal latitude (degrees). * @return &chi; the conformal latitude (degrees).
* *
* The conformal latitude, &chi;, gives the mapping of the ellipsoid to a * The conformal latitude, &chi;, gives the mapping of the ellipsoid to a
* sphere which which is conformal (angles are preserved) and in which the * sphere which which is conformal (angles are preserved) and in which the
* equator of the ellipsoid maps to the equator of the sphere. For a * equator of the ellipsoid maps to the equator of the sphere. For a
* sphere &chi; = &phi;. * sphere &chi; = &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &chi; lies in [&minus;90&deg;, 90&deg;]. * &chi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real ConformalLatitude(real phi) const throw(); Math::real ConformalLatitude(real phi) const;
/** /**
* @param[in] chi the conformal latitude (degrees). * @param[in] chi the conformal latitude (degrees).
* @return &phi; the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* &chi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &chi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. The returned v alue * result is undefined if this condition does not hold. The returned v alue
* &phi; lies in [&minus;90&deg;, 90&deg;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseConformalLatitude(real chi) const throw(); Math::real InverseConformalLatitude(real chi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &psi; the isometric latitude (degrees). * @return &psi; the isometric latitude (degrees).
* *
* The isometric latitude gives the mapping of the ellipsoid to a plane * The isometric latitude gives the mapping of the ellipsoid to a plane
* which which is conformal (angles are preserved) and in which the equ ator * which which is conformal (angles are preserved) and in which the equ ator
* of the ellipsoid maps to a straight line of constant scale; this map ping * of the ellipsoid maps to a straight line of constant scale; this map ping
* defines the Mercator projection. For a sphere &psi; = * defines the Mercator projection. For a sphere &psi; =
* sinh<sup>&minus;1</sup> tan &phi;. * sinh<sup>&minus;1</sup> tan &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. * result is undefined if this condition does not hold.
********************************************************************** / ********************************************************************** /
Math::real IsometricLatitude(real phi) const throw(); Math::real IsometricLatitude(real phi) const;
/** /**
* @param[in] psi the isometric latitude (degrees). * @param[in] psi the isometric latitude (degrees).
* @return &phi; the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* The returned value &phi; lies in [&minus;90&deg;, 90&deg;]. * The returned value &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseIsometricLatitude(real psi) const throw(); Math::real InverseIsometricLatitude(real psi) const;
///@} ///@}
/** \name Other quantities. /** \name Other quantities.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e R = \e a cos &beta; the radius of a circle of latitude * @return \e R = \e a cos &beta; the radius of a circle of latitude
* &phi; (meters). \e R (&pi;/180&deg;) gives meters per degree * &phi; (meters). \e R (&pi;/180&deg;) gives meters per degree
* longitude measured along a circle of latitude. * longitude measured along a circle of latitude.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. * result is undefined if this condition does not hold.
********************************************************************** / ********************************************************************** /
Math::real CircleRadius(real phi) const throw(); Math::real CircleRadius(real phi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e Z = \e b sin &beta; the distance of a circle of latitude * @return \e Z = \e b sin &beta; the distance of a circle of latitude
* &phi; from the equator measured parallel to the ellipsoid axis * &phi; from the equator measured parallel to the ellipsoid axis
* (meters). * (meters).
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. * result is undefined if this condition does not hold.
********************************************************************** / ********************************************************************** /
Math::real CircleHeight(real phi) const throw(); Math::real CircleHeight(real phi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e s the distance along a meridian * @return \e s the distance along a meridian
* between the equator and a point of latitude &phi; (meters). \e s is * between the equator and a point of latitude &phi; (meters). \e s is
* given by \e s = &mu; \e L / 90&deg;, where \e L = * given by \e s = &mu; \e L / 90&deg;, where \e L =
* QuarterMeridian()). * QuarterMeridian()).
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. * result is undefined if this condition does not hold.
********************************************************************** / ********************************************************************** /
Math::real MeridianDistance(real phi) const throw(); Math::real MeridianDistance(real phi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &rho; the meridional radius of curvature of the ellipsoid at * @return &rho; the meridional radius of curvature of the ellipsoid at
* latitude &phi; (meters); this is the curvature of the meridian. \ e * latitude &phi; (meters); this is the curvature of the meridian. \ e
* rho is given by &rho; = (180&deg;/&pi;) d\e s / d&phi;, * rho is given by &rho; = (180&deg;/&pi;) d\e s / d&phi;,
* where \e s = MeridianDistance(); thus &rho; (&pi;/180&deg;) * where \e s = MeridianDistance(); thus &rho; (&pi;/180&deg;)
* gives meters per degree latitude measured along a meridian. * gives meters per degree latitude measured along a meridian.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. * result is undefined if this condition does not hold.
********************************************************************** / ********************************************************************** /
Math::real MeridionalCurvatureRadius(real phi) const throw(); Math::real MeridionalCurvatureRadius(real phi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return &nu; the transverse radius of curvature of the ellipsoid at * @return &nu; the transverse radius of curvature of the ellipsoid at
* latitude &phi; (meters); this is the curvature of a curve on the * latitude &phi; (meters); this is the curvature of a curve on the
* ellipsoid which also lies in a plane perpendicular to the ellipsoi d * ellipsoid which also lies in a plane perpendicular to the ellipsoi d
* and to the meridian. &nu; is related to \e R = CircleRadius() by \e * and to the meridian. &nu; is related to \e R = CircleRadius() by \e
* R = &nu; cos &phi;. * R = &nu; cos &phi;.
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the * &phi; must lie in the range [&minus;90&deg;, 90&deg;]; the
* result is undefined if this condition does not hold. * result is undefined if this condition does not hold.
********************************************************************** / ********************************************************************** /
Math::real TransverseCurvatureRadius(real phi) const throw(); Math::real TransverseCurvatureRadius(real phi) const;
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @param[in] azi the angle between the meridian and the normal section * @param[in] azi the angle between the meridian and the normal section
* (degrees). * (degrees).
* @return the radius of curvature of the ellipsoid in the normal * @return the radius of curvature of the ellipsoid in the normal
* section at latitude &phi; inclined at an angle \e azi to the * section at latitude &phi; inclined at an angle \e azi to the
* meridian (meters). * meridian (meters).
* *
* &phi; must lie in the range [&minus;90&deg;, 90&deg;] and \e * &phi; must lie in the range [&minus;90&deg;, 90&deg;] and \e
* azi must lie in the range [&minus;540&deg;, 540&deg;); the * azi must lie in the range [&minus;540&deg;, 540&deg;); the
* result is undefined if either of conditions does not hold. * result is undefined if either of conditions does not hold.
********************************************************************** / ********************************************************************** /
Math::real NormalCurvatureRadius(real phi, real azi) const throw(); Math::real NormalCurvatureRadius(real phi, real azi) const;
///@} ///@}
/** \name Eccentricity conversions. /** \name Eccentricity conversions.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @param[in] fp = \e f ' = (\e a &minus; \e b) / \e b, the second * @param[in] fp = \e f ' = (\e a &minus; \e b) / \e b, the second
* flattening. * flattening.
* @return \e f = (\e a &minus; \e b) / \e a, the flattening. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* \e f ' should lie in (&minus;1, &infin;). * \e f ' should lie in (&minus;1, &infin;).
* The returned value \e f lies in (&minus;&infin;, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real SecondFlatteningToFlattening(real fp) throw() static Math::real SecondFlatteningToFlattening(real fp)
{ return fp / (1 + fp); } { return fp / (1 + fp); }
/** /**
* @param[in] f = (\e a &minus; \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening. * @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening.
* *
* \e f should lie in (&minus;&infin;, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value \e f ' lies in (&minus;1, &infin;). * The returned value \e f ' lies in (&minus;1, &infin;).
********************************************************************** / ********************************************************************** /
static Math::real FlatteningToSecondFlattening(real f) throw() static Math::real FlatteningToSecondFlattening(real f)
{ return f / (1 - f); } { return f / (1 - f); }
/** /**
* @param[in] n = (\e a &minus; \e b) / (\e a + \e b), the third * @param[in] n = (\e a &minus; \e b) / (\e a + \e b), the third
* flattening. * flattening.
* @return \e f = (\e a &minus; \e b) / \e a, the flattening. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* \e n should lie in (&minus;1, 1). * \e n should lie in (&minus;1, 1).
* The returned value \e f lies in (&minus;&infin;, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real ThirdFlatteningToFlattening(real n) throw() static Math::real ThirdFlatteningToFlattening(real n)
{ return 2 * n / (1 + n); } { return 2 * n / (1 + n); }
/** /**
* @param[in] f = (\e a &minus; \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third * @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third
* flattening. * flattening.
* *
* \e f should lie in (&minus;&infin;, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value \e n lies in (&minus;1, 1). * The returned value \e n lies in (&minus;1, 1).
********************************************************************** / ********************************************************************** /
static Math::real FlatteningToThirdFlattening(real f) throw() static Math::real FlatteningToThirdFlattening(real f)
{ return f / (2 - f); } { return f / (2 - f); }
/** /**
* @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity
* squared. * squared.
* @return \e f = (\e a &minus; \e b) / \e a, the flattening. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* <i>e</i><sup>2</sup> should lie in (&minus;&infin;, 1). * <i>e</i><sup>2</sup> should lie in (&minus;&infin;, 1).
* The returned value \e f lies in (&minus;&infin;, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real EccentricitySqToFlattening(real e2) throw() static Math::real EccentricitySqToFlattening(real e2)
{ return e2 / (std::sqrt(1 - e2) + 1); } { return e2 / (std::sqrt(1 - e2) + 1); }
/** /**
* @param[in] f = (\e a &minus; \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity
* squared. * squared.
* *
* \e f should lie in (&minus;&infin;, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value <i>e</i><sup>2</sup> lies in (&minus;&infin;, 1). * The returned value <i>e</i><sup>2</sup> lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real FlatteningToEccentricitySq(real f) throw() static Math::real FlatteningToEccentricitySq(real f)
{ return f * (2 - f); } { return f * (2 - f); }
/** /**
* @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &min us; * @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &min us;
* <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric ity * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric ity
* squared. * squared.
* @return \e f = (\e a &minus; \e b) / \e a, the flattening. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* <i>e'</i> <sup>2</sup> should lie in (&minus;1, &infin;). * <i>e'</i> <sup>2</sup> should lie in (&minus;1, &infin;).
* The returned value \e f lies in (&minus;&infin;, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real SecondEccentricitySqToFlattening(real ep2) throw() static Math::real SecondEccentricitySqToFlattening(real ep2)
{ return ep2 / (std::sqrt(1 + ep2) + 1 + ep2); } { return ep2 / (std::sqrt(1 + ep2) + 1 + ep2); }
/** /**
* @param[in] f = (\e a &minus; \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric ity * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentric ity
* squared. * squared.
* *
* \e f should lie in (&minus;&infin;, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value <i>e'</i> <sup>2</sup> lies in (&minus;1, &infin; ). * The returned value <i>e'</i> <sup>2</sup> lies in (&minus;1, &infin; ).
********************************************************************** / ********************************************************************** /
static Math::real FlatteningToSecondEccentricitySq(real f) throw() static Math::real FlatteningToSecondEccentricitySq(real f)
{ return f * (2 - f) / Math::sq(1 - f); } { return f * (2 - f) / Math::sq(1 - f); }
/** /**
* @param[in] epp2 = <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> * @param[in] epp2 = <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup>
* &minus; <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + * &minus; <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> +
* <i>b</i><sup>2</sup>), the third eccentricity squared. * <i>b</i><sup>2</sup>), the third eccentricity squared.
* @return \e f = (\e a &minus; \e b) / \e a, the flattening. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* <i>e''</i> <sup>2</sup> should lie in (&minus;1, 1). * <i>e''</i> <sup>2</sup> should lie in (&minus;1, 1).
* The returned value \e f lies in (&minus;&infin;, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real ThirdEccentricitySqToFlattening(real epp2) throw() static Math::real ThirdEccentricitySqToFlattening(real epp2)
{ return 2 * epp2 / (sqrt((1 - epp2) * (1 + epp2)) + 1 + epp2); } { return 2 * epp2 / (sqrt((1 - epp2) * (1 + epp2)) + 1 + epp2); }
/** /**
* @param[in] f = (\e a &minus; \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus; * @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> &minus;
* <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</su p>), * <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</su p>),
* the third eccentricity squared. * the third eccentricity squared.
* *
* \e f should lie in (&minus;&infin;, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value <i>e''</i> <sup>2</sup> lies in (&minus;1, 1). * The returned value <i>e''</i> <sup>2</sup> lies in (&minus;1, 1).
********************************************************************** / ********************************************************************** /
static Math::real FlatteningToThirdEccentricitySq(real f) throw() static Math::real FlatteningToThirdEccentricitySq(real f)
{ return f * (2 - f) / (1 + Math::sq(1 - f)); } { return f * (2 - f) / (1 + Math::sq(1 - f)); }
///@} ///@}
/** /**
* A global instantiation of Ellipsoid with the parameters for the WGS8 4 * A global instantiation of Ellipsoid with the parameters for the WGS8 4
* ellipsoid. * ellipsoid.
********************************************************************** / ********************************************************************** /
static const Ellipsoid WGS84; static const Ellipsoid WGS84;
 End of changes. 41 change blocks. 
41 lines changed or deleted 41 lines changed or added


 EllipticFunction.hpp   EllipticFunction.hpp 
skipping to change at line 74 skipping to change at line 74
typedef Math::real real; typedef Math::real real;
static const real tol_; static const real tol_;
static const real tolRF_; static const real tolRF_;
static const real tolRD_; static const real tolRD_;
static const real tolRG0_; static const real tolRG0_;
static const real tolJAC_; static const real tolJAC_;
enum { num_ = 13 }; // Max depth required for sncndn. Probably 5 is en ough. enum { num_ = 13 }; // Max depth required for sncndn. Probably 5 is en ough.
real _k2, _kp2, _alpha2, _alphap2, _eps; real _k2, _kp2, _alpha2, _alphap2, _eps;
mutable bool _init; mutable bool _init;
mutable real _Kc, _Ec, _Dc, _Pic, _Gc, _Hc; mutable real _Kc, _Ec, _Dc, _Pic, _Gc, _Hc;
bool Init() const throw(); bool Init() const;
public: public:
/** \name Constructor /** \name Constructor
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Constructor specifying the modulus and parameter. * Constructor specifying the modulus and parameter.
* *
* @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>.
* <i>k</i><sup>2</sup> must lie in (-&infin;, 1). (No checking is * <i>k</i><sup>2</sup> must lie in (-&infin;, 1). (No checking is
* done.) * done.)
* @param[in] alpha2 the parameter &alpha;<sup>2</sup>. * @param[in] alpha2 the parameter &alpha;<sup>2</sup>.
* &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.) * &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.)
* *
* If only elliptic integrals of the first and second kinds are needed, * If only elliptic integrals of the first and second kinds are needed,
* then set &alpha;<sup>2</sup> = 0 (the default value); in this case, we * then set &alpha;<sup>2</sup> = 0 (the default value); in this case, we
* have &Pi;(&phi;, 0, \e k) = \e F(&phi;, \e k), \e G(&phi;, 0, \e k) = \e * have &Pi;(&phi;, 0, \e k) = \e F(&phi;, \e k), \e G(&phi;, 0, \e k) = \e
* E(&phi;, \e k), and \e H(&phi;, 0, \e k) = \e F(&phi;, \e k) - \e * E(&phi;, \e k), and \e H(&phi;, 0, \e k) = \e F(&phi;, \e k) - \e
* D(&phi;, \e k). * D(&phi;, \e k).
********************************************************************** / ********************************************************************** /
EllipticFunction(real k2 = 0, real alpha2 = 0) throw(); EllipticFunction(real k2 = 0, real alpha2 = 0);
/** /**
* Constructor specifying the modulus and parameter and their complemen ts. * Constructor specifying the modulus and parameter and their complemen ts.
* *
* @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>.
* <i>k</i><sup>2</sup> must lie in (-&infin;, 1). (No checking is * <i>k</i><sup>2</sup> must lie in (-&infin;, 1). (No checking is
* done.) * done.)
* @param[in] alpha2 the parameter &alpha;<sup>2</sup>. * @param[in] alpha2 the parameter &alpha;<sup>2</sup>.
* &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.) * &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.)
* @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su p> = * @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su p> =
* 1 &minus; <i>k</i><sup>2</sup>. * 1 &minus; <i>k</i><sup>2</sup>.
* @param[in] alphap2 the complementary parameter &alpha;'<sup>2</sup> = 1 * @param[in] alphap2 the complementary parameter &alpha;'<sup>2</sup> = 1
* &minus; &alpha;<sup>2</sup>. * &minus; &alpha;<sup>2</sup>.
* *
* The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp hap2 * The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp hap2
* = 1. (No checking is done that these conditions are met.) This * = 1. (No checking is done that these conditions are met.) This
* constructor is provided to enable accuracy to be maintained, e.g., w hen * constructor is provided to enable accuracy to be maintained, e.g., w hen
* \e k is very close to unity. * \e k is very close to unity.
********************************************************************** / ********************************************************************** /
EllipticFunction(real k2, real alpha2, real kp2, real alphap2) throw(); EllipticFunction(real k2, real alpha2, real kp2, real alphap2);
/** /**
* Reset the modulus and parameter. * Reset the modulus and parameter.
* *
* @param[in] k2 the new value of square of the modulus * @param[in] k2 the new value of square of the modulus
* <i>k</i><sup>2</sup> which must lie in (-&infin;, 1). (No checkin g is * <i>k</i><sup>2</sup> which must lie in (-&infin;, 1). (No checkin g is
* done.) * done.)
* @param[in] alpha2 the new value of parameter &alpha;<sup>2</sup>. * @param[in] alpha2 the new value of parameter &alpha;<sup>2</sup>.
* &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.) * &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.)
********************************************************************** / ********************************************************************** /
void Reset(real k2 = 0, real alpha2 = 0) throw() void Reset(real k2 = 0, real alpha2 = 0)
{ Reset(k2, alpha2, 1 - k2, 1 - alpha2); } { Reset(k2, alpha2, 1 - k2, 1 - alpha2); }
/** /**
* Reset the modulus and parameter supplying also their complements. * Reset the modulus and parameter supplying also their complements.
* *
* @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>. * @param[in] k2 the square of the modulus <i>k</i><sup>2</sup>.
* <i>k</i><sup>2</sup> must lie in (-&infin;, 1). (No checking is * <i>k</i><sup>2</sup> must lie in (-&infin;, 1). (No checking is
* done.) * done.)
* @param[in] alpha2 the parameter &alpha;<sup>2</sup>. * @param[in] alpha2 the parameter &alpha;<sup>2</sup>.
* &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.) * &alpha;<sup>2</sup> must lie in (-&infin;, 1). (No checking is do ne.)
* @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su p> = * @param[in] kp2 the complementary modulus squared <i>k'</i><sup>2</su p> =
* 1 &minus; <i>k</i><sup>2</sup>. * 1 &minus; <i>k</i><sup>2</sup>.
* @param[in] alphap2 the complementary parameter &alpha;'<sup>2</sup> = 1 * @param[in] alphap2 the complementary parameter &alpha;'<sup>2</sup> = 1
* &minus; &alpha;<sup>2</sup>. * &minus; &alpha;<sup>2</sup>.
* *
* The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp hap2 * The arguments must satisfy \e k2 + \e kp2 = 1 and \e alpha2 + \e alp hap2
* = 1. (No checking is done that these conditions are met.) This * = 1. (No checking is done that these conditions are met.) This
* constructor is provided to enable accuracy to be maintained, e.g., w hen * constructor is provided to enable accuracy to be maintained, e.g., w hen
* is very small. * is very small.
********************************************************************** / ********************************************************************** /
void Reset(real k2, real alpha2, real kp2, real alphap2) throw(); void Reset(real k2, real alpha2, real kp2, real alphap2);
///@} ///@}
/** \name Inspector functions. /** \name Inspector functions.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return the square of the modulus <i>k</i><sup>2</sup>. * @return the square of the modulus <i>k</i><sup>2</sup>.
********************************************************************** / ********************************************************************** /
Math::real k2() const throw() { return _k2; } Math::real k2() const { return _k2; }
/** /**
* @return the square of the complementary modulus <i>k'</i><sup>2</sup > = * @return the square of the complementary modulus <i>k'</i><sup>2</sup > =
* 1 &minus; <i>k</i><sup>2</sup>. * 1 &minus; <i>k</i><sup>2</sup>.
********************************************************************** / ********************************************************************** /
Math::real kp2() const throw() { return _kp2; } Math::real kp2() const { return _kp2; }
/** /**
* @return the parameter &alpha;<sup>2</sup>. * @return the parameter &alpha;<sup>2</sup>.
********************************************************************** / ********************************************************************** /
Math::real alpha2() const throw() { return _alpha2; } Math::real alpha2() const { return _alpha2; }
/** /**
* @return the complementary parameter &alpha;'<sup>2</sup> = 1 &minus; * @return the complementary parameter &alpha;'<sup>2</sup> = 1 &minus;
* &alpha;<sup>2</sup>. * &alpha;<sup>2</sup>.
********************************************************************** / ********************************************************************** /
Math::real alphap2() const throw() { return _alphap2; } Math::real alphap2() const { return _alphap2; }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* @return the square of the modulus <i>k</i><sup>2</sup>. * @return the square of the modulus <i>k</i><sup>2</sup>.
* *
* <b>DEPRECATED</b>, use k2() instead. * <b>DEPRECATED</b>, use k2() instead.
********************************************************************** / ********************************************************************** /
Math::real m() const throw() { return _k2; } Math::real m() const { return _k2; }
/** /**
* @return the square of the complementary modulus <i>k'</i><sup>2</sup > = * @return the square of the complementary modulus <i>k'</i><sup>2</sup > =
* 1 &minus; <i>k</i><sup>2</sup>. * 1 &minus; <i>k</i><sup>2</sup>.
* *
* <b>DEPRECATED</b>, use kp2() instead. * <b>DEPRECATED</b>, use kp2() instead.
********************************************************************** / ********************************************************************** /
Math::real m1() const throw() { return _kp2; } Math::real m1() const { return _kp2; }
/// \endcond /// \endcond
/** \name Complete elliptic integrals. /** \name Complete elliptic integrals.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* The complete integral of the first kind. * The complete integral of the first kind.
* *
* @return \e K(\e k). * @return \e K(\e k).
* *
* \e K(\e k) is defined in http://dlmf.nist.gov/19.2.E4 * \e K(\e k) is defined in http://dlmf.nist.gov/19.2.E4
* \f[ * \f[
* K(k) = \int_0^{\pi/2} \frac1{\sqrt{1-k^2\sin^2\phi}}\,d\phi. * K(k) = \int_0^{\pi/2} \frac1{\sqrt{1-k^2\sin^2\phi}}\,d\phi.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real K() const throw() { _init || Init(); return _Kc; } Math::real K() const { _init || Init(); return _Kc; }
/** /**
* The complete integral of the second kind. * The complete integral of the second kind.
* *
* @return \e E(\e k) * @return \e E(\e k)
* *
* \e E(\e k) is defined in http://dlmf.nist.gov/19.2.E5 * \e E(\e k) is defined in http://dlmf.nist.gov/19.2.E5
* \f[ * \f[
* E(k) = \int_0^{\pi/2} \sqrt{1-k^2\sin^2\phi}\,d\phi. * E(k) = \int_0^{\pi/2} \sqrt{1-k^2\sin^2\phi}\,d\phi.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real E() const throw() { _init || Init(); return _Ec; } Math::real E() const { _init || Init(); return _Ec; }
/** /**
* Jahnke's complete integral. * Jahnke's complete integral.
* *
* @return \e D(\e k). * @return \e D(\e k).
* *
* \e D(\e k) is defined in http://dlmf.nist.gov/19.2.E6 * \e D(\e k) is defined in http://dlmf.nist.gov/19.2.E6
* \f[ * \f[
* D(k) = \int_0^{\pi/2} \frac{\sin^2\phi}{\sqrt{1-k^2\sin^2\phi}}\,d \phi. * D(k) = \int_0^{\pi/2} \frac{\sin^2\phi}{\sqrt{1-k^2\sin^2\phi}}\,d \phi.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real D() const throw() { _init || Init(); return _Dc; } Math::real D() const { _init || Init(); return _Dc; }
/** /**
* The difference between the complete integrals of the first and secon d * The difference between the complete integrals of the first and secon d
* kinds. * kinds.
* *
* @return \e K(\e k) &minus; \e E(\e k). * @return \e K(\e k) &minus; \e E(\e k).
********************************************************************** / ********************************************************************** /
Math::real KE() const throw() { _init || Init(); return _k2 * _Dc; } Math::real KE() const { _init || Init(); return _k2 * _Dc; }
/** /**
* The complete integral of the third kind. * The complete integral of the third kind.
* *
* @return &Pi;(&alpha;<sup>2</sup>, \e k) * @return &Pi;(&alpha;<sup>2</sup>, \e k)
* *
* &Pi;(&alpha;<sup>2</sup>, \e k) is defined in * &Pi;(&alpha;<sup>2</sup>, \e k) is defined in
* http://dlmf.nist.gov/19.2.E7 * http://dlmf.nist.gov/19.2.E7
* \f[ * \f[
* \Pi(\alpha^2, k) = \int_0^{\pi/2} * \Pi(\alpha^2, k) = \int_0^{\pi/2}
* \frac1{\sqrt{1-k^2\sin^2\phi}(1 - \alpha^2\sin^2\phi_)}\,d\phi. * \frac1{\sqrt{1-k^2\sin^2\phi}(1 - \alpha^2\sin^2\phi_)}\,d\phi.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real Pi() const throw() { _init || Init(); return _Pic; } Math::real Pi() const { _init || Init(); return _Pic; }
/** /**
* Legendre's complete geodesic longitude integral. * Legendre's complete geodesic longitude integral.
* *
* @return \e G(&alpha;<sup>2</sup>, \e k) * @return \e G(&alpha;<sup>2</sup>, \e k)
* *
* \e G(&alpha;<sup>2</sup>, \e k) is given by * \e G(&alpha;<sup>2</sup>, \e k) is given by
* \f[ * \f[
* G(\alpha^2, k) = \int_0^{\pi/2} * G(\alpha^2, k) = \int_0^{\pi/2}
* \frac{\sqrt{1-k^2\sin^2\phi}}{1 - \alpha^2\sin^2\phi}\,d\phi. * \frac{\sqrt{1-k^2\sin^2\phi}}{1 - \alpha^2\sin^2\phi}\,d\phi.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real G() const throw() { _init || Init(); return _Gc; } Math::real G() const { _init || Init(); return _Gc; }
/** /**
* Cayley's complete geodesic longitude difference integral. * Cayley's complete geodesic longitude difference integral.
* *
* @return \e H(&alpha;<sup>2</sup>, \e k) * @return \e H(&alpha;<sup>2</sup>, \e k)
* *
* \e H(&alpha;<sup>2</sup>, \e k) is given by * \e H(&alpha;<sup>2</sup>, \e k) is given by
* \f[ * \f[
* H(\alpha^2, k) = \int_0^{\pi/2} * H(\alpha^2, k) = \int_0^{\pi/2}
* \frac{\cos^2\phi}{(1-\alpha^2\sin^2\phi)\sqrt{1-k^2\sin^2\phi}} * \frac{\cos^2\phi}{(1-\alpha^2\sin^2\phi)\sqrt{1-k^2\sin^2\phi}}
* \,d\phi. * \,d\phi.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real H() const throw() { _init || Init(); return _Hc; } Math::real H() const { _init || Init(); return _Hc; }
///@} ///@}
/** \name Incomplete elliptic integrals. /** \name Incomplete elliptic integrals.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* The incomplete integral of the first kind. * The incomplete integral of the first kind.
* *
* @param[in] phi * @param[in] phi
* @return \e F(&phi;, \e k). * @return \e F(&phi;, \e k).
* *
* \e F(&phi;, \e k) is defined in http://dlmf.nist.gov/19.2.E4 * \e F(&phi;, \e k) is defined in http://dlmf.nist.gov/19.2.E4
* \f[ * \f[
* F(\phi, k) = \int_0^\phi \frac1{\sqrt{1-k^2\sin^2\theta}}\,d\theta . * F(\phi, k) = \int_0^\phi \frac1{\sqrt{1-k^2\sin^2\theta}}\,d\theta .
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real F(real phi) const throw(); Math::real F(real phi) const;
/** /**
* The incomplete integral of the second kind. * The incomplete integral of the second kind.
* *
* @param[in] phi * @param[in] phi
* @return \e E(&phi;, \e k). * @return \e E(&phi;, \e k).
* *
* \e E(&phi;, \e k) is defined in http://dlmf.nist.gov/19.2.E5 * \e E(&phi;, \e k) is defined in http://dlmf.nist.gov/19.2.E5
* \f[ * \f[
* E(\phi, k) = \int_0^\phi \sqrt{1-k^2\sin^2\theta}\,d\theta. * E(\phi, k) = \int_0^\phi \sqrt{1-k^2\sin^2\theta}\,d\theta.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real E(real phi) const throw(); Math::real E(real phi) const;
/** /**
* The incomplete integral of the second kind with the argument given i n * The incomplete integral of the second kind with the argument given i n
* degrees. * degrees.
* *
* @param[in] ang in <i>degrees</i>. * @param[in] ang in <i>degrees</i>.
* @return \e E(&pi; <i>ang</i>/180, \e k). * @return \e E(&pi; <i>ang</i>/180, \e k).
********************************************************************** / ********************************************************************** /
Math::real Ed(real ang) const throw(); Math::real Ed(real ang) const;
/** /**
* The inverse of the incomplete integral of the second kind. * The inverse of the incomplete integral of the second kind.
* *
* @param[in] x * @param[in] x
* @return &phi; = <i>E</i><sup>&minus;1</sup>(\e x, \e k); i.e., the * @return &phi; = <i>E</i><sup>&minus;1</sup>(\e x, \e k); i.e., the
* solution of such that \e E(&phi;, \e k) = \e x. * solution of such that \e E(&phi;, \e k) = \e x.
********************************************************************** / ********************************************************************** /
Math::real Einv(real x) const throw(); Math::real Einv(real x) const;
/** /**
* The incomplete integral of the third kind. * The incomplete integral of the third kind.
* *
* @param[in] phi * @param[in] phi
* @return &Pi;(&phi;, &alpha;<sup>2</sup>, \e k). * @return &Pi;(&phi;, &alpha;<sup>2</sup>, \e k).
* *
* &Pi;(&phi;, &alpha;<sup>2</sup>, \e k) is defined in * &Pi;(&phi;, &alpha;<sup>2</sup>, \e k) is defined in
* http://dlmf.nist.gov/19.2.E7 * http://dlmf.nist.gov/19.2.E7
* \f[ * \f[
* \Pi(\phi, \alpha^2, k) = \int_0^\phi * \Pi(\phi, \alpha^2, k) = \int_0^\phi
* \frac1{\sqrt{1-k^2\sin^2\theta}(1 - \alpha^2\sin^2\theta_)}\,d\t heta. * \frac1{\sqrt{1-k^2\sin^2\theta}(1 - \alpha^2\sin^2\theta_)}\,d\t heta.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real Pi(real phi) const throw(); Math::real Pi(real phi) const;
/** /**
* Jahnke's incomplete elliptic integral. * Jahnke's incomplete elliptic integral.
* *
* @param[in] phi * @param[in] phi
* @return \e D(&phi;, \e k). * @return \e D(&phi;, \e k).
* *
* \e D(&phi;, \e k) is defined in http://dlmf.nist.gov/19.2.E4 * \e D(&phi;, \e k) is defined in http://dlmf.nist.gov/19.2.E4
* \f[ * \f[
* D(\phi, k) = \int_0^\phi * D(\phi, k) = \int_0^\phi
* \frac{\sin^2\theta}{\sqrt{1-k^2\sin^2\theta}}\,d\theta. * \frac{\sin^2\theta}{\sqrt{1-k^2\sin^2\theta}}\,d\theta.
* \f] * \f]
********************************************************************** / ********************************************************************** /
Math::real D(real phi) const throw(); Math::real D(real phi) const;
/** /**
* Legendre's geodesic longitude integral. * Legendre's geodesic longitude integral.
* *
* @param[in] phi * @param[in] phi
* @return \e G(&phi;, &alpha;<sup>2</sup>, \e k). * @return \e G(&phi;, &alpha;<sup>2</sup>, \e k).
* *
* \e G(&phi;, &alpha;<sup>2</sup>, \e k) is defined by * \e G(&phi;, &alpha;<sup>2</sup>, \e k) is defined by
* \f[ * \f[
* \begin{aligned} * \begin{aligned}
skipping to change at line 382 skipping to change at line 382
* \f] * \f]
* *
* Legendre expresses the longitude of a point on the geodesic in terms of * Legendre expresses the longitude of a point on the geodesic in terms of
* this combination of elliptic integrals in Exercices de Calcul * this combination of elliptic integrals in Exercices de Calcul
* Int&eacute;gral, Vol. 1 (1811), p. 181, * Int&eacute;gral, Vol. 1 (1811), p. 181,
* http://books.google.com/books?id=riIOAAAAQAAJ&pg=PA181. * http://books.google.com/books?id=riIOAAAAQAAJ&pg=PA181.
* *
* See \ref geodellip for the expression for the longitude in terms of this * See \ref geodellip for the expression for the longitude in terms of this
* function. * function.
********************************************************************** / ********************************************************************** /
Math::real G(real phi) const throw(); Math::real G(real phi) const;
/** /**
* Cayley's geodesic longitude difference integral. * Cayley's geodesic longitude difference integral.
* *
* @param[in] phi * @param[in] phi
* @return \e H(&phi;, &alpha;<sup>2</sup>, \e k). * @return \e H(&phi;, &alpha;<sup>2</sup>, \e k).
* *
* \e H(&phi;, &alpha;<sup>2</sup>, \e k) is defined by * \e H(&phi;, &alpha;<sup>2</sup>, \e k) is defined by
* \f[ * \f[
* \begin{aligned} * \begin{aligned}
skipping to change at line 409 skipping to change at line 409
* \end{aligned} * \end{aligned}
* \f] * \f]
* *
* Cayley expresses the longitude difference of a point on the geodesic in * Cayley expresses the longitude difference of a point on the geodesic in
* terms of this combination of elliptic integrals in Phil. Mag. <b>40< /b> * terms of this combination of elliptic integrals in Phil. Mag. <b>40< /b>
* (1870), p. 333, http://books.google.com/books?id=Zk0wAAAAIAAJ&pg=PA3 33. * (1870), p. 333, http://books.google.com/books?id=Zk0wAAAAIAAJ&pg=PA3 33.
* *
* See \ref geodellip for the expression for the longitude in terms of this * See \ref geodellip for the expression for the longitude in terms of this
* function. * function.
********************************************************************** / ********************************************************************** /
Math::real H(real phi) const throw(); Math::real H(real phi) const;
///@} ///@}
/** \name Incomplete integrals in terms of Jacobi elliptic functions. /** \name Incomplete integrals in terms of Jacobi elliptic functions.
********************************************************************** / ********************************************************************** /
/** /**
* The incomplete integral of the first kind in terms of Jacobi ellipti c * The incomplete integral of the first kind in terms of Jacobi ellipti c
* functions. * functions.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return \e F(&phi;, \e k) as though &phi; &isin; (&minus;&pi;, &pi;] . * @return \e F(&phi;, \e k) as though &phi; &isin; (&minus;&pi;, &pi;] .
********************************************************************** / ********************************************************************** /
Math::real F(real sn, real cn, real dn) const throw(); Math::real F(real sn, real cn, real dn) const;
/** /**
* The incomplete integral of the second kind in terms of Jacobi ellipt ic * The incomplete integral of the second kind in terms of Jacobi ellipt ic
* functions. * functions.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return \e E(&phi;, \e k) as though &phi; &isin; (&minus;&pi;, &pi;] . * @return \e E(&phi;, \e k) as though &phi; &isin; (&minus;&pi;, &pi;] .
********************************************************************** / ********************************************************************** /
Math::real E(real sn, real cn, real dn) const throw(); Math::real E(real sn, real cn, real dn) const;
/** /**
* The incomplete integral of the third kind in terms of Jacobi ellipti c * The incomplete integral of the third kind in terms of Jacobi ellipti c
* functions. * functions.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return &Pi;(&phi;, &alpha;<sup>2</sup>, \e k) as though &phi; &isin ; * @return &Pi;(&phi;, &alpha;<sup>2</sup>, \e k) as though &phi; &isin ;
* (&minus;&pi;, &pi;]. * (&minus;&pi;, &pi;].
********************************************************************** / ********************************************************************** /
Math::real Pi(real sn, real cn, real dn) const throw(); Math::real Pi(real sn, real cn, real dn) const;
/** /**
* Jahnke's incomplete elliptic integral in terms of Jacobi elliptic * Jahnke's incomplete elliptic integral in terms of Jacobi elliptic
* functions. * functions.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return \e D(&phi;, \e k) as though &phi; &isin; (&minus;&pi;, &pi;] . * @return \e D(&phi;, \e k) as though &phi; &isin; (&minus;&pi;, &pi;] .
********************************************************************** / ********************************************************************** /
Math::real D(real sn, real cn, real dn) const throw(); Math::real D(real sn, real cn, real dn) const;
/** /**
* Legendre's geodesic longitude integral in terms of Jacobi elliptic * Legendre's geodesic longitude integral in terms of Jacobi elliptic
* functions. * functions.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return \e G(&phi;, &alpha;<sup>2</sup>, \e k) as though &phi; &isin ; * @return \e G(&phi;, &alpha;<sup>2</sup>, \e k) as though &phi; &isin ;
* (&minus;&pi;, &pi;]. * (&minus;&pi;, &pi;].
********************************************************************** / ********************************************************************** /
Math::real G(real sn, real cn, real dn) const throw(); Math::real G(real sn, real cn, real dn) const;
/** /**
* Cayley's geodesic longitude difference integral in terms of Jacobi * Cayley's geodesic longitude difference integral in terms of Jacobi
* elliptic functions. * elliptic functions.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return \e H(&phi;, &alpha;<sup>2</sup>, \e k) as though &phi; &isin ; * @return \e H(&phi;, &alpha;<sup>2</sup>, \e k) as though &phi; &isin ;
* (&minus;&pi;, &pi;]. * (&minus;&pi;, &pi;].
********************************************************************** / ********************************************************************** /
Math::real H(real sn, real cn, real dn) const throw(); Math::real H(real sn, real cn, real dn) const;
///@} ///@}
/** \name Periodic versions of incomplete elliptic integrals. /** \name Periodic versions of incomplete elliptic integrals.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* The periodic incomplete integral of the first kind. * The periodic incomplete integral of the first kind.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return the periodic function &pi; \e F(&phi;, \e k) / (2 \e K(\e k) ) - * @return the periodic function &pi; \e F(&phi;, \e k) / (2 \e K(\e k) ) -
* &phi; * &phi;
********************************************************************** / ********************************************************************** /
Math::real deltaF(real sn, real cn, real dn) const throw(); Math::real deltaF(real sn, real cn, real dn) const;
/** /**
* The periodic incomplete integral of the second kind. * The periodic incomplete integral of the second kind.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return the periodic function &pi; \e E(&phi;, \e k) / (2 \e E(\e k) ) - * @return the periodic function &pi; \e E(&phi;, \e k) / (2 \e E(\e k) ) -
* &phi; * &phi;
********************************************************************** / ********************************************************************** /
Math::real deltaE(real sn, real cn, real dn) const throw(); Math::real deltaE(real sn, real cn, real dn) const;
/** /**
* The periodic inverse of the incomplete integral of the second kind. * The periodic inverse of the incomplete integral of the second kind.
* *
* @param[in] stau = sin&tau; * @param[in] stau = sin&tau;
* @param[in] ctau = sin&tau; * @param[in] ctau = sin&tau;
* @return the periodic function <i>E</i><sup>&minus;1</sup>(&tau; (2 \ e * @return the periodic function <i>E</i><sup>&minus;1</sup>(&tau; (2 \ e
* E(\e k)/&pi;), \e k) - &tau; * E(\e k)/&pi;), \e k) - &tau;
********************************************************************** / ********************************************************************** /
Math::real deltaEinv(real stau, real ctau) const throw(); Math::real deltaEinv(real stau, real ctau) const;
/** /**
* The periodic incomplete integral of the third kind. * The periodic incomplete integral of the third kind.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return the periodic function &pi; &Pi;(&phi;, \e k) / (2 &Pi;(\e k) ) - * @return the periodic function &pi; &Pi;(&phi;, \e k) / (2 &Pi;(\e k) ) -
* &phi; * &phi;
********************************************************************** / ********************************************************************** /
Math::real deltaPi(real sn, real cn, real dn) const throw(); Math::real deltaPi(real sn, real cn, real dn) const;
/** /**
* The periodic Jahnke's incomplete elliptic integral. * The periodic Jahnke's incomplete elliptic integral.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return the periodic function &pi; \e D(&phi;, \e k) / (2 \e D(\e k) ) - * @return the periodic function &pi; \e D(&phi;, \e k) / (2 \e D(\e k) ) -
* &phi; * &phi;
********************************************************************** / ********************************************************************** /
Math::real deltaD(real sn, real cn, real dn) const throw(); Math::real deltaD(real sn, real cn, real dn) const;
/** /**
* Legendre's periodic geodesic longitude integral. * Legendre's periodic geodesic longitude integral.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return the periodic function &pi; \e G(&phi;, \e k) / (2 \e G(\e k) ) - * @return the periodic function &pi; \e G(&phi;, \e k) / (2 \e G(\e k) ) -
* &phi; * &phi;
********************************************************************** / ********************************************************************** /
Math::real deltaG(real sn, real cn, real dn) const throw(); Math::real deltaG(real sn, real cn, real dn) const;
/** /**
* Cayley's periodic geodesic longitude difference integral. * Cayley's periodic geodesic longitude difference integral.
* *
* @param[in] sn = sin&phi; * @param[in] sn = sin&phi;
* @param[in] cn = cos&phi; * @param[in] cn = cos&phi;
* @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup> * @param[in] dn = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
* @return the periodic function &pi; \e H(&phi;, \e k) / (2 \e H(\e k) ) - * @return the periodic function &pi; \e H(&phi;, \e k) / (2 \e H(\e k) ) -
* &phi; * &phi;
********************************************************************** / ********************************************************************** /
Math::real deltaH(real sn, real cn, real dn) const throw(); Math::real deltaH(real sn, real cn, real dn) const;
///@} ///@}
/** \name Elliptic functions. /** \name Elliptic functions.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* The Jacobi elliptic functions. * The Jacobi elliptic functions.
* *
* @param[in] x the argument. * @param[in] x the argument.
* @param[out] sn sn(\e x, \e k). * @param[out] sn sn(\e x, \e k).
* @param[out] cn cn(\e x, \e k). * @param[out] cn cn(\e x, \e k).
* @param[out] dn dn(\e x, \e k). * @param[out] dn dn(\e x, \e k).
********************************************************************** / ********************************************************************** /
void sncndn(real x, real& sn, real& cn, real& dn) const throw(); void sncndn(real x, real& sn, real& cn, real& dn) const;
/** /**
* The &Delta; amplitude function. * The &Delta; amplitude function.
* *
* @param[in] sn sin&phi; * @param[in] sn sin&phi;
* @param[in] cn cos&phi; * @param[in] cn cos&phi;
* @return &Delta; = sqrt(1 &minus; <i>k</i><sup>2</sup> * @return &Delta; = sqrt(1 &minus; <i>k</i><sup>2</sup>
* sin<sup>2</sup>&phi;) * sin<sup>2</sup>&phi;)
********************************************************************** / ********************************************************************** /
Math::real Delta(real sn, real cn) const throw() Math::real Delta(real sn, real cn) const
{ return std::sqrt(_k2 < 0 ? 1 - _k2 * sn*sn : _kp2 + _k2 * cn*cn); } { return std::sqrt(_k2 < 0 ? 1 - _k2 * sn*sn : _kp2 + _k2 * cn*cn); }
///@} ///@}
/** \name Symmetric elliptic integrals. /** \name Symmetric elliptic integrals.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Symmetric integral of the first kind <i>R<sub>F</sub></i>. * Symmetric integral of the first kind <i>R<sub>F</sub></i>.
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @param[in] z * @param[in] z
* @return <i>R<sub>F</sub></i>(\e x, \e y, \e z) * @return <i>R<sub>F</sub></i>(\e x, \e y, \e z)
* *
* <i>R<sub>F</sub></i> is defined in http://dlmf.nist.gov/19.16.E1 * <i>R<sub>F</sub></i> is defined in http://dlmf.nist.gov/19.16.E1
* \f[ R_F(x, y, z) = \frac12 * \f[ R_F(x, y, z) = \frac12
* \int_0^\infty\frac1{\sqrt{(t + x) (t + y) (t + z)}}\, dt \f] * \int_0^\infty\frac1{\sqrt{(t + x) (t + y) (t + z)}}\, dt \f]
* If one of the arguments is zero, it is more efficient to call the * If one of the arguments is zero, it is more efficient to call the
* two-argument version of this function with the non-zero arguments. * two-argument version of this function with the non-zero arguments.
********************************************************************** / ********************************************************************** /
static real RF(real x, real y, real z) throw(); static real RF(real x, real y, real z);
/** /**
* Complete symmetric integral of the first kind, <i>R<sub>F</sub></i> with * Complete symmetric integral of the first kind, <i>R<sub>F</sub></i> with
* one argument zero. * one argument zero.
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @return <i>R<sub>F</sub></i>(\e x, \e y, 0) * @return <i>R<sub>F</sub></i>(\e x, \e y, 0)
********************************************************************** / ********************************************************************** /
static real RF(real x, real y) throw(); static real RF(real x, real y);
/** /**
* Degenerate symmetric integral of the first kind <i>R<sub>C</sub></i> . * Degenerate symmetric integral of the first kind <i>R<sub>C</sub></i> .
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @return <i>R<sub>C</sub></i>(\e x, \e y) = <i>R<sub>F</sub></i>(\e x , \e * @return <i>R<sub>C</sub></i>(\e x, \e y) = <i>R<sub>F</sub></i>(\e x , \e
* y, \e y) * y, \e y)
* *
* <i>R<sub>C</sub></i> is defined in http://dlmf.nist.gov/19.2.E17 * <i>R<sub>C</sub></i> is defined in http://dlmf.nist.gov/19.2.E17
* \f[ R_C(x, y) = \frac12 * \f[ R_C(x, y) = \frac12
* \int_0^\infty\frac1{\sqrt{t + x}(t + y)}\,dt \f] * \int_0^\infty\frac1{\sqrt{t + x}(t + y)}\,dt \f]
********************************************************************** / ********************************************************************** /
static real RC(real x, real y) throw(); static real RC(real x, real y);
/** /**
* Symmetric integral of the second kind <i>R<sub>G</sub></i>. * Symmetric integral of the second kind <i>R<sub>G</sub></i>.
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @param[in] z * @param[in] z
* @return <i>R<sub>G</sub></i>(\e x, \e y, \e z) * @return <i>R<sub>G</sub></i>(\e x, \e y, \e z)
* *
* <i>R<sub>G</sub></i> is defined in Carlson, eq 1.5 * <i>R<sub>G</sub></i> is defined in Carlson, eq 1.5
* \f[ R_G(x, y, z) = \frac14 * \f[ R_G(x, y, z) = \frac14
* \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2}
* \biggl( * \biggl(
* \frac x{t + x} + \frac y{t + y} + \frac z{t + z} * \frac x{t + x} + \frac y{t + y} + \frac z{t + z}
* \biggr)t\,dt \f] * \biggr)t\,dt \f]
* See also http://dlmf.nist.gov/19.16.E3. * See also http://dlmf.nist.gov/19.16.E3.
* If one of the arguments is zero, it is more efficient to call the * If one of the arguments is zero, it is more efficient to call the
* two-argument version of this function with the non-zero arguments. * two-argument version of this function with the non-zero arguments.
********************************************************************** / ********************************************************************** /
static real RG(real x, real y, real z) throw(); static real RG(real x, real y, real z);
/** /**
* Complete symmetric integral of the second kind, <i>R<sub>G</sub></i> * Complete symmetric integral of the second kind, <i>R<sub>G</sub></i>
* with one argument zero. * with one argument zero.
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @return <i>R<sub>G</sub></i>(\e x, \e y, 0) * @return <i>R<sub>G</sub></i>(\e x, \e y, 0)
********************************************************************** / ********************************************************************** /
static real RG(real x, real y) throw(); static real RG(real x, real y);
/** /**
* Symmetric integral of the third kind <i>R<sub>J</sub></i>. * Symmetric integral of the third kind <i>R<sub>J</sub></i>.
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @param[in] z * @param[in] z
* @param[in] p * @param[in] p
* @return <i>R<sub>J</sub></i>(\e x, \e y, \e z, \e p) * @return <i>R<sub>J</sub></i>(\e x, \e y, \e z, \e p)
* *
* <i>R<sub>J</sub></i> is defined in http://dlmf.nist.gov/19.16.E2 * <i>R<sub>J</sub></i> is defined in http://dlmf.nist.gov/19.16.E2
* \f[ R_J(x, y, z, p) = \frac32 * \f[ R_J(x, y, z, p) = \frac32
* \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} (t + p)^{-1}\, d t \f] * \int_0^\infty[(t + x) (t + y) (t + z)]^{-1/2} (t + p)^{-1}\, d t \f]
********************************************************************** / ********************************************************************** /
static real RJ(real x, real y, real z, real p) throw(); static real RJ(real x, real y, real z, real p);
/** /**
* Degenerate symmetric integral of the third kind <i>R<sub>D</sub></i> . * Degenerate symmetric integral of the third kind <i>R<sub>D</sub></i> .
* *
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @param[in] z * @param[in] z
* @return <i>R<sub>D</sub></i>(\e x, \e y, \e z) = <i>R<sub>J</sub></i >(\e * @return <i>R<sub>D</sub></i>(\e x, \e y, \e z) = <i>R<sub>J</sub></i >(\e
* x, \e y, \e z, \e z) * x, \e y, \e z, \e z)
* *
* <i>R<sub>D</sub></i> is defined in http://dlmf.nist.gov/19.16.E5 * <i>R<sub>D</sub></i> is defined in http://dlmf.nist.gov/19.16.E5
* \f[ R_D(x, y, z) = \frac32 * \f[ R_D(x, y, z) = \frac32
* \int_0^\infty[(t + x) (t + y)]^{-1/2} (t + z)^{-3/2}\, dt \f] * \int_0^\infty[(t + x) (t + y)]^{-1/2} (t + z)^{-3/2}\, dt \f]
********************************************************************** / ********************************************************************** /
static real RD(real x, real y, real z) throw(); static real RD(real x, real y, real z);
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP #endif // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP
 End of changes. 48 change blocks. 
48 lines changed or deleted 48 lines changed or added


 GeoCoords.hpp   GeoCoords.hpp 
skipping to change at line 58 skipping to change at line 58
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT GeoCoords { class GEOGRAPHICLIB_EXPORT GeoCoords {
private: private:
typedef Math::real real; typedef Math::real real;
real _lat, _long, _easting, _northing, _gamma, _k; real _lat, _long, _easting, _northing, _gamma, _k;
bool _northp; bool _northp;
int _zone; // See UTMUPS::zonespec int _zone; // See UTMUPS::zonespec
mutable real _alt_easting, _alt_northing, _alt_gamma, _alt_k; mutable real _alt_easting, _alt_northing, _alt_gamma, _alt_k;
mutable int _alt_zone; mutable int _alt_zone;
void CopyToAlt() const throw() { void CopyToAlt() const {
_alt_easting = _easting; _alt_easting = _easting;
_alt_northing = _northing; _alt_northing = _northing;
_alt_gamma = _gamma; _alt_gamma = _gamma;
_alt_k = _k; _alt_k = _k;
_alt_zone = _zone; _alt_zone = _zone;
} }
static void UTMUPSString(int zone, bool northp, real easting, real nort hing, static void UTMUPSString(int zone, bool northp, real easting, real nort hing,
int prec, std::string& utm); int prec, bool abbrev, std::string& utm);
void FixHemisphere(); void FixHemisphere();
public: public:
/** \name Initializing the GeoCoords object /** \name Initializing the GeoCoords object
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* The default constructor is equivalent to \e latitude = 90&deg;, * The default constructor is equivalent to \e latitude = 90&deg;,
* \e longitude = 0&deg;. * \e longitude = 0&deg;.
********************************************************************** / ********************************************************************** /
GeoCoords() throw() GeoCoords()
// This is the N pole // This is the N pole
: _lat(90) : _lat(90)
, _long(0) , _long(0)
, _easting(2000000) , _easting(2000000)
, _northing(2000000) , _northing(2000000)
, _northp(true) , _northp(true)
, _zone(0) , _zone(0)
{ CopyToAlt(); } { CopyToAlt(); }
/** /**
skipping to change at line 117 skipping to change at line 117
* - 33.44 43.27 * - 33.44 43.27
* - N33d26.4' E43d16.2' * - N33d26.4' E43d16.2'
* - 43d16'12&quot;E 33d26'24&quot;N * - 43d16'12&quot;E 33d26'24&quot;N
* - 43:16:12E 33:26:24 * - 43:16:12E 33:26:24
* - MGRS * - MGRS
* - 38SLC301 * - 38SLC301
* - 38SLC391014 * - 38SLC391014
* - 38SLC3918701405 * - 38SLC3918701405
* - 37SHT9708 * - 37SHT9708
* - UTM * - UTM
* - 38N 339188 3701405 * - 38n 339188 3701405
* - 897039 3708229 37N * - 897039 3708229 37n
* *
* <b>Latitude and Longitude parsing</b>: Latitude precedes longitude, * <b>Latitude and Longitude parsing</b>: Latitude precedes longitude,
* unless a N, S, E, W hemisphere designator is used on one or both * unless a N, S, E, W hemisphere designator is used on one or both
* coordinates. If \e swaplatlong = true (default is false), then * coordinates. If \e swaplatlong = true (default is false), then
* longitude precedes latitude in the absence of a hemisphere designato r. * longitude precedes latitude in the absence of a hemisphere designato r.
* Thus (with \e swaplatlong = false) * Thus (with \e swaplatlong = false)
* - 40 -75 * - 40 -75
* - N40 W75 * - N40 W75
* - -75 N40 * - -75 N40
* - 75W 40N * - 75W 40N
skipping to change at line 154 skipping to change at line 154
* - 40.508333333 * - 40.508333333
* . * .
* all specify the same angle. The leading sign applies to all compone nts * all specify the same angle. The leading sign applies to all compone nts
* so -1d30 is -(1+30/60) = -1.5. Latitudes must be in the range * so -1d30 is -(1+30/60) = -1.5. Latitudes must be in the range
* [&minus;90&deg;, 90&deg;] and longitudes in the range * [&minus;90&deg;, 90&deg;] and longitudes in the range
* [&minus;540&deg;, 540&deg;). Internally longitudes are reduced * [&minus;540&deg;, 540&deg;). Internally longitudes are reduced
* to the range [&minus;180&deg;, 180&deg;). * to the range [&minus;180&deg;, 180&deg;).
* *
* <b>UTM/UPS parsing</b>: For UTM zones (&minus;80&deg; &le; Lat < * <b>UTM/UPS parsing</b>: For UTM zones (&minus;80&deg; &le; Lat <
* 84&deg;), the zone designator is made up of a zone number (for 1 to 60) * 84&deg;), the zone designator is made up of a zone number (for 1 to 60)
* and a hemisphere letter (N or S), e.g., 38N. The latitude zone desi * and a hemisphere letter (n or s), e.g., 38n (38north can also be use
gner d).
* ([C--M] in the southern hemisphere and [N--X] in the northern) shoul * The latitude band designer ([C--M] in the southern hemisphere and [N
d --X]
* NOT be used. (This is part of the MGRS coordinate.) The zone * in the northern) should NOT be used. (This is part of the MGRS
* designator for the poles (where UPS is employed) is a hemisphere let * coordinate.) The zone designator for the poles (where UPS is employ
ter ed)
* by itself, i.e., N or S. * is a hemisphere letter by itself, i.e., n or s (north or south can a
lso
* be used).
* *
* <b>MGRS parsing</b> interprets the grid references as square area at the * <b>MGRS parsing</b> interprets the grid references as square area at the
* specified precision (1m, 10m, 100m, etc.). If \e centerp = true (th e * specified precision (1m, 10m, 100m, etc.). If \e centerp = true (th e
* default), the center of this square is then taken to be the precise * default), the center of this square is then taken to be the precise
* position; thus: * position; thus:
* - 38SMB = 38N 450000 3650000 * - 38SMB = 38n 450000 3650000
* - 38SMB4484 = 38N 444500 3684500 * - 38SMB4484 = 38n 444500 3684500
* - 38SMB44148470 = 38N 444145 3684705 * - 38SMB44148470 = 38n 444145 3684705
* . * .
* Otherwise, the "south-west" corner of the square is used, i.e., * Otherwise, the "south-west" corner of the square is used, i.e.,
* - 38SMB = 38N 400000 3600000 * - 38SMB = 38n 400000 3600000
* - 38SMB4484 = 38N 444000 3684000 * - 38SMB4484 = 38n 444000 3684000
* - 38SMB44148470 = 38N 444140 3684700 * - 38SMB44148470 = 38n 444140 3684700
********************************************************************** / ********************************************************************** /
explicit GeoCoords(const std::string& s, explicit GeoCoords(const std::string& s,
bool centerp = true, bool swaplatlong = false) bool centerp = true, bool swaplatlong = false)
{ Reset(s, centerp, swaplatlong); } { Reset(s, centerp, swaplatlong); }
/** /**
* Construct from geographic coordinates. * Construct from geographic coordinates.
* *
* @param[in] latitude (degrees). * @param[in] latitude (degrees).
* @param[in] longitude (degrees). * @param[in] longitude (degrees).
skipping to change at line 276 skipping to change at line 277
CopyToAlt(); CopyToAlt();
} }
///@} ///@}
/** \name Querying the GeoCoords object /** \name Querying the GeoCoords object
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return latitude (degrees) * @return latitude (degrees)
********************************************************************** / ********************************************************************** /
Math::real Latitude() const throw() { return _lat; } Math::real Latitude() const { return _lat; }
/** /**
* @return longitude (degrees) * @return longitude (degrees)
********************************************************************** / ********************************************************************** /
Math::real Longitude() const throw() { return _long; } Math::real Longitude() const { return _long; }
/** /**
* @return easting (meters) * @return easting (meters)
********************************************************************** / ********************************************************************** /
Math::real Easting() const throw() { return _easting; } Math::real Easting() const { return _easting; }
/** /**
* @return northing (meters) * @return northing (meters)
********************************************************************** / ********************************************************************** /
Math::real Northing() const throw() { return _northing; } Math::real Northing() const { return _northing; }
/** /**
* @return meridian convergence (degrees) for the UTM/UPS projection. * @return meridian convergence (degrees) for the UTM/UPS projection.
********************************************************************** / ********************************************************************** /
Math::real Convergence() const throw() { return _gamma; } Math::real Convergence() const { return _gamma; }
/** /**
* @return scale for the UTM/UPS projection. * @return scale for the UTM/UPS projection.
********************************************************************** / ********************************************************************** /
Math::real Scale() const throw() { return _k; } Math::real Scale() const { return _k; }
/** /**
* @return hemisphere (false means south, true means north). * @return hemisphere (false means south, true means north).
********************************************************************** / ********************************************************************** /
bool Northp() const throw() { return _northp; } bool Northp() const { return _northp; }
/** /**
* @return hemisphere letter N or S. * @return hemisphere letter n or s.
********************************************************************** / ********************************************************************** /
char Hemisphere() const throw() { return _northp ? 'N' : 'S'; } char Hemisphere() const { return _northp ? 'n' : 's'; }
/** /**
* @return the zone corresponding to the input (return 0 for UPS). * @return the zone corresponding to the input (return 0 for UPS).
********************************************************************** / ********************************************************************** /
int Zone() const throw() { return _zone; } int Zone() const { return _zone; }
///@} ///@}
/** \name Setting and querying the alternate zone /** \name Setting and querying the alternate zone
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Specify alternate zone number. * Specify alternate zone number.
* *
* @param[in] zone zone number for the alternate representation. * @param[in] zone zone number for the alternate representation.
skipping to change at line 353 skipping to change at line 354
UTMUPS::Forward(_lat, _long, UTMUPS::Forward(_lat, _long,
_alt_zone, northp, _alt_zone, northp,
_alt_easting, _alt_northing, _alt_gamma, _alt_k, _alt_easting, _alt_northing, _alt_gamma, _alt_k,
zone); zone);
} }
} }
/** /**
* @return current alternate zone (return 0 for UPS). * @return current alternate zone (return 0 for UPS).
********************************************************************** / ********************************************************************** /
int AltZone() const throw() { return _alt_zone; } int AltZone() const { return _alt_zone; }
/** /**
* @return easting (meters) for alternate zone. * @return easting (meters) for alternate zone.
********************************************************************** / ********************************************************************** /
Math::real AltEasting() const throw() { return _alt_easting; } Math::real AltEasting() const { return _alt_easting; }
/** /**
* @return northing (meters) for alternate zone. * @return northing (meters) for alternate zone.
********************************************************************** / ********************************************************************** /
Math::real AltNorthing() const throw() { return _alt_northing; } Math::real AltNorthing() const { return _alt_northing; }
/** /**
* @return meridian convergence (degrees) for alternate zone. * @return meridian convergence (degrees) for alternate zone.
********************************************************************** / ********************************************************************** /
Math::real AltConvergence() const throw() { return _alt_gamma; } Math::real AltConvergence() const { return _alt_gamma; }
/** /**
* @return scale for alternate zone. * @return scale for alternate zone.
********************************************************************** / ********************************************************************** /
Math::real AltScale() const throw() { return _alt_k; } Math::real AltScale() const { return _alt_k; }
///@} ///@}
/** \name String representations of the GeoCoords object /** \name String representations of the GeoCoords object
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* String representation with latitude and longitude as signed decimal * String representation with latitude and longitude as signed decimal
* degrees. * degrees.
* *
* @param[in] prec precision (relative to about 1m). * @param[in] prec precision (relative to about 1m).
skipping to change at line 429 skipping to change at line 430
const; const;
/** /**
* MGRS string. * MGRS string.
* *
* @param[in] prec precision (relative to about 1m). * @param[in] prec precision (relative to about 1m).
* @exception std::bad_alloc if memory for the string can't be allocate d. * @exception std::bad_alloc if memory for the string can't be allocate d.
* @return MGRS string. * @return MGRS string.
* *
* This gives the coordinates of the enclosing grid square with size gi ven * This gives the coordinates of the enclosing grid square with size gi ven
* by the precision. Thus 38N 444180 3684790 converted to a MGRS * by the precision. Thus 38n 444180 3684790 converted to a MGRS
* coordinate at precision &minus;2 (100m) is 38SMB441847 and not * coordinate at precision &minus;2 (100m) is 38SMB441847 and not
* 38SMB442848. \e prec specifies the precision of the MGRS string as * 38SMB442848. \e prec specifies the precision of the MGRS string as
* follows: * follows:
* - prec = &minus;5 (min), 100km * - prec = &minus;5 (min), 100km
* - prec = &minus;4, 10km * - prec = &minus;4, 10km
* - prec = &minus;3, 1km * - prec = &minus;3, 1km
* - prec = &minus;2, 100m * - prec = &minus;2, 100m
* - prec = &minus;1, 10m * - prec = &minus;1, 10m
* - prec = 0, 1m * - prec = 0, 1m
* - prec = 1, 0.1m * - prec = 1, 0.1m
* - prec = 6 (max), 1&mu;m * - prec = 6 (max), 1&mu;m
********************************************************************** / ********************************************************************** /
std::string MGRSRepresentation(int prec = 0) const; std::string MGRSRepresentation(int prec = 0) const;
/** /**
* UTM/UPS string. * UTM/UPS string.
* *
* @param[in] prec precision (relative to about 1m) * @param[in] prec precision (relative to about 1m)
* @param[in] abbrev if true (the default) use abbreviated (n/s) notati
on
* for hemisphere; otherwise spell out the hemisphere (north/south)
* @exception std::bad_alloc if memory for the string can't be allocate d. * @exception std::bad_alloc if memory for the string can't be allocate d.
* @return UTM/UPS string representation: zone designator, easting, and * @return UTM/UPS string representation: zone designator, easting, and
* northing. * northing.
* *
* Precision specifies accuracy of representation as follows: * Precision specifies accuracy of representation as follows:
* - prec = &minus;5 (min), 100km * - prec = &minus;5 (min), 100km
* - prec = &minus;3, 1km * - prec = &minus;3, 1km
* - prec = 0, 1m * - prec = 0, 1m
* - prec = 3, 1mm * - prec = 3, 1mm
* - prec = 6, 1&mu;m * - prec = 6, 1&mu;m
* - prec = 9 (max), 1nm * - prec = 9 (max), 1nm
********************************************************************** / ********************************************************************** /
std::string UTMUPSRepresentation(int prec = 0) const; std::string UTMUPSRepresentation(int prec = 0, bool abbrev = true) cons t;
/** /**
* UTM/UPS string with hemisphere override. * UTM/UPS string with hemisphere override.
* *
* @param[in] prec precision (relative to about 1m)
* @param[in] northp hemisphere override * @param[in] northp hemisphere override
* @param[in] prec precision (relative to about 1m)
* @param[in] abbrev if true (the default) use abbreviated (n/s) notati
on
* for hemisphere; otherwise spell out the hemisphere (north/south)
* @exception GeographicErr if the hemisphere override attempts to chan ge * @exception GeographicErr if the hemisphere override attempts to chan ge
* UPS N to UPS S or vice verse. * UPS N to UPS S or vice versa.
* @exception std::bad_alloc if memory for the string can't be allocate d. * @exception std::bad_alloc if memory for the string can't be allocate d.
* @return UTM/UPS string representation: zone designator, easting, and * @return UTM/UPS string representation: zone designator, easting, and
* northing. * northing.
********************************************************************** / ********************************************************************** /
std::string UTMUPSRepresentation(bool northp, int prec = 0) const; std::string UTMUPSRepresentation(bool northp, int prec = 0,
bool abbrev = true) const;
/** /**
* MGRS string for the alternate zone. See GeoCoords::MGRSRepresentati on. * MGRS string for the alternate zone. See GeoCoords::MGRSRepresentati on.
* *
* @param[in] prec precision (relative to about 1m). * @param[in] prec precision (relative to about 1m).
* @exception std::bad_alloc if memory for the string can't be allocate d. * @exception std::bad_alloc if memory for the string can't be allocate d.
* @return MGRS string. * @return MGRS string.
********************************************************************** / ********************************************************************** /
std::string AltMGRSRepresentation(int prec = 0) const; std::string AltMGRSRepresentation(int prec = 0) const;
/** /**
* UTM/UPS string for the alternate zone. See * UTM/UPS string for the alternate zone. See
* GeoCoords::UTMUPSRepresentation. * GeoCoords::UTMUPSRepresentation.
* *
* @param[in] prec precision (relative to about 1m) * @param[in] prec precision (relative to about 1m)
* @param[in] abbrev if true (the default) use abbreviated (n/s) notati
on
* for hemisphere; otherwise spell out the hemisphere (north/south)
* @exception std::bad_alloc if memory for the string can't be allocate d. * @exception std::bad_alloc if memory for the string can't be allocate d.
* @return UTM/UPS string representation: zone designator, easting, and * @return UTM/UPS string representation: zone designator, easting, and
* northing. * northing.
********************************************************************** / ********************************************************************** /
std::string AltUTMUPSRepresentation(int prec = 0) const; std::string AltUTMUPSRepresentation(int prec = 0, bool abbrev = true) c onst;
/** /**
* UTM/UPS string for the alternate zone, with hemisphere override. * UTM/UPS string for the alternate zone, with hemisphere override.
* *
* @param[in] prec precision (relative to about 1m)
* @param[in] northp hemisphere override * @param[in] northp hemisphere override
* @param[in] prec precision (relative to about 1m)
* @param[in] abbrev if true (the default) use abbreviated (n/s) notati
on
* for hemisphere; otherwise spell out the hemisphere (north/south)
* @exception GeographicErr if the hemisphere override attempts to chan ge * @exception GeographicErr if the hemisphere override attempts to chan ge
* UPS N to UPS S or vice verse. * UPS n to UPS s or vice verse.
* @exception std::bad_alloc if memory for the string can't be allocate d. * @exception std::bad_alloc if memory for the string can't be allocate d.
* @return UTM/UPS string representation: zone designator, easting, and * @return UTM/UPS string representation: zone designator, easting, and
* northing. * northing.
********************************************************************** / ********************************************************************** /
std::string AltUTMUPSRepresentation(bool northp, int prec = 0) const; std::string AltUTMUPSRepresentation(bool northp, int prec = 0,
bool abbrev = true) const;
///@} ///@}
/** \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.)
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() { return UTMUPS::MajorRadius(); } Math::real MajorRadius() const { return UTMUPS::MajorRadius(); }
/** /**
* @return \e f the flattening of the WGS84 ellipsoid. * @return \e f the 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.)
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return UTMUPS::Flattening(); } Math::real Flattening() const { return UTMUPS::Flattening(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return UTMUPS::InverseFlattening(); } { return UTMUPS::InverseFlattening(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_GEOCOORDS_HPP #endif // GEOGRAPHICLIB_GEOCOORDS_HPP
 End of changes. 38 change blocks. 
46 lines changed or deleted 62 lines changed or added


 Geocentric.hpp   Geocentric.hpp 
skipping to change at line 77 skipping to change at line 77
friend class GravityCircle; // GravityCircle uses Rotation friend class GravityCircle; // GravityCircle uses Rotation
friend class GravityModel; // GravityModel uses IntForward friend class GravityModel; // GravityModel uses IntForward
friend class NormalGravity; // NormalGravity uses IntForward friend class NormalGravity; // NormalGravity uses IntForward
friend class SphericalHarmonic; friend class SphericalHarmonic;
friend class SphericalHarmonic1; friend class SphericalHarmonic1;
friend class SphericalHarmonic2; friend class SphericalHarmonic2;
static const size_t dim_ = 3; static const size_t dim_ = 3;
static const size_t dim2_ = dim_ * dim_; static const size_t dim2_ = dim_ * dim_;
real _a, _f, _e2, _e2m, _e2a, _e4a, _maxrad; real _a, _f, _e2, _e2m, _e2a, _e4a, _maxrad;
static void Rotation(real sphi, real cphi, real slam, real clam, static void Rotation(real sphi, real cphi, real slam, real clam,
real M[dim2_]) throw(); real M[dim2_]);
static void Rotate(real M[dim2_], real x, real y, real z, static void Rotate(real M[dim2_], real x, real y, real z,
real& X, real& Y, real& Z) throw() { real& X, real& Y, real& Z) {
// Perform [X,Y,Z]^t = M.[x,y,z]^t // Perform [X,Y,Z]^t = M.[x,y,z]^t
// (typically local cartesian to geocentric) // (typically local cartesian to geocentric)
X = M[0] * x + M[1] * y + M[2] * z; X = M[0] * x + M[1] * y + M[2] * z;
Y = M[3] * x + M[4] * y + M[5] * z; Y = M[3] * x + M[4] * y + M[5] * z;
Z = M[6] * x + M[7] * y + M[8] * z; Z = M[6] * x + M[7] * y + M[8] * z;
} }
static void Unrotate(real M[dim2_], real X, real Y, real Z, static void Unrotate(real M[dim2_], real X, real Y, real Z,
real& x, real& y, real& z) throw() { real& x, real& y, real& z) {
// Perform [x,y,z]^t = M^t.[X,Y,Z]^t // Perform [x,y,z]^t = M^t.[X,Y,Z]^t
// (typically geocentric to local cartesian) // (typically geocentric to local cartesian)
x = M[0] * X + M[3] * Y + M[6] * Z; x = M[0] * X + M[3] * Y + M[6] * Z;
y = M[1] * X + M[4] * Y + M[7] * Z; y = M[1] * X + M[4] * Y + M[7] * Z;
z = M[2] * X + M[5] * Y + M[8] * Z; z = M[2] * X + M[5] * Y + M[8] * Z;
} }
void IntForward(real lat, real lon, real h, real& X, real& Y, real& Z, void IntForward(real lat, real lon, real h, real& X, real& Y, real& Z,
real M[dim2_]) const throw(); real M[dim2_]) const;
void IntReverse(real X, real Y, real Z, real& lat, real& lon, real& h, void IntReverse(real X, real Y, real Z, real& lat, real& lon, real& h,
real M[dim2_]) const throw(); real M[dim2_]) const;
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] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re. * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re.
* Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing
* to 1/\e f. * to 1/\e f.
skipping to change at line 132 skipping to change at line 132
* @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 [&minus;90&deg;, 90&deg;]; \e lon * \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
* should be in the range [&minus;540&deg;, 540&deg;). * should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
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 {
if (Init()) if (Init())
IntForward(lat, lon, h, X, Y, Z, NULL); IntForward(lat, lon, h, X, Y, Z, NULL);
} }
/** /**
* Convert from geodetic to geocentric coordinates and return rotation * Convert from geodetic to geocentric coordinates and return rotation
* matrix. * matrix.
* *
* @param[in] lat latitude of point (degrees). * @param[in] lat latitude of point (degrees).
* @param[in] lon longitude of point (degrees). * @param[in] lon longitude of point (degrees).
skipping to change at line 162 skipping to change at line 162
* - in east, north, up coordinates (where the components are relative to a * - in east, north, up coordinates (where the components are relative to a
* local coordinate system at (\e lat, \e lon, \e h)); call this * local coordinate system at (\e lat, \e lon, \e h)); call this
* representation \e v1. * representation \e v1.
* - in geocentric \e X, \e Y, \e Z coordinates; call this representati on * - in geocentric \e X, \e Y, \e Z coordinates; call this representati on
* \e v0. * \e v0.
* . * .
* Then we have \e v0 = \e M &sdot; \e v1. * Then we have \e v0 = \e M &sdot; \e v1.
********************************************************************** / ********************************************************************** /
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,
std::vector<real>& M) std::vector<real>& M)
const throw() { const {
if (!Init()) if (!Init())
return; return;
if (M.end() == M.begin() + dim2_) { if (M.end() == M.begin() + dim2_) {
real t[dim2_]; real t[dim2_];
IntForward(lat, lon, h, X, Y, Z, t); IntForward(lat, lon, h, X, Y, Z, t);
copy(t, t + dim2_, M.begin()); std::copy(t, t + dim2_, M.begin());
} else } else
IntForward(lat, lon, h, X, Y, Z, NULL); IntForward(lat, lon, h, X, Y, Z, NULL);
} }
/** /**
* 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).
skipping to change at line 194 skipping to change at line 194
* \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
* latitudes (applies only if \e Z = 0), then the solution with \e lat > 0 * latitudes (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 &ge; &minus; \e a * returned. The value of \e h returned satisfies \e h &ge; &minus; \e a
* (1 &minus; <i>e</i><sup>2</sup>) / sqrt(1 &minus; <i>e</i><sup>2</su p> * (1 &minus; <i>e</i><sup>2</sup>) / sqrt(1 &minus; <i>e</i><sup>2</su p>
* sin<sup>2</sup>\e lat). The value of \e lon returned is in the rang e * sin<sup>2</sup>\e lat). The value of \e lon returned is in the rang e
* [&minus;180&deg;, 180&deg;). * [&minus;180&deg;, 180&deg;).
********************************************************************** / ********************************************************************** /
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 {
if (Init()) if (Init())
IntReverse(X, Y, Z, lat, lon, h, NULL); IntReverse(X, Y, Z, lat, lon, h, NULL);
} }
/** /**
* 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).
skipping to change at line 224 skipping to change at line 224
* local coordinate system at (\e lat, \e lon, \e h)); call this * local coordinate system at (\e lat, \e lon, \e h)); call this
* representation \e v1. * representation \e v1.
* - in geocentric \e X, \e Y, \e Z coordinates; call this representati on * - in geocentric \e X, \e Y, \e Z coordinates; call this representati on
* \e v0. * \e v0.
* . * .
* Then we have \e v1 = \e M<sup>T</sup> &sdot; \e v0, where \e * Then we have \e v1 = \e M<sup>T</sup> &sdot; \e v0, where \e
* M<sup>T</sup> is the transpose of \e M. * M<sup>T</sup> is the transpose of \e M.
********************************************************************** / ********************************************************************** /
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,
std::vector<real>& M) std::vector<real>& M)
const throw() { const {
if (!Init()) if (!Init())
return; return;
if (M.end() == M.begin() + dim2_) { if (M.end() == M.begin() + dim2_) {
real t[dim2_]; real t[dim2_];
IntReverse(X, Y, Z, lat, lon, h, t); IntReverse(X, Y, Z, lat, lon, h, t);
copy(t, t + dim2_, M.begin()); std::copy(t, t + dim2_, M.begin());
} else } else
IntReverse(X, Y, Z, lat, lon, h, NULL); IntReverse(X, Y, Z, lat, lon, h, NULL);
} }
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _a > 0; } bool Init() const { return _a > 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 used in the constructor. * the value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() Math::real MajorRadius() const
{ return Init() ? _a : Math::NaN<real>(); } { return Init() ? _a : Math::NaN<real>(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the * @return \e f the flattening of the ellipsoid. This is the
* value used in the constructor. * value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return Init() ? 1/_f : Math::NaN<real>(); } { return Init() ? 1/_f : Math::NaN<real>(); }
/// \endcond /// \endcond
/** /**
* A global instantiation of Geocentric with the parameters for the WGS 84 * A global instantiation of Geocentric with the parameters for the WGS 84
* ellipsoid. * ellipsoid.
********************************************************************** / ********************************************************************** /
static const Geocentric WGS84; static const Geocentric WGS84;
}; };
 End of changes. 15 change blocks. 
15 lines changed or deleted 15 lines changed or added


 Geodesic.hpp   Geodesic.hpp 
skipping to change at line 208 skipping to change at line 208
CAP_C1p = 1U<<1, CAP_C1p = 1U<<1,
CAP_C2 = 1U<<2, CAP_C2 = 1U<<2,
CAP_C3 = 1U<<3, CAP_C3 = 1U<<3,
CAP_C4 = 1U<<4, CAP_C4 = 1U<<4,
CAP_ALL = 0x1FU, CAP_ALL = 0x1FU,
OUT_ALL = 0x7F80U, OUT_ALL = 0x7F80U,
}; };
static real SinCosSeries(bool sinp, static real SinCosSeries(bool sinp,
real sinx, real cosx, const real c[], int n) real sinx, real cosx, const real c[], int n)
throw(); ;
static inline real AngRound(real x) throw() { static inline real AngRound(real x) {
// The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^ 57 // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^ 57
// for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi s // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi s
// is about 1000 times more resolution than we get with angles around 90 // is about 1000 times more resolution than we get with angles around 90
// degrees.) We use this to avoid having to deal with near singular // degrees.) We use this to avoid having to deal with near singular
// cases when x is non-zero but tiny (e.g., 1.0e-200). // cases when x is non-zero but tiny (e.g., 1.0e-200).
const real z = 1/real(16); const real z = 1/real(16);
volatile real y = std::abs(x); volatile real y = std::abs(x);
// The compiler mustn't "simplify" z - (z - y) to y // The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y; y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y; return x < 0 ? -y : y;
} }
static inline void SinCosNorm(real& sinx, real& cosx) throw() { static inline void SinCosNorm(real& sinx, real& cosx) {
real r = Math::hypot(sinx, cosx); real r = Math::hypot(sinx, cosx);
sinx /= r; sinx /= r;
cosx /= r; cosx /= r;
} }
static real Astroid(real x, real y) throw(); static real Astroid(real x, real y);
real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2; real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2;
real _A3x[nA3x_], _C3x[nC3x_], _C4x[nC4x_]; real _A3x[nA3x_], _C3x[nC3x_], _C4x[nC4x_];
void Lengths(real eps, real sig12, void Lengths(real eps, real sig12,
real ssig1, real csig1, real dn1, real ssig1, real csig1, real dn1,
real ssig2, real csig2, real dn2, real ssig2, real csig2, real dn2,
real cbet1, real cbet2, real cbet1, real cbet2,
real& s12s, real& m12a, real& m0, real& s12s, real& m12a, real& m0,
bool scalep, real& M12, real& M21, bool scalep, real& M12, real& M21,
real C1a[], real C2a[]) const throw(); real C1a[], real C2a[]) const;
real InverseStart(real sbet1, real cbet1, real dn1, real InverseStart(real sbet1, real cbet1, real dn1,
real sbet2, real cbet2, real dn2, real sbet2, real cbet2, real dn2,
real lam12, real lam12,
real& salp1, real& calp1, real& salp1, real& calp1,
real& salp2, real& calp2, real& dnm, real& salp2, real& calp2, real& dnm,
real C1a[], real C2a[]) const throw(); real C1a[], real C2a[]) const;
real Lambda12(real sbet1, real cbet1, real dn1, real Lambda12(real sbet1, real cbet1, real dn1,
real sbet2, real cbet2, real dn2, real sbet2, real cbet2, real dn2,
real salp1, real calp1, real salp1, real calp1,
real& salp2, real& calp2, real& sig12, real& salp2, real& calp2, real& sig12,
real& ssig1, real& csig1, real& ssig2, real& csig2, real& ssig1, real& csig1, real& ssig2, real& csig2,
real& eps, real& domg12, bool diffp, real& dlam12, real& eps, real& domg12, bool diffp, real& dlam12,
real C1a[], real C2a[], real C3a[]) real C1a[], real C2a[], real C3a[])
const throw(); const;
// These are Maxima generated functions to provide series approximation s to // These are Maxima generated functions to provide series approximation s to
// the integrals for the ellipsoidal geodesic. // the integrals for the ellipsoidal geodesic.
static real A1m1f(real eps) throw(); static real A1m1f(real eps);
static void C1f(real eps, real c[]) throw(); static void C1f(real eps, real c[]);
static void C1pf(real eps, real c[]) throw(); static void C1pf(real eps, real c[]);
static real A2m1f(real eps) throw(); static real A2m1f(real eps);
static void C2f(real eps, real c[]) throw(); static void C2f(real eps, real c[]);
void A3coeff() throw(); void A3coeff();
real A3f(real eps) const throw(); real A3f(real eps) const;
void C3coeff() throw(); void C3coeff();
void C3f(real eps, real c[]) const throw(); void C3f(real eps, real c[]) const;
void C4coeff() throw(); void C4coeff();
void C4f(real k2, real c[]) const throw(); void C4f(real k2, real c[]) const;
public: public:
/** /**
* Bit masks for what calculations to do. These masks do double duty. * Bit masks for what calculations to do. These masks do double duty.
* They signify to the GeodesicLine::GeodesicLine constructor and to * They signify to the GeodesicLine::GeodesicLine constructor and to
* Geodesic::Line what capabilities should be included in the GeodesicL ine * Geodesic::Line what capabilities should be included in the GeodesicL ine
* object. They also specify which results to return in the general * object. They also specify which results to return in the general
* routines Geodesic::GenDirect and Geodesic::GenInverse routines. * routines Geodesic::GenDirect and Geodesic::GenInverse routines.
* GeodesicLine::mask is a duplication of this enum. * GeodesicLine::mask is a duplication of this enum.
skipping to change at line 393 skipping to change at line 393
* prolate ellipsoid, an additional condition is necessary for a shorte st * prolate ellipsoid, an additional condition is necessary for a shorte st
* path: the longitudinal extent must not exceed of 180&deg;.) * path: the longitudinal extent must not exceed of 180&deg;.)
* *
* The following functions are overloaded versions of Geodesic::Direct * The following functions are overloaded versions of Geodesic::Direct
* which omit some of the output parameters. Note, however, that the a rc * which omit some of the output parameters. Note, however, that the a rc
* length is always computed and returned as the function value. * length is always computed and returned as the function value.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21, real& S12) real& m12, real& M12, real& M21, real& S12)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, t, m12, M12, M21, S12); lat2, lon2, azi2, t, m12, M12, M21, S12);
} }
/** /**
* See the documentation for Geodesic::Direct. * See the documentation for Geodesic::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2) real& lat2, real& lon2)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Direct. * See the documentation for Geodesic::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2) real& lat2, real& lon2, real& azi2)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Direct. * See the documentation for Geodesic::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& m12) real& lat2, real& lon2, real& azi2, real& m12)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | REDUCEDLENGTH, LATITUDE | LONGITUDE | AZIMUTH | REDUCEDLENGTH,
lat2, lon2, azi2, t, m12, t, t, t); lat2, lon2, azi2, t, m12, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Direct. * See the documentation for Geodesic::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& M12, real& M21) real& M12, real& M21)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | GEODESICSCALE, LATITUDE | LONGITUDE | AZIMUTH | GEODESICSCALE,
lat2, lon2, azi2, t, t, M12, M21, t); lat2, lon2, azi2, t, t, M12, M21, t);
} }
/** /**
* See the documentation for Geodesic::Direct. * See the documentation for Geodesic::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21) real& m12, real& M12, real& M21)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, t, m12, M12, M21, t); lat2, lon2, azi2, t, m12, M12, M21, t);
} }
///@} ///@}
/** \name Direct geodesic problem specified in terms of arc length. /** \name Direct geodesic problem specified in terms of arc length.
********************************************************************** / ********************************************************************** /
skipping to change at line 506 skipping to change at line 506
* 180&deg; signifies a geodesic which is not a shortest path. (For a * 180&deg; signifies a geodesic which is not a shortest path. (For a
* prolate ellipsoid, an additional condition is necessary for a shorte st * prolate ellipsoid, an additional condition is necessary for a shorte st
* path: the longitudinal extent must not exceed of 180&deg;.) * path: the longitudinal extent must not exceed of 180&deg;.)
* *
* The following functions are overloaded versions of Geodesic::Direct * The following functions are overloaded versions of Geodesic::Direct
* which omit some of the output parameters. * which omit some of the output parameters.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12, real& lat2, real& lon2, real& azi2, real& s12,
real& m12, real& M12, real& M21, real& S12) real& m12, real& M12, real& M21, real& S12)
const throw() { const {
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, s12, m12, M12, M21, S12); lat2, lon2, azi2, s12, m12, M12, M21, S12);
} }
/** /**
* See the documentation for Geodesic::ArcDirect. * See the documentation for Geodesic::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2) const throw() { real& lat2, real& lon2) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::ArcDirect. * See the documentation for Geodesic::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2) const throw() { real& lat2, real& lon2, real& azi2) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::ArcDirect. * See the documentation for Geodesic::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12) real& lat2, real& lon2, real& azi2, real& s12)
const throw() { const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE, LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
lat2, lon2, azi2, s12, t, t, t, t); lat2, lon2, azi2, s12, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::ArcDirect. * See the documentation for Geodesic::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& s12, real& m12) const throw() { real& s12, real& m12) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH, REDUCEDLENGTH,
lat2, lon2, azi2, s12, m12, t, t, t); lat2, lon2, azi2, s12, m12, t, t, t);
} }
/** /**
* See the documentation for Geodesic::ArcDirect. * See the documentation for Geodesic::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12, real& lat2, real& lon2, real& azi2, real& s12,
real& M12, real& M21) const throw() { real& M12, real& M21) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
GEODESICSCALE, GEODESICSCALE,
lat2, lon2, azi2, s12, t, M12, M21, t); lat2, lon2, azi2, s12, t, M12, M21, t);
} }
/** /**
* See the documentation for Geodesic::ArcDirect. * See the documentation for Geodesic::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12, real& lat2, real& lon2, real& azi2, real& s12,
real& m12, real& M12, real& M21) const throw() { real& m12, real& M12, real& M21) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, s12, m12, M12, M21, t); lat2, lon2, azi2, s12, m12, M12, M21, t);
} }
///@} ///@}
/** \name General version of the direct geodesic solution. /** \name General version of the direct geodesic solution.
********************************************************************** / ********************************************************************** /
skipping to change at line 639 skipping to change at line 639
* The function value \e a12 is always computed and returned and this * The function value \e a12 is always computed and returned and this
* equals \e s12_a12 is \e arcmode is true. If \e outmask includes * equals \e s12_a12 is \e arcmode is true. If \e outmask includes
* Geodesic::DISTANCE and \e arcmode is false, then \e s12 = \e s12_a12 . * Geodesic::DISTANCE and \e arcmode is false, then \e s12 = \e s12_a12 .
* It is not necessary to include Geodesic::DISTANCE_IN in \e outmask; this * It is not necessary to include Geodesic::DISTANCE_IN in \e outmask; this
* is automatically included is \e arcmode is false. * is automatically included is \e arcmode is false.
********************************************************************** / ********************************************************************** /
Math::real GenDirect(real lat1, real lon1, real azi1, Math::real GenDirect(real lat1, real lon1, real azi1,
bool arcmode, real s12_a12, unsigned outmask, bool arcmode, real s12_a12, unsigned outmask,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21, real& s12, real& m12, real& M12, real& M21,
real& S12) const throw(); real& S12) const;
///@} ///@}
/** \name Inverse geodesic problem. /** \name Inverse geodesic problem.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Solve the inverse geodesic problem. * Solve the inverse geodesic problem.
* *
* @param[in] lat1 latitude of point 1 (degrees). * @param[in] lat1 latitude of point 1 (degrees).
* @param[in] lon1 longitude of point 1 (degrees). * @param[in] lon1 longitude of point 1 (degrees).
skipping to change at line 683 skipping to change at line 683
* this fails to converge (this is very unlikely in geodetic applicatio ns * this fails to converge (this is very unlikely in geodetic applicatio ns
* but does occur for very eccentric ellipsoids), then the bisection me thod * but does occur for very eccentric ellipsoids), then the bisection me thod
* is used to refine the solution. * is used to refine the solution.
* *
* The following functions are overloaded versions of Geodesic::Inverse * The following functions are overloaded versions of Geodesic::Inverse
* which omit some of the output parameters. Note, however, that the a rc * which omit some of the output parameters. Note, however, that the a rc
* length is always computed and returned as the function value. * length is always computed and returned as the function value.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& m12, real& s12, real& azi1, real& azi2, real& m12,
real& M12, real& M21, real& S12) const throw() { real& M12, real& M21, real& S12) const {
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | DISTANCE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
s12, azi1, azi2, m12, M12, M21, S12); s12, azi1, azi2, m12, M12, M21, S12);
} }
/** /**
* See the documentation for Geodesic::Inverse. * See the documentation for Geodesic::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12) const throw() { real& s12) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE, DISTANCE,
s12, t, t, t, t, t, t); s12, t, t, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Inverse. * See the documentation for Geodesic::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& azi1, real& azi2) const throw() { real& azi1, real& azi2) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
AZIMUTH, AZIMUTH,
t, azi1, azi2, t, t, t, t); t, azi1, azi2, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Inverse. * See the documentation for Geodesic::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2) real& s12, real& azi1, real& azi2)
const throw() { const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH, DISTANCE | AZIMUTH,
s12, azi1, azi2, t, t, t, t); s12, azi1, azi2, t, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Inverse. * See the documentation for Geodesic::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& m12) real& s12, real& azi1, real& azi2, real& m12)
const throw() { const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | REDUCEDLENGTH, DISTANCE | AZIMUTH | REDUCEDLENGTH,
s12, azi1, azi2, m12, t, t, t); s12, azi1, azi2, m12, t, t, t);
} }
/** /**
* See the documentation for Geodesic::Inverse. * See the documentation for Geodesic::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& s12, real& azi1, real& azi2,
real& M12, real& M21) const throw() { real& M12, real& M21) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | GEODESICSCALE, DISTANCE | AZIMUTH | GEODESICSCALE,
s12, azi1, azi2, t, M12, M21, t); s12, azi1, azi2, t, M12, M21, t);
} }
/** /**
* See the documentation for Geodesic::Inverse. * See the documentation for Geodesic::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& m12, real& s12, real& azi1, real& azi2, real& m12,
real& M12, real& M21) const throw() { real& M12, real& M21) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | DISTANCE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
s12, azi1, azi2, m12, M12, M21, t); s12, azi1, azi2, m12, M12, M21, t);
} }
///@} ///@}
/** \name General version of inverse geodesic solution. /** \name General version of inverse geodesic solution.
********************************************************************** / ********************************************************************** /
skipping to change at line 802 skipping to change at line 802
* M12 and \e M21; * M12 and \e M21;
* - \e outmask |= Geodesic::AREA for the area \e S12; * - \e outmask |= Geodesic::AREA for the area \e S12;
* - \e outmask |= Geodesic::ALL for all of the above. * - \e outmask |= Geodesic::ALL for all of the above.
* . * .
* The arc length is always computed and returned as the function value . * The arc length is always computed and returned as the function value .
********************************************************************** / ********************************************************************** /
Math::real GenInverse(real lat1, real lon1, real lat2, real lon2, Math::real GenInverse(real lat1, real lon1, real lat2, real lon2,
unsigned outmask, unsigned outmask,
real& s12, real& azi1, real& azi2, real& s12, real& azi1, real& azi2,
real& m12, real& M12, real& M21, real& S12) real& m12, real& M12, real& M21, real& S12)
const throw(); const;
///@} ///@}
/** \name Interface to GeodesicLine. /** \name Interface to GeodesicLine.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Set up to compute several points on a single geodesic. * Set up to compute several points on a single geodesic.
* *
* @param[in] lat1 latitude of point 1 (degrees). * @param[in] lat1 latitude of point 1 (degrees).
skipping to change at line 847 skipping to change at line 847
* length can only be specified in terms of arc length; * length can only be specified in terms of arc length;
* - \e caps |= Geodesic::ALL for all of the above. * - \e caps |= Geodesic::ALL for all of the above.
* . * .
* The default value of \e caps is Geodesic::ALL. * The default value of \e caps is Geodesic::ALL.
* *
* If the point is at a pole, the azimuth is defined by keeping \e lon1 * If the point is at a pole, the azimuth is defined by keeping \e lon1
* fixed, writing \e lat1 = &plusmn;(90 &minus; &epsilon;), and taking the * fixed, writing \e lat1 = &plusmn;(90 &minus; &epsilon;), and taking the
* limit &epsilon; &rarr; 0+. * limit &epsilon; &rarr; 0+.
********************************************************************** / ********************************************************************** /
GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps = ALL) GeodesicLine Line(real lat1, real lon1, real azi1, unsigned caps = ALL)
const throw(); const;
///@} ///@}
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the * @return \e f the flattening of the ellipsoid. This is the
* value used in the constructor. * value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* @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() Math::real EllipsoidArea() const
{ return 4 * Math::pi<real>() * _c2; } { 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;
}; };
 End of changes. 34 change blocks. 
46 lines changed or deleted 46 lines changed or added


 GeodesicExact.hpp   GeodesicExact.hpp 
skipping to change at line 109 skipping to change at line 109
CAP_E = 1U<<0, CAP_E = 1U<<0,
// Skip 1U<<1 for compatibility with Geodesic (not required) // Skip 1U<<1 for compatibility with Geodesic (not required)
CAP_D = 1U<<2, CAP_D = 1U<<2,
CAP_H = 1U<<3, CAP_H = 1U<<3,
CAP_C4 = 1U<<4, CAP_C4 = 1U<<4,
CAP_ALL = 0x1FU, CAP_ALL = 0x1FU,
OUT_ALL = 0x7F80U, OUT_ALL = 0x7F80U,
}; };
static real CosSeries(real sinx, real cosx, const real c[], int n) static real CosSeries(real sinx, real cosx, const real c[], int n)
throw(); ;
static inline real AngRound(real x) throw() { static inline real AngRound(real x) {
// The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^ 57 // The makes the smallest gap in x = 1/16 - nextafter(1/16, 0) = 1/2^ 57
// for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi s // for reals = 0.7 pm on the earth if x is an angle in degrees. (Thi s
// is about 1000 times more resolution than we get with angles around 90 // is about 1000 times more resolution than we get with angles around 90
// degrees.) We use this to avoid having to deal with near singular // degrees.) We use this to avoid having to deal with near singular
// cases when x is non-zero but tiny (e.g., 1.0e-200). // cases when x is non-zero but tiny (e.g., 1.0e-200).
const real z = 1/real(16); const real z = 1/real(16);
volatile real y = std::abs(x); volatile real y = std::abs(x);
// The compiler mustn't "simplify" z - (z - y) to y // The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y; y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y; return x < 0 ? -y : y;
} }
static inline void SinCosNorm(real& sinx, real& cosx) throw() { static inline void SinCosNorm(real& sinx, real& cosx) {
real r = Math::hypot(sinx, cosx); real r = Math::hypot(sinx, cosx);
sinx /= r; sinx /= r;
cosx /= r; cosx /= r;
} }
static real Astroid(real x, real y) throw(); static real Astroid(real x, real y);
real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2; real _a, _f, _f1, _e2, _ep2, _n, _b, _c2, _etol2;
real _C4x[nC4x_]; real _C4x[nC4x_];
void Lengths(const EllipticFunction& E, void Lengths(const EllipticFunction& E,
real sig12, real sig12,
real ssig1, real csig1, real dn1, real ssig1, real csig1, real dn1,
real ssig2, real csig2, real dn2, real ssig2, real csig2, real dn2,
real cbet1, real cbet2, real cbet1, real cbet2,
real& s12s, real& m12a, real& m0, real& s12s, real& m12a, real& m0,
bool scalep, real& M12, real& M21) const throw(); bool scalep, real& M12, real& M21) const;
real InverseStart(EllipticFunction& E, real InverseStart(EllipticFunction& E,
real sbet1, real cbet1, real dn1, real sbet1, real cbet1, real dn1,
real sbet2, real cbet2, real dn2, real sbet2, real cbet2, real dn2,
real lam12, real lam12,
real& salp1, real& calp1, real& salp1, real& calp1,
real& salp2, real& calp2, real& dnm) const throw(); real& salp2, real& calp2, real& dnm) const;
real Lambda12(real sbet1, real cbet1, real dn1, real Lambda12(real sbet1, real cbet1, real dn1,
real sbet2, real cbet2, real dn2, real sbet2, real cbet2, real dn2,
real salp1, real calp1, real salp1, real calp1,
real& salp2, real& calp2, real& sig12, real& salp2, real& calp2, real& sig12,
real& ssig1, real& csig1, real& ssig2, real& csig2, real& ssig1, real& csig1, real& ssig2, real& csig2,
EllipticFunction& E, EllipticFunction& E,
real& omg12, bool diffp, real& dlam12) real& omg12, bool diffp, real& dlam12)
const throw(); const;
// These are Maxima generated functions to provide series approximation s to // These are Maxima generated functions to provide series approximation s to
// the integrals for the area. // the integrals for the area.
void C4coeff() throw(); void C4coeff();
void C4f(real k2, real c[]) const throw(); void C4f(real k2, real c[]) const;
public: public:
/** /**
* Bit masks for what calculations to do. These masks do double duty. * Bit masks for what calculations to do. These masks do double duty.
* They signify to the GeodesicLineExact::GeodesicLineExact constructor and * They signify to the GeodesicLineExact::GeodesicLineExact constructor and
* to GeodesicExact::Line what capabilities should be included in the * to GeodesicExact::Line what capabilities should be included in the
* GeodesicLineExact object. They also specify which results to return in * GeodesicLineExact object. They also specify which results to return in
* the general routines GeodesicExact::GenDirect and * the general routines GeodesicExact::GenDirect and
* GeodesicExact::GenInverse routines. GeodesicLineExact::mask is a * GeodesicExact::GenInverse routines. GeodesicLineExact::mask is a
skipping to change at line 285 skipping to change at line 285
* prolate ellipsoid, an additional condition is necessary for a shorte st * prolate ellipsoid, an additional condition is necessary for a shorte st
* path: the longitudinal extent must not exceed of 180&deg;.) * path: the longitudinal extent must not exceed of 180&deg;.)
* *
* The following functions are overloaded versions of GeodesicExact::Di rect * The following functions are overloaded versions of GeodesicExact::Di rect
* which omit some of the output parameters. Note, however, that the a rc * which omit some of the output parameters. Note, however, that the a rc
* length is always computed and returned as the function value. * length is always computed and returned as the function value.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21, real& S12) real& m12, real& M12, real& M21, real& S12)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, t, m12, M12, M21, S12); lat2, lon2, azi2, t, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicExact::Direct. * See the documentation for GeodesicExact::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2) real& lat2, real& lon2)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Direct. * See the documentation for GeodesicExact::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2) real& lat2, real& lon2, real& azi2)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Direct. * See the documentation for GeodesicExact::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& m12) real& lat2, real& lon2, real& azi2, real& m12)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | REDUCEDLENGTH, LATITUDE | LONGITUDE | AZIMUTH | REDUCEDLENGTH,
lat2, lon2, azi2, t, m12, t, t, t); lat2, lon2, azi2, t, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Direct. * See the documentation for GeodesicExact::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& M12, real& M21) real& M12, real& M21)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | GEODESICSCALE, LATITUDE | LONGITUDE | AZIMUTH | GEODESICSCALE,
lat2, lon2, azi2, t, t, M12, M21, t); lat2, lon2, azi2, t, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicExact::Direct. * See the documentation for GeodesicExact::Direct.
********************************************************************** / ********************************************************************** /
Math::real Direct(real lat1, real lon1, real azi1, real s12, Math::real Direct(real lat1, real lon1, real azi1, real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21) real& m12, real& M12, real& M21)
const throw() { const {
real t; real t;
return GenDirect(lat1, lon1, azi1, false, s12, return GenDirect(lat1, lon1, azi1, false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, t, m12, M12, M21, t); lat2, lon2, azi2, t, m12, M12, M21, t);
} }
///@} ///@}
/** \name Direct geodesic problem specified in terms of arc length. /** \name Direct geodesic problem specified in terms of arc length.
********************************************************************** / ********************************************************************** /
skipping to change at line 398 skipping to change at line 398
* 180&deg; signifies a geodesic which is not a shortest path. (For a * 180&deg; signifies a geodesic which is not a shortest path. (For a
* prolate ellipsoid, an additional condition is necessary for a shorte st * prolate ellipsoid, an additional condition is necessary for a shorte st
* path: the longitudinal extent must not exceed of 180&deg;.) * path: the longitudinal extent must not exceed of 180&deg;.)
* *
* The following functions are overloaded versions of GeodesicExact::Di rect * The following functions are overloaded versions of GeodesicExact::Di rect
* which omit some of the output parameters. * which omit some of the output parameters.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12, real& lat2, real& lon2, real& azi2, real& s12,
real& m12, real& M12, real& M21, real& S12) real& m12, real& M12, real& M21, real& S12)
const throw() { const {
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, s12, m12, M12, M21, S12); lat2, lon2, azi2, s12, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicExact::ArcDirect. * See the documentation for GeodesicExact::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2) const throw() { real& lat2, real& lon2) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::ArcDirect. * See the documentation for GeodesicExact::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2) const throw() { real& lat2, real& lon2, real& azi2) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::ArcDirect. * See the documentation for GeodesicExact::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12) real& lat2, real& lon2, real& azi2, real& s12)
const throw() { const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE, LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
lat2, lon2, azi2, s12, t, t, t, t); lat2, lon2, azi2, s12, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::ArcDirect. * See the documentation for GeodesicExact::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& s12, real& m12) const throw() { real& s12, real& m12) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH, REDUCEDLENGTH,
lat2, lon2, azi2, s12, m12, t, t, t); lat2, lon2, azi2, s12, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::ArcDirect. * See the documentation for GeodesicExact::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12, real& lat2, real& lon2, real& azi2, real& s12,
real& M12, real& M21) const throw() { real& M12, real& M21) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
GEODESICSCALE, GEODESICSCALE,
lat2, lon2, azi2, s12, t, M12, M21, t); lat2, lon2, azi2, s12, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicExact::ArcDirect. * See the documentation for GeodesicExact::ArcDirect.
********************************************************************** / ********************************************************************** /
void ArcDirect(real lat1, real lon1, real azi1, real a12, void ArcDirect(real lat1, real lon1, real azi1, real a12,
real& lat2, real& lon2, real& azi2, real& s12, real& lat2, real& lon2, real& azi2, real& s12,
real& m12, real& M12, real& M21) const throw() { real& m12, real& M12, real& M21) const {
real t; real t;
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, s12, m12, M12, M21, t); lat2, lon2, azi2, s12, m12, M12, M21, t);
} }
///@} ///@}
/** \name General version of the direct geodesic solution. /** \name General version of the direct geodesic solution.
********************************************************************** / ********************************************************************** /
skipping to change at line 531 skipping to change at line 531
* The function value \e a12 is always computed and returned and this * The function value \e a12 is always computed and returned and this
* equals \e s12_a12 is \e arcmode is true. If \e outmask includes * equals \e s12_a12 is \e arcmode is true. If \e outmask includes
* GeodesicExact::DISTANCE and \e arcmode is false, then \e s12 = \e * GeodesicExact::DISTANCE and \e arcmode is false, then \e s12 = \e
* s12_a12. It is not necessary to include GeodesicExact::DISTANCE_IN in * s12_a12. It is not necessary to include GeodesicExact::DISTANCE_IN in
* \e outmask; this is automatically included is \e arcmode is false. * \e outmask; this is automatically included is \e arcmode is false.
********************************************************************** / ********************************************************************** /
Math::real GenDirect(real lat1, real lon1, real azi1, Math::real GenDirect(real lat1, real lon1, real azi1,
bool arcmode, real s12_a12, unsigned outmask, bool arcmode, real s12_a12, unsigned outmask,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21, real& s12, real& m12, real& M12, real& M21,
real& S12) const throw(); real& S12) const;
///@} ///@}
/** \name Inverse geodesic problem. /** \name Inverse geodesic problem.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Perform the inverse geodesic calculation. * Perform the inverse geodesic calculation.
* *
* @param[in] lat1 latitude of point 1 (degrees). * @param[in] lat1 latitude of point 1 (degrees).
* @param[in] lon1 longitude of point 1 (degrees). * @param[in] lon1 longitude of point 1 (degrees).
skipping to change at line 570 skipping to change at line 570
* If either point is at a pole, the azimuth is defined by keeping the * If either point is at a pole, the azimuth is defined by keeping the
* longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon; ), * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon; ),
* and taking the limit &epsilon; &rarr; 0+. * and taking the limit &epsilon; &rarr; 0+.
* *
* The following functions are overloaded versions of GeodesicExact::In verse * The following functions are overloaded versions of GeodesicExact::In verse
* which omit some of the output parameters. Note, however, that the a rc * which omit some of the output parameters. Note, however, that the a rc
* length is always computed and returned as the function value. * length is always computed and returned as the function value.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& m12, real& s12, real& azi1, real& azi2, real& m12,
real& M12, real& M21, real& S12) const throw() { real& M12, real& M21, real& S12) const {
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | DISTANCE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
s12, azi1, azi2, m12, M12, M21, S12); s12, azi1, azi2, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicExact::Inverse. * See the documentation for GeodesicExact::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12) const throw() { real& s12) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE, DISTANCE,
s12, t, t, t, t, t, t); s12, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Inverse. * See the documentation for GeodesicExact::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& azi1, real& azi2) const throw() { real& azi1, real& azi2) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
AZIMUTH, AZIMUTH,
t, azi1, azi2, t, t, t, t); t, azi1, azi2, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Inverse. * See the documentation for GeodesicExact::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2) real& s12, real& azi1, real& azi2)
const throw() { const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH, DISTANCE | AZIMUTH,
s12, azi1, azi2, t, t, t, t); s12, azi1, azi2, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Inverse. * See the documentation for GeodesicExact::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& m12) real& s12, real& azi1, real& azi2, real& m12)
const throw() { const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | REDUCEDLENGTH, DISTANCE | AZIMUTH | REDUCEDLENGTH,
s12, azi1, azi2, m12, t, t, t); s12, azi1, azi2, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicExact::Inverse. * See the documentation for GeodesicExact::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& s12, real& azi1, real& azi2,
real& M12, real& M21) const throw() { real& M12, real& M21) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | GEODESICSCALE, DISTANCE | AZIMUTH | GEODESICSCALE,
s12, azi1, azi2, t, M12, M21, t); s12, azi1, azi2, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicExact::Inverse. * See the documentation for GeodesicExact::Inverse.
********************************************************************** / ********************************************************************** /
Math::real Inverse(real lat1, real lon1, real lat2, real lon2, Math::real Inverse(real lat1, real lon1, real lat2, real lon2,
real& s12, real& azi1, real& azi2, real& m12, real& s12, real& azi1, real& azi2, real& m12,
real& M12, real& M21) const throw() { real& M12, real& M21) const {
real t; real t;
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | DISTANCE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
s12, azi1, azi2, m12, M12, M21, t); s12, azi1, azi2, m12, M12, M21, t);
} }
///@} ///@}
/** \name General version of inverse geodesic solution. /** \name General version of inverse geodesic solution.
********************************************************************** / ********************************************************************** /
skipping to change at line 689 skipping to change at line 689
* M12 and \e M21; * M12 and \e M21;
* - \e outmask |= GeodesicExact::AREA for the area \e S12; * - \e outmask |= GeodesicExact::AREA for the area \e S12;
* - \e outmask |= GeodesicExact::ALL for all of the above. * - \e outmask |= GeodesicExact::ALL for all of the above.
* . * .
* The arc length is always computed and returned as the function value . * The arc length is always computed and returned as the function value .
********************************************************************** / ********************************************************************** /
Math::real GenInverse(real lat1, real lon1, real lat2, real lon2, Math::real GenInverse(real lat1, real lon1, real lat2, real lon2,
unsigned outmask, unsigned outmask,
real& s12, real& azi1, real& azi2, real& s12, real& azi1, real& azi2,
real& m12, real& M12, real& M21, real& S12) real& m12, real& M12, real& M21, real& S12)
const throw(); const;
///@} ///@}
/** \name Interface to GeodesicLineExact. /** \name Interface to GeodesicLineExact.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Set up to compute several points on a single geodesic. * Set up to compute several points on a single geodesic.
* *
* @param[in] lat1 latitude of point 1 (degrees). * @param[in] lat1 latitude of point 1 (degrees).
skipping to change at line 735 skipping to change at line 735
* - \e caps |= GeodesicExact::ALL for all of the above. * - \e caps |= GeodesicExact::ALL for all of the above.
* . * .
* The default value of \e caps is GeodesicExact::ALL which turns on al l * The default value of \e caps is GeodesicExact::ALL which turns on al l
* the capabilities. * the capabilities.
* *
* If the point is at a pole, the azimuth is defined by keeping \e lon1 * If the point is at a pole, the azimuth is defined by keeping \e lon1
* fixed, writing \e lat1 = &plusmn;(90 &minus; &epsilon;), and taking the * fixed, writing \e lat1 = &plusmn;(90 &minus; &epsilon;), and taking the
* limit &epsilon; &rarr; 0+. * limit &epsilon; &rarr; 0+.
********************************************************************** / ********************************************************************** /
GeodesicLineExact Line(real lat1, real lon1, real azi1, unsigned caps = ALL) GeodesicLineExact Line(real lat1, real lon1, real azi1, unsigned caps = ALL)
const throw(); const;
///@} ///@}
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the * @return \e f the flattening of the ellipsoid. This is the
* value used in the constructor. * value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* @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
* GeodesicExact::EllipsoidArea()/2 to the sum of \e S12 for each sid e of * GeodesicExact::EllipsoidArea()/2 to the sum of \e S12 for each sid e of
* the polygon. * the polygon.
********************************************************************** / ********************************************************************** /
Math::real EllipsoidArea() const throw() Math::real EllipsoidArea() const
{ return 4 * Math::pi<real>() * _c2; } { return 4 * Math::pi<real>() * _c2; }
///@} ///@}
/** /**
* A global instantiation of GeodesicExact with the parameters for the WGS84 * A global instantiation of GeodesicExact with the parameters for the WGS84
* ellipsoid. * ellipsoid.
********************************************************************** / ********************************************************************** /
static const GeodesicExact WGS84; static const GeodesicExact WGS84;
}; };
 End of changes. 34 change blocks. 
36 lines changed or deleted 36 lines changed or added


 GeodesicLine.hpp   GeodesicLine.hpp 
skipping to change at line 198 skipping to change at line 198
* - \e caps |= GeodesicLine::ALL for all of the above. * - \e caps |= GeodesicLine::ALL for all of the above.
* . * .
* The default value of \e caps is GeodesicLine::ALL. * The default value of \e caps is GeodesicLine::ALL.
* *
* If the point is at a pole, the azimuth is defined by keeping \e lon1 * If the point is at a pole, the azimuth is defined by keeping \e lon1
* fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and ta king * fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and ta king
* the limit &epsilon; &rarr; 0+. * the limit &epsilon; &rarr; 0+.
********************************************************************** / ********************************************************************** /
GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1, GeodesicLine(const Geodesic& g, real lat1, real lon1, real azi1,
unsigned caps = ALL) unsigned caps = ALL)
throw(); ;
/** /**
* A default constructor. If GeodesicLine::Position is called on the * A default constructor. If GeodesicLine::Position is called on the
* resulting object, it returns immediately (without doing any * resulting object, it returns immediately (without doing any
* calculations). The object can be set with a call to Geodesic::Line. * calculations). The object can be set with a call to Geodesic::Line.
* Use Init() to test whether object is still in this uninitialized sta te. * Use Init() to test whether object is still in this uninitialized sta te.
********************************************************************** / ********************************************************************** /
GeodesicLine() throw() : _caps(0U) {} GeodesicLine() : _caps(0U) {}
///@} ///@}
/** \name Position in terms of distance /** \name Position in terms of distance
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Compute the position of point 2 which is a distance \e s12 (meters) from * Compute the position of point 2 which is a distance \e s12 (meters) from
* point 1. * point 1.
* *
skipping to change at line 255 skipping to change at line 255
* will not be altered. * will not be altered.
* *
* The following functions are overloaded versions of * The following functions are overloaded versions of
* GeodesicLine::Position which omit some of the output parameters. No te, * GeodesicLine::Position which omit some of the output parameters. No te,
* however, that the arc length is always computed and returned as the * however, that the arc length is always computed and returned as the
* function value. * function value.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, Math::real Position(real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21, real& m12, real& M12, real& M21,
real& S12) const throw() { real& S12) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, t, m12, M12, M21, S12); lat2, lon2, azi2, t, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicLine::Position. * See the documentation for GeodesicLine::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2) const throw() { Math::real Position(real s12, real& lat2, real& lon2) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::Position. * See the documentation for GeodesicLine::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2, Math::real Position(real s12, real& lat2, real& lon2,
real& azi2) const throw() { real& azi2) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::Position. * See the documentation for GeodesicLine::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2, Math::real Position(real s12, real& lat2, real& lon2,
real& azi2, real& m12) const throw() { real& azi2, real& m12) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | LATITUDE | LONGITUDE |
AZIMUTH | REDUCEDLENGTH, AZIMUTH | REDUCEDLENGTH,
lat2, lon2, azi2, t, m12, t, t, t); lat2, lon2, azi2, t, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::Position. * See the documentation for GeodesicLine::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2, Math::real Position(real s12, real& lat2, real& lon2,
real& azi2, real& M12, real& M21) real& azi2, real& M12, real& M21)
const throw() { const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | LATITUDE | LONGITUDE |
AZIMUTH | GEODESICSCALE, AZIMUTH | GEODESICSCALE,
lat2, lon2, azi2, t, t, M12, M21, t); lat2, lon2, azi2, t, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicLine::Position. * See the documentation for GeodesicLine::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, Math::real Position(real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21) real& m12, real& M12, real& M21)
const throw() { const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, t, m12, M12, M21, t); lat2, lon2, azi2, t, m12, M12, M21, t);
} }
///@} ///@}
/** \name Position in terms of arc length /** \name Position in terms of arc length
skipping to change at line 368 skipping to change at line 368
* *
* Requesting a value which the GeodesicLine object is not capable of * Requesting a value which the GeodesicLine object is not capable of
* computing is not an error; the corresponding argument will not be * computing is not an error; the corresponding argument will not be
* altered. * altered.
* *
* The following functions are overloaded versions of * The following functions are overloaded versions of
* GeodesicLine::ArcPosition which omit some of the output parameters. * GeodesicLine::ArcPosition which omit some of the output parameters.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21, real& s12, real& m12, real& M12, real& M21,
real& S12) const throw() { real& S12) const {
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, s12, m12, M12, M21, S12); lat2, lon2, azi2, s12, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicLine::ArcPosition. * See the documentation for GeodesicLine::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2) void ArcPosition(real a12, real& lat2, real& lon2)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::ArcPosition. * See the documentation for GeodesicLine::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, void ArcPosition(real a12,
real& lat2, real& lon2, real& azi2) real& lat2, real& lon2, real& azi2)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::ArcPosition. * See the documentation for GeodesicLine::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12) const throw() { real& s12) const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE, LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
lat2, lon2, azi2, s12, t, t, t, t); lat2, lon2, azi2, s12, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::ArcPosition. * See the documentation for GeodesicLine::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& m12) const throw() { real& s12, real& m12) const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
DISTANCE | REDUCEDLENGTH, DISTANCE | REDUCEDLENGTH,
lat2, lon2, azi2, s12, m12, t, t, t); lat2, lon2, azi2, s12, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicLine::ArcPosition. * See the documentation for GeodesicLine::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& M12, real& M21) real& s12, real& M12, real& M21)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
DISTANCE | GEODESICSCALE, DISTANCE | GEODESICSCALE,
lat2, lon2, azi2, s12, t, M12, M21, t); lat2, lon2, azi2, s12, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicLine::ArcPosition. * See the documentation for GeodesicLine::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21) real& s12, real& m12, real& M12, real& M21)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
DISTANCE | REDUCEDLENGTH | GEODESICSCALE, DISTANCE | REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, s12, m12, M12, M21, t); lat2, lon2, azi2, s12, m12, M12, M21, t);
} }
///@} ///@}
/** \name The general position function. /** \name The general position function.
********************************************************************** / ********************************************************************** /
skipping to change at line 506 skipping to change at line 506
* - \e outmask |= GeodesicLine::ALL for all of the above. * - \e outmask |= GeodesicLine::ALL for all of the above.
* . * .
* Requesting a value which the GeodesicLine object is not capable of * Requesting a value which the GeodesicLine object is not capable of
* computing is not an error; the corresponding argument will not be * computing is not an error; the corresponding argument will not be
* altered. Note, however, that the arc length is always computed and * altered. Note, however, that the arc length is always computed and
* returned as the function value. * returned as the function value.
********************************************************************** / ********************************************************************** /
Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask, Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21, real& s12, real& m12, real& M12, real& M21,
real& S12) const throw(); real& S12) const;
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _caps != 0U; } bool Init() const { return _caps != 0U; }
/** /**
* @return \e lat1 the latitude of point 1 (degrees). * @return \e lat1 the latitude of point 1 (degrees).
********************************************************************** / ********************************************************************** /
Math::real Latitude() const throw() Math::real Latitude() const
{ return Init() ? _lat1 : Math::NaN<real>(); } { return Init() ? _lat1 : Math::NaN<real>(); }
/** /**
* @return \e lon1 the longitude of point 1 (degrees). * @return \e lon1 the longitude of point 1 (degrees).
********************************************************************** / ********************************************************************** /
Math::real Longitude() const throw() Math::real Longitude() const
{ return Init() ? _lon1 : Math::NaN<real>(); } { return Init() ? _lon1 : Math::NaN<real>(); }
/** /**
* @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() Math::real Azimuth() const
{ return Init() ? _azi1 : Math::NaN<real>(); } { return Init() ? _azi1 : Math::NaN<real>(); }
/** /**
* @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 {
return Init() ? return Init() ?
atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>(); atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>();
} }
/** /**
* @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 {
return Init() ? return Init() ?
atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>(); atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>();
} }
/** /**
* @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() Math::real MajorRadius() const
{ return Init() ? _a : Math::NaN<real>(); } { return Init() ? _a : Math::NaN<real>(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geodesic object used in the constructor. * inherited from the Geodesic object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return Init() ? 1/_f : Math::NaN<real>(); } { return Init() ? 1/_f : Math::NaN<real>(); }
/// \endcond /// \endcond
/** /**
* @return \e caps the computational capabilities that this object was * @return \e caps the computational capabilities that this object was
* constructed with. LATITUDE and AZIMUTH are always included. * constructed with. LATITUDE and AZIMUTH are always included.
********************************************************************** / ********************************************************************** /
unsigned Capabilities() const throw() { return _caps; } unsigned Capabilities() const { return _caps; }
/** /**
* @param[in] testcaps a set of bitor'ed GeodesicLine::mask values. * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
* @return true if the GeodesicLine object has all these capabilities. * @return true if the GeodesicLine object has all these capabilities.
********************************************************************** / ********************************************************************** /
bool Capabilities(unsigned testcaps) const throw() { bool Capabilities(unsigned testcaps) const {
testcaps &= OUT_ALL; testcaps &= OUT_ALL;
return (_caps & testcaps) == testcaps; return (_caps & testcaps) == testcaps;
} }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_GEODESICLINE_HPP #endif // GEOGRAPHICLIB_GEODESICLINE_HPP
 End of changes. 27 change blocks. 
27 lines changed or deleted 27 lines changed or added


 GeodesicLineExact.hpp   GeodesicLineExact.hpp 
skipping to change at line 171 skipping to change at line 171
* - \e caps |= GeodesicLineExact::ALL for all of the above. * - \e caps |= GeodesicLineExact::ALL for all of the above.
* . * .
* The default value of \e caps is GeodesicLineExact::ALL. * The default value of \e caps is GeodesicLineExact::ALL.
* *
* If the point is at a pole, the azimuth is defined by keeping \e lon1 * If the point is at a pole, the azimuth is defined by keeping \e lon1
* fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and ta king * fixed, writing \e lat1 = &plusmn;(90&deg; &minus; &epsilon;), and ta king
* the limit &epsilon; &rarr; 0+. * the limit &epsilon; &rarr; 0+.
********************************************************************** / ********************************************************************** /
GeodesicLineExact(const GeodesicExact& g, real lat1, real lon1, real az i1, GeodesicLineExact(const GeodesicExact& g, real lat1, real lon1, real az i1,
unsigned caps = ALL) unsigned caps = ALL)
throw(); ;
/** /**
* A default constructor. If GeodesicLineExact::Position is called on the * A default constructor. If GeodesicLineExact::Position is called on the
* resulting object, it returns immediately (without doing any * resulting object, it returns immediately (without doing any
* calculations). The object can be set with a call to * calculations). The object can be set with a call to
* GeodesicExact::Line. Use Init() to test whether object is still in this * GeodesicExact::Line. Use Init() to test whether object is still in this
* uninitialized state. * uninitialized state.
********************************************************************** / ********************************************************************** /
GeodesicLineExact() throw() : _caps(0U) {} GeodesicLineExact() : _caps(0U) {}
///@} ///@}
/** \name Position in terms of distance /** \name Position in terms of distance
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Compute the position of point 2 which is a distance \e s12 (meters) * Compute the position of point 2 which is a distance \e s12 (meters)
* from point 1. * from point 1.
* *
skipping to change at line 229 skipping to change at line 229
* argument will not be altered. * argument will not be altered.
* *
* The following functions are overloaded versions of * The following functions are overloaded versions of
* GeodesicLineExact::Position which omit some of the output parameters . * GeodesicLineExact::Position which omit some of the output parameters .
* Note, however, that the arc length is always computed and returned a s * Note, however, that the arc length is always computed and returned a s
* the function value. * the function value.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, Math::real Position(real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21, real& m12, real& M12, real& M21,
real& S12) const throw() { real& S12) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, t, m12, M12, M21, S12); lat2, lon2, azi2, t, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicLineExact::Position. * See the documentation for GeodesicLineExact::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2) const throw() { Math::real Position(real s12, real& lat2, real& lon2) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::Position. * See the documentation for GeodesicLineExact::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2, Math::real Position(real s12, real& lat2, real& lon2,
real& azi2) const throw() { real& azi2) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::Position. * See the documentation for GeodesicLineExact::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2, Math::real Position(real s12, real& lat2, real& lon2,
real& azi2, real& m12) const throw() { real& azi2, real& m12) const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | LATITUDE | LONGITUDE |
AZIMUTH | REDUCEDLENGTH, AZIMUTH | REDUCEDLENGTH,
lat2, lon2, azi2, t, m12, t, t, t); lat2, lon2, azi2, t, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::Position. * See the documentation for GeodesicLineExact::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, real& lat2, real& lon2, Math::real Position(real s12, real& lat2, real& lon2,
real& azi2, real& M12, real& M21) real& azi2, real& M12, real& M21)
const throw() { const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | LATITUDE | LONGITUDE |
AZIMUTH | GEODESICSCALE, AZIMUTH | GEODESICSCALE,
lat2, lon2, azi2, t, t, M12, M21, t); lat2, lon2, azi2, t, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicLineExact::Position. * See the documentation for GeodesicLineExact::Position.
********************************************************************** / ********************************************************************** /
Math::real Position(real s12, Math::real Position(real s12,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& m12, real& M12, real& M21) real& m12, real& M12, real& M21)
const throw() { const {
real t; real t;
return GenPosition(false, s12, return GenPosition(false, s12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
REDUCEDLENGTH | GEODESICSCALE, REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, t, m12, M12, M21, t); lat2, lon2, azi2, t, m12, M12, M21, t);
} }
///@} ///@}
/** \name Position in terms of arc length /** \name Position in terms of arc length
skipping to change at line 342 skipping to change at line 342
* *
* Requesting a value which the GeodesicLineExact object is not capable of * Requesting a value which the GeodesicLineExact object is not capable of
* computing is not an error; the corresponding argument will not be * computing is not an error; the corresponding argument will not be
* altered. * altered.
* *
* The following functions are overloaded versions of * The following functions are overloaded versions of
* GeodesicLineExact::ArcPosition which omit some of the output paramet ers. * GeodesicLineExact::ArcPosition which omit some of the output paramet ers.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21, real& s12, real& m12, real& M12, real& M21,
real& S12) const throw() { real& S12) const {
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
REDUCEDLENGTH | GEODESICSCALE | AREA, REDUCEDLENGTH | GEODESICSCALE | AREA,
lat2, lon2, azi2, s12, m12, M12, M21, S12); lat2, lon2, azi2, s12, m12, M12, M21, S12);
} }
/** /**
* See the documentation for GeodesicLineExact::ArcPosition. * See the documentation for GeodesicLineExact::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2) void ArcPosition(real a12, real& lat2, real& lon2)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE, LATITUDE | LONGITUDE,
lat2, lon2, t, t, t, t, t, t); lat2, lon2, t, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::ArcPosition. * See the documentation for GeodesicLineExact::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, void ArcPosition(real a12,
real& lat2, real& lon2, real& azi2) real& lat2, real& lon2, real& azi2)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH, LATITUDE | LONGITUDE | AZIMUTH,
lat2, lon2, azi2, t, t, t, t, t); lat2, lon2, azi2, t, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::ArcPosition. * See the documentation for GeodesicLineExact::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12) const throw() { real& s12) const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE, LATITUDE | LONGITUDE | AZIMUTH | DISTANCE,
lat2, lon2, azi2, s12, t, t, t, t); lat2, lon2, azi2, s12, t, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::ArcPosition. * See the documentation for GeodesicLineExact::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& m12) const throw() { real& s12, real& m12) const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
DISTANCE | REDUCEDLENGTH, DISTANCE | REDUCEDLENGTH,
lat2, lon2, azi2, s12, m12, t, t, t); lat2, lon2, azi2, s12, m12, t, t, t);
} }
/** /**
* See the documentation for GeodesicLineExact::ArcPosition. * See the documentation for GeodesicLineExact::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& M12, real& M21) real& s12, real& M12, real& M21)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
DISTANCE | GEODESICSCALE, DISTANCE | GEODESICSCALE,
lat2, lon2, azi2, s12, t, M12, M21, t); lat2, lon2, azi2, s12, t, M12, M21, t);
} }
/** /**
* See the documentation for GeodesicLineExact::ArcPosition. * See the documentation for GeodesicLineExact::ArcPosition.
********************************************************************** / ********************************************************************** /
void ArcPosition(real a12, real& lat2, real& lon2, real& azi2, void ArcPosition(real a12, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21) real& s12, real& m12, real& M12, real& M21)
const throw() { const {
real t; real t;
GenPosition(true, a12, GenPosition(true, a12,
LATITUDE | LONGITUDE | AZIMUTH | LATITUDE | LONGITUDE | AZIMUTH |
DISTANCE | REDUCEDLENGTH | GEODESICSCALE, DISTANCE | REDUCEDLENGTH | GEODESICSCALE,
lat2, lon2, azi2, s12, m12, M12, M21, t); lat2, lon2, azi2, s12, m12, M12, M21, t);
} }
///@} ///@}
/** \name The general position function. /** \name The general position function.
********************************************************************** / ********************************************************************** /
skipping to change at line 480 skipping to change at line 480
* - \e outmask |= GeodesicLine::ALL for all of the above. * - \e outmask |= GeodesicLine::ALL for all of the above.
* . * .
* Requesting a value which the GeodesicLineExact object is not capable of * Requesting a value which the GeodesicLineExact object is not capable of
* computing is not an error; the corresponding argument will not be * computing is not an error; the corresponding argument will not be
* altered. Note, however, that the arc length is always computed and * altered. Note, however, that the arc length is always computed and
* returned as the function value. * returned as the function value.
********************************************************************** / ********************************************************************** /
Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask, Math::real GenPosition(bool arcmode, real s12_a12, unsigned outmask,
real& lat2, real& lon2, real& azi2, real& lat2, real& lon2, real& azi2,
real& s12, real& m12, real& M12, real& M21, real& s12, real& m12, real& M12, real& M21,
real& S12) const throw(); real& S12) const;
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _caps != 0U; } bool Init() const { return _caps != 0U; }
/** /**
* @return \e lat1 the latitude of point 1 (degrees). * @return \e lat1 the latitude of point 1 (degrees).
********************************************************************** / ********************************************************************** /
Math::real Latitude() const throw() Math::real Latitude() const
{ return Init() ? _lat1 : Math::NaN<real>(); } { return Init() ? _lat1 : Math::NaN<real>(); }
/** /**
* @return \e lon1 the longitude of point 1 (degrees). * @return \e lon1 the longitude of point 1 (degrees).
********************************************************************** / ********************************************************************** /
Math::real Longitude() const throw() Math::real Longitude() const
{ return Init() ? _lon1 : Math::NaN<real>(); } { return Init() ? _lon1 : Math::NaN<real>(); }
/** /**
* @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() Math::real Azimuth() const
{ return Init() ? _azi1 : Math::NaN<real>(); } { return Init() ? _azi1 : Math::NaN<real>(); }
/** /**
* @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 {
return Init() ? return Init() ?
atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>(); atan2(_salp0, _calp0) / Math::degree<real>() : Math::NaN<real>();
} }
/** /**
* @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 {
return Init() ? return Init() ?
atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>(); atan2(_ssig1, _csig1) / Math::degree<real>() : Math::NaN<real>();
} }
/** /**
* @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 GeodesicExact object used in the * the value inherited from the GeodesicExact object used in the
* constructor. * constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() Math::real MajorRadius() const
{ return Init() ? _a : Math::NaN<real>(); } { return Init() ? _a : Math::NaN<real>(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the GeodesicExact object used in the constructor. * inherited from the GeodesicExact object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return Init() ? 1/_f : Math::NaN<real>(); } { return Init() ? 1/_f : Math::NaN<real>(); }
/// \endcond /// \endcond
/** /**
* @return \e caps the computational capabilities that this object was * @return \e caps the computational capabilities that this object was
* constructed with. LATITUDE and AZIMUTH are always included. * constructed with. LATITUDE and AZIMUTH are always included.
********************************************************************** / ********************************************************************** /
unsigned Capabilities() const throw() { return _caps; } unsigned Capabilities() const { return _caps; }
/** /**
* @param[in] testcaps a set of bitor'ed GeodesicLineExact::mask values . * @param[in] testcaps a set of bitor'ed GeodesicLineExact::mask values .
* @return true if the GeodesicLineExact object has all these capabilit ies. * @return true if the GeodesicLineExact object has all these capabilit ies.
********************************************************************** / ********************************************************************** /
bool Capabilities(unsigned testcaps) const throw() { bool Capabilities(unsigned testcaps) const {
testcaps &= OUT_ALL; testcaps &= OUT_ALL;
return (_caps & testcaps) == testcaps; return (_caps & testcaps) == testcaps;
} }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_GEODESICLINEEXACT_HPP #endif // GEOGRAPHICLIB_GEODESICLINEEXACT_HPP
 End of changes. 27 change blocks. 
27 lines changed or deleted 27 lines changed or added


 Geohash.hpp   Geohash.hpp 
skipping to change at line 101 skipping to change at line 101
int& len, bool centerp = true); int& len, bool centerp = true);
/** /**
* The latitude resolution of a geohash. * The latitude resolution of a geohash.
* *
* @param[in] len the length of the geohash. * @param[in] len the length of the geohash.
* @return the latitude resolution (degrees). * @return the latitude resolution (degrees).
* *
* Internally, \e len is first put in the range [0, 18]. * Internally, \e len is first put in the range [0, 18].
********************************************************************** / ********************************************************************** /
static Math::real LatitudeResolution(int len) throw() { static Math::real LatitudeResolution(int len) {
len = (std::max)(0, (std::min)(int(maxlen_), len)); len = (std::max)(0, (std::min)(int(maxlen_), len));
return 180 * std::pow(0.5, 5 * len / 2); return 180 * std::pow(0.5, 5 * len / 2);
} }
/** /**
* The longitude resolution of a geohash. * The longitude resolution of a geohash.
* *
* @param[in] len the length of the geohash. * @param[in] len the length of the geohash.
* @return the longitude resolution (degrees). * @return the longitude resolution (degrees).
* *
* Internally, \e len is first put in the range [0, 18]. * Internally, \e len is first put in the range [0, 18].
********************************************************************** / ********************************************************************** /
static Math::real LongitudeResolution(int len) throw() { static Math::real LongitudeResolution(int len) {
len = (std::max)(0, (std::min)(int(maxlen_), len)); len = (std::max)(0, (std::min)(int(maxlen_), len));
return 360 * std::pow(0.5, 5 * len - 5 * len / 2); return 360 * std::pow(0.5, 5 * len - 5 * len / 2);
} }
/** /**
* The geohash length required to meet a given geographic resolution. * The geohash length required to meet a given geographic resolution.
* *
* @param[in] res the minimum of resolution in latitude and longitude * @param[in] res the minimum of resolution in latitude and longitude
* (degrees). * (degrees).
* @return geohash length. * @return geohash length.
* *
* The returned length is in the range [0, 18]. * The returned length is in the range [0, 18].
********************************************************************** / ********************************************************************** /
static int GeohashLength(real res) throw() { static int GeohashLength(real res) {
res = std::abs(res); res = std::abs(res);
for (int len = 0; len < maxlen_; ++len) for (int len = 0; len < maxlen_; ++len)
if (LongitudeResolution(len) <= res) if (LongitudeResolution(len) <= res)
return len; return len;
return maxlen_; return maxlen_;
} }
/** /**
* The geohash length required to meet a given geographic resolution. * The geohash length required to meet a given geographic resolution.
* *
* @param[in] latres the resolution in latitude (degrees). * @param[in] latres the resolution in latitude (degrees).
* @param[in] lonres the resolution in longitude (degrees). * @param[in] lonres the resolution in longitude (degrees).
* @return geohash length. * @return geohash length.
* *
* The returned length is in the range [0, 18]. * The returned length is in the range [0, 18].
********************************************************************** / ********************************************************************** /
static int GeohashLength(real latres, real lonres) throw() { static int GeohashLength(real latres, real lonres) {
latres = std::abs(latres); latres = std::abs(latres);
lonres = std::abs(lonres); lonres = std::abs(lonres);
for (int len = 0; len < maxlen_; ++len) for (int len = 0; len < maxlen_; ++len)
if (LatitudeResolution(len) <= latres && if (LatitudeResolution(len) <= latres &&
LongitudeResolution(len) <= lonres) LongitudeResolution(len) <= lonres)
return len; return len;
return maxlen_; return maxlen_;
} }
/** /**
* The decimal geographic precision required to match a given geohash * The decimal geographic precision required to match a given geohash
* length. This is the number of digits needed after decimal point in a * length. This is the number of digits needed after decimal point in a
* decimal degrees representation. * decimal degrees representation.
* *
* @param[in] len the length of the geohash. * @param[in] len the length of the geohash.
* @return the decimal precision (may be negative). * @return the decimal precision (may be negative).
* *
* Internally, \e len is first put in the range [0, 18]. The returned * Internally, \e len is first put in the range [0, 18]. The returned
* decimal precision is in the range [&minus;2, 12]. * decimal precision is in the range [&minus;2, 12].
********************************************************************** / ********************************************************************** /
static int DecimalPrecision(int len) throw() { static int DecimalPrecision(int len) {
return -int(std::floor(std::log(LatitudeResolution(len))/ return -int(std::floor(std::log(LatitudeResolution(len))/
std::log(Math::real(10)))); std::log(Math::real(10))));
} }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning (pop) # pragma warning (pop)
 End of changes. 5 change blocks. 
5 lines changed or deleted 5 lines changed or added


 Geoid.hpp   Geoid.hpp 
skipping to change at line 269 skipping to change at line 269
* or coarser. For a 1' grid, the required RAM is 450MB; a 2.5' grid n eeds * or coarser. For a 1' grid, the required RAM is 450MB; a 2.5' grid n eeds
* 72MB; and a 5' grid needs 18MB. * 72MB; and a 5' grid needs 18MB.
********************************************************************** / ********************************************************************** /
void CacheAll() const { CacheArea(real(-90), real(0), void CacheAll() const { CacheArea(real(-90), real(0),
real(90), real(360)); } real(90), real(360)); }
/** /**
* Clear the cache. This never throws an error. (This does nothing wi th a * Clear the cache. This never throws an error. (This does nothing wi th a
* thread safe Geoid.) * thread safe Geoid.)
********************************************************************** / ********************************************************************** /
void CacheClear() const throw(); void CacheClear() const;
///@} ///@}
/** \name Compute geoid heights /** \name Compute geoid heights
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Compute the geoid height at a point * Compute the geoid height at a point
* *
* @param[in] lat latitude of the point (degrees). * @param[in] lat latitude of the point (degrees).
skipping to change at line 346 skipping to change at line 346
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return geoid description, if available, in the data file; if * @return geoid description, if available, in the data file; if
* absent, return "NONE". * absent, return "NONE".
********************************************************************** / ********************************************************************** /
const std::string& Description() const throw() { return _description; } const std::string& Description() const { return _description; }
/** /**
* @return date of the data file; if absent, return "UNKNOWN". * @return date of the data file; if absent, return "UNKNOWN".
********************************************************************** / ********************************************************************** /
const std::string& DateTime() const throw() { return _datetime; } const std::string& DateTime() const { return _datetime; }
/** /**
* @return full file name used to load the geoid data. * @return full file name used to load the geoid data.
********************************************************************** / ********************************************************************** /
const std::string& GeoidFile() const throw() { return _filename; } const std::string& GeoidFile() const { return _filename; }
/** /**
* @return "name" used to load the geoid data (from the first argument of * @return "name" used to load the geoid data (from the first argument of
* the constructor). * the constructor).
********************************************************************** / ********************************************************************** /
const std::string& GeoidName() const throw() { return _name; } const std::string& GeoidName() const { return _name; }
/** /**
* @return directory used to load the geoid data. * @return directory used to load the geoid data.
********************************************************************** / ********************************************************************** /
const std::string& GeoidDirectory() const throw() { return _dir; } const std::string& GeoidDirectory() const { return _dir; }
/** /**
* @return interpolation method ("cubic" or "bilinear"). * @return interpolation method ("cubic" or "bilinear").
********************************************************************** / ********************************************************************** /
const std::string Interpolation() const const std::string Interpolation() const
{ return std::string(_cubic ? "cubic" : "bilinear"); } { return std::string(_cubic ? "cubic" : "bilinear"); }
/** /**
* @return estimate of the maximum interpolation and quantization error * @return estimate of the maximum interpolation and quantization error
* (meters). * (meters).
* *
* This relies on the value being stored in the data file. If the valu e is * This relies on the value being stored in the data file. If the valu e is
* absent, return &minus;1. * absent, return &minus;1.
********************************************************************** / ********************************************************************** /
Math::real MaxError() const throw() { return _maxerror; } Math::real MaxError() const { return _maxerror; }
/** /**
* @return estimate of the RMS interpolation and quantization error * @return estimate of the RMS interpolation and quantization error
* (meters). * (meters).
* *
* This relies on the value being stored in the data file. If the valu e is * This relies on the value being stored in the data file. If the valu e is
* absent, return &minus;1. * absent, return &minus;1.
********************************************************************** / ********************************************************************** /
Math::real RMSError() const throw() { return _rmserror; } Math::real RMSError() const { return _rmserror; }
/** /**
* @return offset (meters). * @return offset (meters).
* *
* This in used in converting from the pixel values in the data file to * This in used in converting from the pixel values in the data file to
* geoid heights. * geoid heights.
********************************************************************** / ********************************************************************** /
Math::real Offset() const throw() { return _offset; } Math::real Offset() const { return _offset; }
/** /**
* @return scale (meters). * @return scale (meters).
* *
* This in used in converting from the pixel values in the data file to * This in used in converting from the pixel values in the data file to
* geoid heights. * geoid heights.
********************************************************************** / ********************************************************************** /
Math::real Scale() const throw() { return _scale; } Math::real Scale() const { return _scale; }
/** /**
* @return true if the object is constructed to be thread safe. * @return true if the object is constructed to be thread safe.
********************************************************************** / ********************************************************************** /
bool ThreadSafe() const throw() { return _threadsafe; } bool ThreadSafe() const { return _threadsafe; }
/** /**
* @return true if a data cache is active. * @return true if a data cache is active.
********************************************************************** / ********************************************************************** /
bool Cache() const throw() { return _cache; } bool Cache() const { return _cache; }
/** /**
* @return west edge of the cached area; the cache includes this edge. * @return west edge of the cached area; the cache includes this edge.
********************************************************************** / ********************************************************************** /
Math::real CacheWest() const throw() { Math::real CacheWest() const {
return _cache ? ((_xoffset + (_xsize == _width ? 0 : _cubic) return _cache ? ((_xoffset + (_xsize == _width ? 0 : _cubic)
+ _width/2) % _width - _width/2) / _rlonres : + _width/2) % _width - _width/2) / _rlonres :
0; 0;
} }
/** /**
* @return east edge of the cached area; the cache excludes this edge. * @return east edge of the cached area; the cache excludes this edge.
********************************************************************** / ********************************************************************** /
Math::real CacheEast() const throw() { Math::real CacheEast() const {
return _cache ? return _cache ?
CacheWest() + CacheWest() +
(_xsize - (_xsize == _width ? 0 : 1 + 2 * _cubic)) / _rlonres : (_xsize - (_xsize == _width ? 0 : 1 + 2 * _cubic)) / _rlonres :
0; 0;
} }
/** /**
* @return north edge of the cached area; the cache includes this edge. * @return north edge of the cached area; the cache includes this edge.
********************************************************************** / ********************************************************************** /
Math::real CacheNorth() const throw() { Math::real CacheNorth() const {
return _cache ? 90 - (_yoffset + _cubic) / _rlatres : 0; return _cache ? 90 - (_yoffset + _cubic) / _rlatres : 0;
} }
/** /**
* @return south edge of the cached area; the cache excludes this edge * @return south edge of the cached area; the cache excludes this edge
* unless it's the south pole. * unless it's the south pole.
********************************************************************** / ********************************************************************** /
Math::real CacheSouth() const throw() { Math::real CacheSouth() const {
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() Math::real MajorRadius() const
{ return Constants::WGS84_a<real>(); } { return Constants::WGS84_a<real>(); }
/** /**
* @return \e f the flattening of the WGS84 ellipsoid. * @return \e f the 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 Flattening() const throw() { return Constants::WGS84_f<real> (); } Math::real Flattening() const { return Constants::WGS84_f<real>(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the WGS84 ellipsoid. * @return \e r the inverse flattening of the WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return 1/Constants::WGS84_f<real>(); } { return 1/Constants::WGS84_f<real>(); }
/// \endcond /// \endcond
/** /**
* @return the default path for geoid data files. * @return the default path for geoid data files.
* *
* This is the value of the environment variable GEOID_PATH, if set; * This is the value of the environment variable GEOID_PATH, if set;
* otherwise, it is $GEOGRAPHICLIB_DATA/geoids if the environment varia ble * otherwise, it is $GEOGRAPHICLIB_DATA/geoids if the environment varia ble
* GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default * GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default
* (/usr/local/share/GeographicLib/geoids on non-Windows systems and * (/usr/local/share/GeographicLib/geoids on non-Windows systems and
 End of changes. 19 change blocks. 
19 lines changed or deleted 19 lines changed or added


 Gnomonic.hpp   Gnomonic.hpp 
skipping to change at line 118 skipping to change at line 118
static const int numit_ = 10; static const int numit_ = 10;
public: public:
/** /**
* Constructor for Gnomonic. * Constructor for Gnomonic.
* *
* @param[in] earth the Geodesic object to use for geodesic calculation s. * @param[in] earth the Geodesic object to use for geodesic calculation s.
* By default this uses the WGS84 ellipsoid. * By default this uses the WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
explicit Gnomonic(const Geodesic& earth = Geodesic::WGS84) explicit Gnomonic(const Geodesic& earth = Geodesic::WGS84)
throw()
: _earth(earth) : _earth(earth)
, _a(_earth.MajorRadius()) , _a(_earth.MajorRadius())
, _f(_earth.Flattening()) , _f(_earth.Flattening())
{} {}
/** /**
* Forward projection, from geographic to gnomonic. * Forward projection, from geographic to gnomonic.
* *
* @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lat0 latitude of center point of projection (degrees).
* @param[in] lon0 longitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees).
skipping to change at line 147 skipping to change at line 146
* \e lon0 and \e lon should be in the range [&minus;540&deg;, 540&deg; ). * \e lon0 and \e lon should be in the range [&minus;540&deg;, 540&deg; ).
* The scale of the projection is 1/<i>rk</i><sup>2</sup> in the "radia l" * The scale of the projection is 1/<i>rk</i><sup>2</sup> in the "radia l"
* direction, \e azi clockwise from true north, and is 1/\e rk in the * direction, \e azi clockwise from true north, and is 1/\e rk in the
* direction perpendicular to this. If the point lies "over the horizo n", * direction perpendicular to this. If the point lies "over the horizo n",
* i.e., if \e rk &le; 0, then NaNs are returned for \e x and \e y (the * i.e., if \e rk &le; 0, then NaNs are returned for \e x and \e y (the
* correct values are returned for \e azi and \e rk). A call to Forwar d * correct values are returned for \e azi and \e rk). A call to Forwar d
* followed by a call to Reverse will return the original (\e lat, \e l on) * followed by a call to Reverse will return the original (\e lat, \e l on)
* (to within roundoff) provided the point in not over the horizon. * (to within roundoff) provided the point in not over the horizon.
********************************************************************** / ********************************************************************** /
void Forward(real lat0, real lon0, real lat, real lon, void Forward(real lat0, real lon0, real lat, real lon,
real& x, real& y, real& azi, real& rk) const throw(); real& x, real& y, real& azi, real& rk) const;
/** /**
* Reverse projection, from gnomonic to geographic. * Reverse projection, from gnomonic to geographic.
* *
* @param[in] lat0 latitude of center point of projection (degrees). * @param[in] lat0 latitude of center point of projection (degrees).
* @param[in] lon0 longitude of center point of projection (degrees). * @param[in] lon0 longitude of center point of projection (degrees).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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).
skipping to change at line 174 skipping to change at line 173
* be in the range [&minus;180&deg;, 180&deg;). The scale of the * be in the range [&minus;180&deg;, 180&deg;). The scale of the
* projection is 1/\e rk<sup>2</sup> in the "radial" direction, \e azi * projection is 1/\e rk<sup>2</sup> in the "radial" direction, \e azi
* clockwise from true north, and is 1/\e rk in the direction perpendic ular * clockwise from true north, and is 1/\e rk in the direction perpendic ular
* to this. Even though all inputs should return a valid \e lat and \e * to this. Even though all inputs should return a valid \e lat and \e
* lon, it's possible that the procedure fails to converge for very lar ge * lon, it's possible that the procedure fails to converge for very lar ge
* \e x or \e y; in this case NaNs are returned for all the output * \e x or \e y; in this case NaNs are returned for all the output
* arguments. A call to Reverse followed by a call to Forward will ret urn * arguments. A call to Reverse followed by a call to Forward will ret urn
* the original (\e x, \e y) (to roundoff). * the original (\e x, \e y) (to roundoff).
********************************************************************** / ********************************************************************** /
void Reverse(real lat0, real lon0, real x, real y, void Reverse(real lat0, real lon0, real x, real y,
real& lat, real& lon, real& azi, real& rk) const throw(); real& lat, real& lon, real& azi, real& rk) const;
/** /**
* Gnomonic::Forward without returning the azimuth and scale. * Gnomonic::Forward without returning the azimuth and scale.
********************************************************************** / ********************************************************************** /
void Forward(real lat0, real lon0, real lat, real lon, void Forward(real lat0, real lon0, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real azi, rk; real azi, rk;
Forward(lat0, lon0, lat, lon, x, y, azi, rk); Forward(lat0, lon0, lat, lon, x, y, azi, rk);
} }
/** /**
* Gnomonic::Reverse without returning the azimuth and scale. * Gnomonic::Reverse without returning the azimuth and scale.
********************************************************************** / ********************************************************************** /
void Reverse(real lat0, real lon0, real x, real y, void Reverse(real lat0, real lon0, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real azi, rk; real azi, rk;
Reverse(lat0, lon0, x, y, lat, lon, azi, rk); Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
} }
/** \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 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 _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geodesic object used in the constructor. * inherited from the Geodesic object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return _earth.InverseFlattening(); } { return _earth.InverseFlattening(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_GNOMONIC_HPP #endif // GEOGRAPHICLIB_GNOMONIC_HPP
 End of changes. 8 change blocks. 
8 lines changed or deleted 7 lines changed or added


 GravityCircle.hpp   GravityCircle.hpp 
skipping to change at line 93 skipping to change at line 93
, _gamma0(gamma0) , _gamma0(gamma0)
, _gamma(gamma) , _gamma(gamma)
, _frot(frot) , _frot(frot)
, _gravitational(gravitational) , _gravitational(gravitational)
, _disturbing(disturbing) , _disturbing(disturbing)
, _correction(correction) , _correction(correction)
{} {}
friend class GravityModel; // GravityModel calls the private constructo r friend class GravityModel; // GravityModel calls the private constructo r
Math::real W(real clam, real slam, Math::real W(real clam, real slam,
real& gX, real& gY, real& gZ) const throw(); real& gX, real& gY, real& gZ) const;
Math::real V(real clam, real slam, Math::real V(real clam, real slam,
real& gX, real& gY, real& gZ) const throw(); real& gX, real& gY, real& gZ) const;
Math::real InternalT(real clam, real slam, Math::real InternalT(real clam, real slam,
real& deltaX, real& deltaY, real& deltaZ, real& deltaX, real& deltaY, real& deltaZ,
bool gradp, bool correct) const throw(); bool gradp, bool correct) const;
public: public:
/** /**
* A default constructor for the normal gravity. This sets up an * A default constructor for the normal gravity. This sets up an
* uninitialized object which can be later replaced by the * uninitialized object which can be later replaced by the
* GravityModel::Circle. * GravityModel::Circle.
********************************************************************** / ********************************************************************** /
GravityCircle() : _a(-1) {} GravityCircle() : _a(-1) {}
/** \name Compute the gravitational field /** \name Compute the gravitational field
********************************************************************** / ********************************************************************** /
skipping to change at line 124 skipping to change at line 124
* @param[out] gx the easterly component of the acceleration * @param[out] gx the easterly component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gy the northerly component of the acceleration * @param[out] gy the northerly component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gz the upward component of the acceleration * @param[out] gz the upward component of the acceleration
* (m s<sup>&minus;2</sup>); this is usually negative. * (m s<sup>&minus;2</sup>); this is usually negative.
* @return \e W the sum of the gravitational and centrifugal potentials . * @return \e W the sum of the gravitational and centrifugal potentials .
* *
* The function includes the effects of the earth's rotation. * The function includes the effects of the earth's rotation.
********************************************************************** / ********************************************************************** /
Math::real Gravity(real lon, real& gx, real& gy, real& gz) const throw( ); Math::real Gravity(real lon, real& gx, real& gy, real& gz) const;
/** /**
* Evaluate the gravity disturbance vector. * Evaluate the gravity disturbance vector.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[out] deltax the easterly component of the disturbance vector * @param[out] deltax the easterly component of the disturbance vector
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltay the northerly component of the disturbance vector * @param[out] deltay the northerly component of the disturbance vector
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltaz the upward component of the disturbance vector * @param[out] deltaz the upward component of the disturbance vector
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e T the corresponding disturbing potential. * @return \e T the corresponding disturbing potential.
********************************************************************** / ********************************************************************** /
Math::real Disturbance(real lon, real& deltax, real& deltay, real& delt az) Math::real Disturbance(real lon, real& deltax, real& deltay, real& delt az)
const throw(); const;
/** /**
* Evaluate the geoid height. * Evaluate the geoid height.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @return \e N the height of the geoid above the reference ellipsoid * @return \e N the height of the geoid above the reference ellipsoid
* (meters). * (meters).
* *
* Some approximations are made in computing the geoid height so that t he * Some approximations are made in computing the geoid height so that t he
* results of the NGA codes are reproduced accurately. Details are giv en * results of the NGA codes are reproduced accurately. Details are giv en
* in \ref gravitygeoid. * in \ref gravitygeoid.
********************************************************************** / ********************************************************************** /
Math::real GeoidHeight(real lon) const throw(); Math::real GeoidHeight(real lon) const;
/** /**
* Evaluate the components of the gravity anomaly vector using the * Evaluate the components of the gravity anomaly vector using the
* spherical approximation. * spherical approximation.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[out] Dg01 the gravity anomaly (m s<sup>&minus;2</sup>). * @param[out] Dg01 the gravity anomaly (m s<sup>&minus;2</sup>).
* @param[out] xi the northerly component of the deflection of the vert ical * @param[out] xi the northerly component of the deflection of the vert ical
* (degrees). * (degrees).
* @param[out] eta the easterly component of the deflection of the vert ical * @param[out] eta the easterly component of the deflection of the vert ical
* (degrees). * (degrees).
* *
* The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used * The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used
* so that the results of the NGA codes are reproduced accurately. * so that the results of the NGA codes are reproduced accurately.
* approximations used here. Details are given in \ref gravitygeoid. * approximations used here. Details are given in \ref gravitygeoid.
********************************************************************** / ********************************************************************** /
void SphericalAnomaly(real lon, real& Dg01, real& xi, real& eta) void SphericalAnomaly(real lon, real& Dg01, real& xi, real& eta)
const throw(); const;
/** /**
* Evaluate the components of the acceleration due to gravity and the * Evaluate the components of the acceleration due to gravity and the
* centrifugal acceleration in geocentric coordinates. * centrifugal acceleration in geocentric coordinates.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[out] gX the \e X component of the acceleration * @param[out] gX the \e X component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gY the \e Y component of the acceleration * @param[out] gY the \e Y component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gZ the \e Z component of the acceleration * @param[out] gZ the \e Z component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e W = \e V + &Phi; the sum of the gravitational and * @return \e W = \e V + &Phi; the sum of the gravitational and
* centrifugal potentials (m<sup>2</sup> s<sup>&minus;2</sup>). * centrifugal potentials (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real W(real lon, real& gX, real& gY, real& gZ) const throw() { Math::real W(real lon, real& gX, real& gY, real& gZ) const {
real clam, slam; real clam, slam;
CircularEngine::cossin(lon, clam, slam); CircularEngine::cossin(lon, clam, slam);
return W(clam, slam, gX, gY, gZ); return W(clam, slam, gX, gY, gZ);
} }
/** /**
* Evaluate the components of the acceleration due to gravity in geocen tric * Evaluate the components of the acceleration due to gravity in geocen tric
* coordinates. * coordinates.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[out] GX the \e X component of the acceleration * @param[out] GX the \e X component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] GY the \e Y component of the acceleration * @param[out] GY the \e Y component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] GZ the \e Z component of the acceleration * @param[out] GZ the \e Z component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e V = \e W - &Phi; the gravitational potential * @return \e V = \e W - &Phi; the gravitational potential
* (m<sup>2</sup> s<sup>&minus;2</sup>). * (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real V(real lon, real& GX, real& GY, real& GZ) const throw() { Math::real V(real lon, real& GX, real& GY, real& GZ) const {
real clam, slam; real clam, slam;
CircularEngine::cossin(lon, clam, slam); CircularEngine::cossin(lon, clam, slam);
return V(clam, slam, GX, GY, GZ); return V(clam, slam, GX, GY, GZ);
} }
/** /**
* Evaluate the components of the gravity disturbance in geocentric * Evaluate the components of the gravity disturbance in geocentric
* coordinates. * coordinates.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[out] deltaX the \e X component of the gravity disturbance * @param[out] deltaX the \e X component of the gravity disturbance
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltaY the \e Y component of the gravity disturbance * @param[out] deltaY the \e Y component of the gravity disturbance
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltaZ the \e Z component of the gravity disturbance * @param[out] deltaZ the \e Z component of the gravity disturbance
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e T = \e W - \e U the disturbing potential (also called the * @return \e T = \e W - \e U the disturbing potential (also called the
* anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>). * anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real T(real lon, real& deltaX, real& deltaY, real& deltaZ) Math::real T(real lon, real& deltaX, real& deltaY, real& deltaZ)
const throw() { const {
real clam, slam; real clam, slam;
CircularEngine::cossin(lon, clam, slam); CircularEngine::cossin(lon, clam, slam);
return InternalT(clam, slam, deltaX, deltaY, deltaZ, true, true); return InternalT(clam, slam, deltaX, deltaY, deltaZ, true, true);
} }
/** /**
* Evaluate disturbing potential in geocentric coordinates. * Evaluate disturbing potential in geocentric coordinates.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @return \e T = \e W - \e U the disturbing potential (also called the * @return \e T = \e W - \e U the disturbing potential (also called the
* anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>). * anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real T(real lon) const throw() { Math::real T(real lon) const {
real clam, slam, dummy; real clam, slam, dummy;
CircularEngine::cossin(lon, clam, slam); CircularEngine::cossin(lon, clam, slam);
return InternalT(clam, slam, dummy, dummy, dummy, false, true); return InternalT(clam, slam, dummy, dummy, dummy, false, true);
} }
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _a > 0; } bool Init() const { return _a > 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 GravityModel object used in the * the value inherited from the GravityModel object used in the
* constructor. * constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() Math::real MajorRadius() const
{ return Init() ? _a : Math::NaN<real>(); } { return Init() ? _a : Math::NaN<real>(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the GravityModel object used in the constructor. * inherited from the GravityModel object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
/** /**
* @return the latitude of the circle (degrees). * @return the latitude of the circle (degrees).
********************************************************************** / ********************************************************************** /
Math::real Latitude() const throw() Math::real Latitude() const
{ return Init() ? _lat : Math::NaN<real>(); } { return Init() ? _lat : Math::NaN<real>(); }
/** /**
* @return the height of the circle (meters). * @return the height of the circle (meters).
********************************************************************** / ********************************************************************** /
Math::real Height() const throw() Math::real Height() const
{ return Init() ? _h : Math::NaN<real>(); } { return Init() ? _h : Math::NaN<real>(); }
/** /**
* @return \e caps the computational capabilities that this object was * @return \e caps the computational capabilities that this object was
* constructed with. * constructed with.
********************************************************************** / ********************************************************************** /
unsigned Capabilities() const throw() { return _caps; } unsigned Capabilities() const { return _caps; }
/** /**
* @param[in] testcaps a set of bitor'ed GeodesicLine::mask values. * @param[in] testcaps a set of bitor'ed GeodesicLine::mask values.
* @return true if the GeodesicLine object has all these capabilities. * @return true if the GeodesicLine object has all these capabilities.
********************************************************************** / ********************************************************************** /
bool Capabilities(unsigned testcaps) const throw() { bool Capabilities(unsigned testcaps) const {
return (_caps & testcaps) == testcaps; return (_caps & testcaps) == testcaps;
} }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_GRAVITYCIRCLE_HPP #endif // GEOGRAPHICLIB_GRAVITYCIRCLE_HPP
 End of changes. 18 change blocks. 
18 lines changed or deleted 18 lines changed or added


 GravityModel.hpp   GravityModel.hpp 
skipping to change at line 100 skipping to change at line 100
SphericalHarmonic::normalization _norm; SphericalHarmonic::normalization _norm;
NormalGravity _earth; NormalGravity _earth;
std::vector<real> _Cx, _Sx, _CC, _CS, _zonal; std::vector<real> _Cx, _Sx, _CC, _CS, _zonal;
real _dzonal0; // A left over contribution to _zonal. real _dzonal0; // A left over contribution to _zonal.
SphericalHarmonic _gravitational; SphericalHarmonic _gravitational;
SphericalHarmonic1 _disturbing; SphericalHarmonic1 _disturbing;
SphericalHarmonic _correction; SphericalHarmonic _correction;
void ReadMetadata(const std::string& name); void ReadMetadata(const std::string& name);
Math::real InternalT(real X, real Y, real Z, Math::real InternalT(real X, real Y, real Z,
real& deltaX, real& deltaY, real& deltaZ, real& deltaX, real& deltaY, real& deltaZ,
bool gradp, bool correct) const throw(); bool gradp, bool correct) const;
GravityModel(const GravityModel&); // copy constructor not allowed GravityModel(const GravityModel&); // copy constructor not allowed
GravityModel& operator=(const GravityModel&); // nor copy assignment GravityModel& operator=(const GravityModel&); // nor copy assignment
enum captype { enum captype {
CAP_NONE = 0U, CAP_NONE = 0U,
CAP_G = 1U<<0, // implies potentials W and V CAP_G = 1U<<0, // implies potentials W and V
CAP_T = 1U<<1, CAP_T = 1U<<1,
CAP_DELTA = 1U<<2 | CAP_T, // delta implies T? CAP_DELTA = 1U<<2 | CAP_T, // delta implies T?
CAP_C = 1U<<3, CAP_C = 1U<<3,
CAP_GAMMA0 = 1U<<4, CAP_GAMMA0 = 1U<<4,
skipping to change at line 208 skipping to change at line 208
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gy the northerly component of the acceleration * @param[out] gy the northerly component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gz the upward component of the acceleration * @param[out] gz the upward component of the acceleration
* (m s<sup>&minus;2</sup>); this is usually negative. * (m s<sup>&minus;2</sup>); this is usually negative.
* @return \e W the sum of the gravitational and centrifugal potentials . * @return \e W the sum of the gravitational and centrifugal potentials .
* *
* The function includes the effects of the earth's rotation. * The function includes the effects of the earth's rotation.
********************************************************************** / ********************************************************************** /
Math::real Gravity(real lat, real lon, real h, Math::real Gravity(real lat, real lon, real h,
real& gx, real& gy, real& gz) const throw(); real& gx, real& gy, real& gz) const;
/** /**
* Evaluate the gravity disturbance vector at an arbitrary point above (or * Evaluate the gravity disturbance vector at an arbitrary point above (or
* below) the ellipsoid. * below) the ellipsoid.
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[in] h the height above the ellipsoid (meters). * @param[in] h the height above the ellipsoid (meters).
* @param[out] deltax the easterly component of the disturbance vector * @param[out] deltax the easterly component of the disturbance vector
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltay the northerly component of the disturbance vector * @param[out] deltay the northerly component of the disturbance vector
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltaz the upward component of the disturbance vector * @param[out] deltaz the upward component of the disturbance vector
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e T the corresponding disturbing potential. * @return \e T the corresponding disturbing potential.
********************************************************************** / ********************************************************************** /
Math::real Disturbance(real lat, real lon, real h, Math::real Disturbance(real lat, real lon, real h,
real& deltax, real& deltay, real& deltaz) real& deltax, real& deltay, real& deltaz)
const throw(); const;
/** /**
* Evaluate the geoid height. * Evaluate the geoid height.
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @return \e N the height of the geoid above the ReferenceEllipsoid() * @return \e N the height of the geoid above the ReferenceEllipsoid()
* (meters). * (meters).
* *
* This calls NormalGravity::U for ReferenceEllipsoid(). Some * This calls NormalGravity::U for ReferenceEllipsoid(). Some
* approximations are made in computing the geoid height so that the * approximations are made in computing the geoid height so that the
* results of the NGA codes are reproduced accurately. Details are giv en * results of the NGA codes are reproduced accurately. Details are giv en
* in \ref gravitygeoid. * in \ref gravitygeoid.
********************************************************************** / ********************************************************************** /
Math::real GeoidHeight(real lat, real lon) const throw(); Math::real GeoidHeight(real lat, real lon) const;
/** /**
* Evaluate the components of the gravity anomaly vector using the * Evaluate the components of the gravity anomaly vector using the
* spherical approximation. * spherical approximation.
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[in] h the height above the ellipsoid (meters). * @param[in] h the height above the ellipsoid (meters).
* @param[out] Dg01 the gravity anomaly (m s<sup>&minus;2</sup>). * @param[out] Dg01 the gravity anomaly (m s<sup>&minus;2</sup>).
* @param[out] xi the northerly component of the deflection of the vert ical * @param[out] xi the northerly component of the deflection of the vert ical
* (degrees). * (degrees).
* @param[out] eta the easterly component of the deflection of the vert ical * @param[out] eta the easterly component of the deflection of the vert ical
* (degrees). * (degrees).
* *
* The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used * The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used
* so that the results of the NGA codes are reproduced accurately. * so that the results of the NGA codes are reproduced accurately.
* approximations used here. Details are given in \ref gravitygeoid. * approximations used here. Details are given in \ref gravitygeoid.
********************************************************************** / ********************************************************************** /
void SphericalAnomaly(real lat, real lon, real h, void SphericalAnomaly(real lat, real lon, real h,
real& Dg01, real& xi, real& eta) const throw(); real& Dg01, real& xi, real& eta) const;
///@} ///@}
/** \name Compute gravity in geocentric coordinates /** \name Compute gravity in geocentric coordinates
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Evaluate the components of the acceleration due to gravity and the * Evaluate the components of the acceleration due to gravity and the
* centrifugal acceleration in geocentric coordinates. * centrifugal acceleration in geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
skipping to change at line 287 skipping to change at line 287
* @param[out] gY the \e Y component of the acceleration * @param[out] gY the \e Y component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gZ the \e Z component of the acceleration * @param[out] gZ the \e Z component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e W = \e V + &Phi; the sum of the gravitational and * @return \e W = \e V + &Phi; the sum of the gravitational and
* centrifugal potentials (m<sup>2</sup> s<sup>&minus;2</sup>). * centrifugal potentials (m<sup>2</sup> s<sup>&minus;2</sup>).
* *
* This calls NormalGravity::U for ReferenceEllipsoid(). * This calls NormalGravity::U for ReferenceEllipsoid().
********************************************************************** / ********************************************************************** /
Math::real W(real X, real Y, real Z, Math::real W(real X, real Y, real Z,
real& gX, real& gY, real& gZ) const throw(); real& gX, real& gY, real& gZ) const;
/** /**
* Evaluate the components of the acceleration due to gravity in geocen tric * Evaluate the components of the acceleration due to gravity in geocen tric
* coordinates. * coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[in] Z geocentric coordinate of point (meters). * @param[in] Z geocentric coordinate of point (meters).
* @param[out] GX the \e X component of the acceleration * @param[out] GX the \e X component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] GY the \e Y component of the acceleration * @param[out] GY the \e Y component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] GZ the \e Z component of the acceleration * @param[out] GZ the \e Z component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e V = \e W - &Phi; the gravitational potential * @return \e V = \e W - &Phi; the gravitational potential
* (m<sup>2</sup> s<sup>&minus;2</sup>). * (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real V(real X, real Y, real Z, Math::real V(real X, real Y, real Z,
real& GX, real& GY, real& GZ) const throw(); real& GX, real& GY, real& GZ) const;
/** /**
* Evaluate the components of the gravity disturbance in geocentric * Evaluate the components of the gravity disturbance in geocentric
* coordinates. * coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[in] Z geocentric coordinate of point (meters). * @param[in] Z geocentric coordinate of point (meters).
* @param[out] deltaX the \e X component of the gravity disturbance * @param[out] deltaX the \e X component of the gravity disturbance
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltaY the \e Y component of the gravity disturbance * @param[out] deltaY the \e Y component of the gravity disturbance
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] deltaZ the \e Z component of the gravity disturbance * @param[out] deltaZ the \e Z component of the gravity disturbance
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e T = \e W - \e U the disturbing potential (also called the * @return \e T = \e W - \e U the disturbing potential (also called the
* anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>). * anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real T(real X, real Y, real Z, Math::real T(real X, real Y, real Z,
real& deltaX, real& deltaY, real& deltaZ) const throw() real& deltaX, real& deltaY, real& deltaZ) const
{ return InternalT(X, Y, Z, deltaX, deltaY, deltaZ, true, true); } { return InternalT(X, Y, Z, deltaX, deltaY, deltaZ, true, true); }
/** /**
* Evaluate disturbing potential in geocentric coordinates. * Evaluate disturbing potential in geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[in] Z geocentric coordinate of point (meters). * @param[in] Z geocentric coordinate of point (meters).
* @return \e T = \e W - \e U the disturbing potential (also called the * @return \e T = \e W - \e U the disturbing potential (also called the
* anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>). * anomalous potential) (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real T(real X, real Y, real Z) const throw() { Math::real T(real X, real Y, real Z) const {
real dummy; real dummy;
return InternalT(X, Y, Z, dummy, dummy, dummy, false, true); return InternalT(X, Y, Z, dummy, dummy, dummy, false, true);
} }
/** /**
* Evaluate the components of the acceleration due to normal gravity an d * Evaluate the components of the acceleration due to normal gravity an d
* the centrifugal acceleration in geocentric coordinates. * the centrifugal acceleration in geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
skipping to change at line 362 skipping to change at line 362
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gammaZ the \e Z component of the normal acceleration * @param[out] gammaZ the \e Z component of the normal acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e U = <i>V</i><sub>0</sub> + &Phi; the sum of the * @return \e U = <i>V</i><sub>0</sub> + &Phi; the sum of the
* normal gravitational and centrifugal potentials * normal gravitational and centrifugal potentials
* (m<sup>2</sup> s<sup>&minus;2</sup>). * (m<sup>2</sup> s<sup>&minus;2</sup>).
* *
* This calls NormalGravity::U for ReferenceEllipsoid(). * This calls NormalGravity::U for ReferenceEllipsoid().
********************************************************************** / ********************************************************************** /
Math::real U(real X, real Y, real Z, Math::real U(real X, real Y, real Z,
real& gammaX, real& gammaY, real& gammaZ) const throw() real& gammaX, real& gammaY, real& gammaZ) const
{ return _earth.U(X, Y, Z, gammaX, gammaY, gammaZ); } { return _earth.U(X, Y, Z, gammaX, gammaY, gammaZ); }
/** /**
* Evaluate the centrifugal acceleration in geocentric coordinates. * Evaluate the centrifugal acceleration in geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[out] fX the \e X component of the centrifugal acceleration * @param[out] fX the \e X component of the centrifugal acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] fY the \e Y component of the centrifugal acceleration * @param[out] fY the \e Y component of the centrifugal acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return &Phi; the centrifugal potential (m<sup>2</sup> * @return &Phi; the centrifugal potential (m<sup>2</sup>
* s<sup>&minus;2</sup>). * s<sup>&minus;2</sup>).
* *
* This calls NormalGravity::Phi for ReferenceEllipsoid(). * This calls NormalGravity::Phi for ReferenceEllipsoid().
********************************************************************** / ********************************************************************** /
Math::real Phi(real X, real Y, real& fX, real& fY) const throw() Math::real Phi(real X, real Y, real& fX, real& fY) const
{ return _earth.Phi(X, Y, fX, fY); } { return _earth.Phi(X, Y, fX, fY); }
///@} ///@}
/** \name Compute gravity on a circle of constant latitude /** \name Compute gravity on a circle of constant latitude
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Create a GravityCircle object to allow the gravity field at many poi nts * Create a GravityCircle object to allow the gravity field at many poi nts
* with constant \e lat and \e h and varying \e lon to be computed * with constant \e lat and \e h and varying \e lon to be computed
* efficiently. * efficiently.
skipping to change at line 428 skipping to change at line 428
GravityCircle Circle(real lat, real h, unsigned caps = ALL) const; GravityCircle Circle(real lat, real h, unsigned caps = ALL) const;
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return the NormalGravity object for the reference ellipsoid. * @return the NormalGravity object for the reference ellipsoid.
********************************************************************** / ********************************************************************** /
const NormalGravity& ReferenceEllipsoid() const throw() { return _earth ; } const NormalGravity& ReferenceEllipsoid() const { return _earth; }
/** /**
* @return the description of the gravity model, if available, in the d ata * @return the description of the gravity model, if available, in the d ata
* file; if absent, return "NONE". * file; if absent, return "NONE".
********************************************************************** / ********************************************************************** /
const std::string& Description() const throw() { return _description; } const std::string& Description() const { return _description; }
/** /**
* @return date of the model; if absent, return "UNKNOWN". * @return date of the model; if absent, return "UNKNOWN".
********************************************************************** / ********************************************************************** /
const std::string& DateTime() const throw() { return _date; } const std::string& DateTime() const { return _date; }
/** /**
* @return full file name used to load the gravity model. * @return full file name used to load the gravity model.
********************************************************************** / ********************************************************************** /
const std::string& GravityFile() const throw() { return _filename; } const std::string& GravityFile() const { return _filename; }
/** /**
* @return "name" used to load the gravity model (from the first argume nt * @return "name" used to load the gravity model (from the first argume nt
* of the constructor, but this may be overridden by the model file). * of the constructor, but this may be overridden by the model file).
********************************************************************** / ********************************************************************** /
const std::string& GravityModelName() const throw() { return _name; } const std::string& GravityModelName() const { return _name; }
/** /**
* @return directory used to load the gravity model. * @return directory used to load the gravity model.
********************************************************************** / ********************************************************************** /
const std::string& GravityModelDirectory() const throw() { return _dir; } const std::string& GravityModelDirectory() const { return _dir; }
/** /**
* @return \e a the equatorial radius of the ellipsoid (meters). * @return \e a the equatorial radius of the ellipsoid (meters).
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() { return _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e GM the mass constant of the model (m<sup>3</sup> * @return \e GM the mass constant of the model (m<sup>3</sup>
* s<sup>&minus;2</sup>); this is the product of \e G the gravitation al * s<sup>&minus;2</sup>); this is the product of \e G the gravitation al
* constant and \e M the mass of the earth (usually including the mas s of * constant and \e M the mass of the earth (usually including the mas s of
* the earth's atmosphere). * the earth's atmosphere).
********************************************************************** / ********************************************************************** /
Math::real MassConstant() const throw() { return _GMmodel; } Math::real MassConstant() const { return _GMmodel; }
/** /**
* @return \e GM the mass constant of the ReferenceEllipsoid() * @return \e GM the mass constant of the ReferenceEllipsoid()
* (m<sup>3</sup> s<sup>&minus;2</sup>). * (m<sup>3</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real ReferenceMassConstant() const throw() Math::real ReferenceMassConstant() const
{ return _earth.MassConstant(); } { return _earth.MassConstant(); }
/** /**
* @return &omega; the angular velocity of the model and the * @return &omega; the angular velocity of the model and the
* ReferenceEllipsoid() (rad s<sup>&minus;1</sup>). * ReferenceEllipsoid() (rad s<sup>&minus;1</sup>).
********************************************************************** / ********************************************************************** /
Math::real AngularVelocity() const throw() Math::real AngularVelocity() const
{ return _earth.AngularVelocity(); } { return _earth.AngularVelocity(); }
/** /**
* @return \e f the flattening of the ellipsoid. * @return \e f the flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
///@} ///@}
/** /**
* @return the default path for gravity model data files. * @return the default path for gravity model data files.
* *
* This is the value of the environment variable GRAVITY_PATH, if set; * This is the value of the environment variable GRAVITY_PATH, if set;
* otherwise, it is $GEOGRAPHICLIB_DATA/gravity if the environment vari able * otherwise, it is $GEOGRAPHICLIB_DATA/gravity if the environment vari able
* GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default * GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time default
* (/usr/local/share/GeographicLib/gravity on non-Windows systems and * (/usr/local/share/GeographicLib/gravity on non-Windows systems and
* C:/Documents and Settings/All Users/Application * C:/Documents and Settings/All Users/Application
 End of changes. 22 change blocks. 
22 lines changed or deleted 22 lines changed or added


 LambertConformalConic.hpp   LambertConformalConic.hpp 
skipping to change at line 68 skipping to change at line 68
private: private:
typedef Math::real real; typedef Math::real real;
real _a, _f, _fm, _e2, _e, _e2m; real _a, _f, _fm, _e2, _e, _e2m;
real _sign, _n, _nc, _t0nm1, _scale, _lat0, _k0; real _sign, _n, _nc, _t0nm1, _scale, _lat0, _k0;
real _scbet0, _tchi0, _scchi0, _psi0, _nrho0, _drhomax; real _scbet0, _tchi0, _scchi0, _psi0, _nrho0, _drhomax;
static const real eps_; static const real eps_;
static const real epsx_; static const real epsx_;
static const real tol_; static const real tol_;
static const real ahypover_; static const real ahypover_;
static const int numit_ = 5; static const int numit_ = 5;
static inline real hyp(real x) throw() { return Math::hypot(real(1), x) ; } static inline real hyp(real x) { return Math::hypot(real(1), x); }
// e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0 // e * atanh(e * x) = log( ((1 + e*x)/(1 - e*x))^(e/2) ) if f >= 0
// - sqrt(-e2) * atan( sqrt(-e2) * x) if f < 0 // - sqrt(-e2) * atan( sqrt(-e2) * x) if f < 0
inline real eatanhe(real x) const throw() inline real eatanhe(real x) const
{ return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); } { return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); }
// Divided differences // Divided differences
// Definition: Df(x,y) = (f(x)-f(y))/(x-y) // Definition: Df(x,y) = (f(x)-f(y))/(x-y)
// See: // See:
// W. M. Kahan and R. J. Fateman, // W. M. Kahan and R. J. Fateman,
// Symbolic computation of divided differences, // Symbolic computation of divided differences,
// SIGSAM Bull. 33(3), 7-28 (1999) // SIGSAM Bull. 33(3), 7-28 (1999)
// http://dx.doi.org/10.1145/334714.334716 // http://dx.doi.org/10.1145/334714.334716
// http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf // http://www.cs.berkeley.edu/~fateman/papers/divdiff.pdf
// //
// General rules // General rules
// h(x) = f(g(x)): Dh(x,y) = Df(g(x),g(y))*Dg(x,y) // h(x) = f(g(x)): Dh(x,y) = Df(g(x),g(y))*Dg(x,y)
// h(x) = f(x)*g(x): // h(x) = f(x)*g(x):
// Dh(x,y) = Df(x,y)*g(x) + Dg(x,y)*f(y) // Dh(x,y) = Df(x,y)*g(x) + Dg(x,y)*f(y)
// = Df(x,y)*g(y) + Dg(x,y)*f(x) // = Df(x,y)*g(y) + Dg(x,y)*f(x)
// = Df(x,y)*(g(x)+g(y))/2 + Dg(x,y)*(f(x)+f(y))/2 // = Df(x,y)*(g(x)+g(y))/2 + Dg(x,y)*(f(x)+f(y))/2
// //
// hyp(x) = sqrt(1+x^2): Dhyp(x,y) = (x+y)/(hyp(x)+hyp(y)) // hyp(x) = sqrt(1+x^2): Dhyp(x,y) = (x+y)/(hyp(x)+hyp(y))
static inline real Dhyp(real x, real y, real hx, real hy) throw() static inline real Dhyp(real x, real y, real hx, real hy)
// hx = hyp(x) // hx = hyp(x)
{ return (x + y) / (hx + hy); } { return (x + y) / (hx + hy); }
// sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^ 2)) // sn(x) = x/sqrt(1+x^2): Dsn(x,y) = (x+y)/((sn(x)+sn(y))*(1+x^2)*(1+y^ 2))
static inline real Dsn(real x, real y, real sx, real sy) throw() { static inline real Dsn(real x, real y, real sx, real sy) {
// sx = x/hyp(x) // sx = x/hyp(x)
real t = x * y; real t = x * y;
return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) : return t > 0 ? (x + y) * Math::sq( (sx * sy)/t ) / (sx + sy) :
(x - y != 0 ? (sx - sy) / (x - y) : 1); (x - y != 0 ? (sx - sy) / (x - y) : 1);
} }
// Dlog1p(x,y) = log1p((x-y)/(1+y)/(x-y) // Dlog1p(x,y) = log1p((x-y)/(1+y)/(x-y)
static inline real Dlog1p(real x, real y) throw() { static inline real Dlog1p(real x, real y) {
real t = x - y; if (t < 0) { t = -t; y = x; } real t = x - y; if (t < 0) { t = -t; y = x; }
return t != 0 ? Math::log1p(t / (1 + y)) / t : 1 / (1 + x); return t != 0 ? Math::log1p(t / (1 + y)) / t : 1 / (1 + x);
} }
// Dexp(x,y) = exp((x+y)/2) * 2*sinh((x-y)/2)/(x-y) // Dexp(x,y) = exp((x+y)/2) * 2*sinh((x-y)/2)/(x-y)
static inline real Dexp(real x, real y) throw() { static inline real Dexp(real x, real y) {
real t = (x - y)/2; real t = (x - y)/2;
return (t != 0 ? sinh(t)/t : real(1)) * exp((x + y)/2); return (t != 0 ? sinh(t)/t : real(1)) * exp((x + y)/2);
} }
// Dsinh(x,y) = 2*sinh((x-y)/2)/(x-y) * cosh((x+y)/2) // Dsinh(x,y) = 2*sinh((x-y)/2)/(x-y) * cosh((x+y)/2)
// cosh((x+y)/2) = (c+sinh(x)*sinh(y)/c)/2 // cosh((x+y)/2) = (c+sinh(x)*sinh(y)/c)/2
// c=sqrt((1+cosh(x))*(1+cosh(y))) // c=sqrt((1+cosh(x))*(1+cosh(y)))
// cosh((x+y)/2) = sqrt( (sinh(x)*sinh(y) + cosh(x)*cosh(y) + 1)/2 ) // cosh((x+y)/2) = sqrt( (sinh(x)*sinh(y) + cosh(x)*cosh(y) + 1)/2 )
static inline real Dsinh(real x, real y, real sx, real sy, real cx, rea l cy) static inline real Dsinh(real x, real y, real sx, real sy, real cx, rea l cy)
// sx = sinh(x), cx = cosh(x) // sx = sinh(x), cx = cosh(x)
throw() { {
// real t = (x - y)/2, c = sqrt((1 + cx) * (1 + cy)); // real t = (x - y)/2, c = sqrt((1 + cx) * (1 + cy));
// return (t != 0 ? sinh(t)/t : real(1)) * (c + sx * sy / c) /2; // return (t != 0 ? sinh(t)/t : real(1)) * (c + sx * sy / c) /2;
real t = (x - y)/2; real t = (x - y)/2;
return (t != 0 ? sinh(t)/t : real(1)) * sqrt((sx * sy + cx * cy + 1) /2); return (t != 0 ? sinh(t)/t : real(1)) * sqrt((sx * sy + cx * cy + 1) /2);
} }
// Dasinh(x,y) = asinh((x-y)*(x+y)/(x*sqrt(1+y^2)+y*sqrt(1+x^2)))/(x-y) // Dasinh(x,y) = asinh((x-y)*(x+y)/(x*sqrt(1+y^2)+y*sqrt(1+x^2)))/(x-y)
// = asinh((x*sqrt(1+y^2)-y*sqrt(1+x^2)))/(x-y) // = asinh((x*sqrt(1+y^2)-y*sqrt(1+x^2)))/(x-y)
static inline real Dasinh(real x, real y, real hx, real hy) throw() { static inline real Dasinh(real x, real y, real hx, real hy) {
// hx = hyp(x) // hx = hyp(x)
real t = x - y; real t = x - y;
return t != 0 ? return t != 0 ?
Math::asinh(x*y > 0 ? t * (x+y) / (x*hy + y*hx) : x*hy - y*hx) / t : Math::asinh(x*y > 0 ? t * (x+y) / (x*hy + y*hx) : x*hy - y*hx) / t :
1/hx; 1/hx;
} }
// Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y) // Deatanhe(x,y) = eatanhe((x-y)/(1-e^2*x*y))/(x-y)
inline real Deatanhe(real x, real y) const throw() { inline real Deatanhe(real x, real y) const {
real t = x - y, d = 1 - _e2 * x * y; real t = x - y, d = 1 - _e2 * x * y;
return t != 0 ? eatanhe(t / d) / t : _e2 / d; return t != 0 ? eatanhe(t / d) / t : _e2 / d;
} }
void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1) thro w(); void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1);
public: public:
/** /**
* Constructor with a single standard parallel. * Constructor with a single standard parallel.
* *
* @param[in] a equatorial radius of ellipsoid (meters). * @param[in] a equatorial radius of ellipsoid (meters).
* @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re. * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re.
* Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing
* to 1/\e f. * to 1/\e f.
* @param[in] stdlat standard parallel (degrees), the circle of tangenc y. * @param[in] stdlat standard parallel (degrees), the circle of tangenc y.
skipping to change at line 239 skipping to change at line 239
* The latitude origin is given by LambertConformalConic::LatitudeOrigi n(). * The latitude origin is given by LambertConformalConic::LatitudeOrigi n().
* No false easting or northing is added and \e lat should be in the ra nge * No false easting or northing is added and \e lat should be in the ra nge
* [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
* range [&minus;540&deg;, 540&deg;). The error in the projection * range [&minus;540&deg;, 540&deg;). The error in the projection
* is less than about 10 nm (10 nanometers), true distance, and the err ors * is less than about 10 nm (10 nanometers), true distance, and the err ors
* in the meridian convergence and scale are consistent with this. The * in the meridian convergence and scale are consistent with this. The
* values of \e x and \e y returned for points which project to infinit y * values of \e x and \e y returned for points which project to infinit y
* (i.e., one or both of the poles) will be large but finite. * (i.e., one or both of the poles) will be large but finite.
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y, real& gamma, real& k) const throw(); real& x, real& y, real& gamma, real& k) const;
/** /**
* Reverse projection, from Lambert conformal conic to geographic. * Reverse projection, from Lambert conformal conic to geographic.
* *
* @param[in] lon0 central meridian longitude (degrees). * @param[in] lon0 central meridian longitude (degrees).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
skipping to change at line 261 skipping to change at line 261
* *
* The latitude origin is given by LambertConformalConic::LatitudeOrigi n(). * The latitude origin is given by LambertConformalConic::LatitudeOrigi n().
* No false easting or northing is added. \e lon0 should be in the ran ge * No false easting or northing is added. \e lon0 should be in the ran ge
* [&minus;540&deg;, 540&deg;). The value of \e lon returned is in * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
* the range [&minus;180&deg;, 180&deg;). The error in the * the range [&minus;180&deg;, 180&deg;). The error in the
* projection is less than about 10 nm (10 nanometers), true distance, and * projection is less than about 10 nm (10 nanometers), true distance, and
* the errors in the meridian convergence and scale are consistent with * the errors in the meridian convergence and scale are consistent with
* this. * this.
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon, real& gamma, real& k) const throw(); real& lat, real& lon, real& gamma, real& k) const;
/** /**
* LambertConformalConic::Forward without returning the convergence and * LambertConformalConic::Forward without returning the convergence and
* scale. * scale.
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real gamma, k; real gamma, k;
Forward(lon0, lat, lon, x, y, gamma, k); Forward(lon0, lat, lon, x, y, gamma, k);
} }
/** /**
* LambertConformalConic::Reverse without returning the convergence and * LambertConformalConic::Reverse without returning the convergence and
* scale. * scale.
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real gamma, k; real gamma, k;
Reverse(lon0, x, y, lat, lon, gamma, k); Reverse(lon0, x, y, lat, lon, gamma, k);
} }
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the * @return \e f the flattening of the ellipsoid. This is the
* value used in the constructor. * value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* @return latitude of the origin for the projection (degrees). * @return latitude of the origin for the projection (degrees).
* *
* This is the latitude of minimum scale and equals the \e stdlat in th e * This is the latitude of minimum scale and equals the \e stdlat in th e
* 1-parallel constructor and lies between \e stdlat1 and \e stdlat2 in the * 1-parallel constructor and lies between \e stdlat1 and \e stdlat2 in the
* 2-parallel constructors. * 2-parallel constructors.
********************************************************************** / ********************************************************************** /
Math::real OriginLatitude() const throw() { return _lat0; } Math::real OriginLatitude() const { return _lat0; }
/** /**
* @return central scale for the projection. This is the scale on the * @return central scale for the projection. This is the scale on the
* latitude of origin. * latitude of origin.
********************************************************************** / ********************************************************************** /
Math::real CentralScale() const throw() { return _k0; } Math::real CentralScale() const { return _k0; }
///@} ///@}
/** /**
* A global instantiation of LambertConformalConic with the WGS84 * A global instantiation of LambertConformalConic with the WGS84
* ellipsoid, \e stdlat = 0, and \e k0 = 1. This degenerates to the * ellipsoid, \e stdlat = 0, and \e k0 = 1. This degenerates to the
* Mercator projection. * Mercator projection.
********************************************************************** / ********************************************************************** /
static const LambertConformalConic Mercator; static const LambertConformalConic Mercator;
}; };
 End of changes. 19 change blocks. 
19 lines changed or deleted 19 lines changed or added


 LocalCartesian.hpp   LocalCartesian.hpp 
skipping to change at line 47 skipping to change at line 47
class GEOGRAPHICLIB_EXPORT LocalCartesian { class GEOGRAPHICLIB_EXPORT LocalCartesian {
private: private:
typedef Math::real real; typedef Math::real real;
static const size_t dim_ = 3; static const size_t dim_ = 3;
static const size_t dim2_ = dim_ * dim_; static const size_t dim2_ = dim_ * dim_;
Geocentric _earth; Geocentric _earth;
real _lat0, _lon0, _h0; real _lat0, _lon0, _h0;
real _x0, _y0, _z0, _r[dim2_]; real _x0, _y0, _z0, _r[dim2_];
void IntForward(real lat, real lon, real h, real& x, real& y, real& z, void IntForward(real lat, real lon, real h, real& x, real& y, real& z,
real M[dim2_]) const throw(); real M[dim2_]) const;
void IntReverse(real x, real y, real z, real& lat, real& lon, real& h, void IntReverse(real x, real y, real z, real& lat, real& lon, real& h,
real M[dim2_]) const throw(); real M[dim2_]) const;
void MatrixMultiply(real M[dim2_]) const throw(); void MatrixMultiply(real M[dim2_]) const;
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.
* *
* \e lat0 should be in the range [&minus;90&deg;, 90&deg;]; \e * \e lat0 should be in the range [&minus;90&deg;, 90&deg;]; \e
* lon0 should be in the range [&minus;540&deg;, 540&deg;). * lon0 should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
LocalCartesian(real lat0, real lon0, real h0 = 0, LocalCartesian(real lat0, real lon0, real h0 = 0,
const Geocentric& earth = Geocentric::WGS84) throw() const Geocentric& earth = Geocentric::WGS84)
: _earth(earth) : _earth(earth)
{ Reset(lat0, lon0, h0); } { Reset(lat0, lon0, h0); }
/** /**
* Default constructor. * Default constructor.
* *
* @param[in] earth Geocentric object for the transformation; default * @param[in] earth Geocentric object for the transformation; default
* Geocentric::WGS84. * Geocentric::WGS84.
* *
* Sets \e lat0 = 0, \e lon0 = 0, \e h0 = 0. * Sets \e lat0 = 0, \e lon0 = 0, \e h0 = 0.
********************************************************************** / ********************************************************************** /
explicit LocalCartesian(const Geocentric& earth = Geocentric::WGS84) explicit LocalCartesian(const Geocentric& earth = Geocentric::WGS84)
throw()
: _earth(earth) : _earth(earth)
{ Reset(real(0), real(0), real(0)); } { Reset(real(0), real(0), real(0)); }
/** /**
* Reset the origin. * Reset 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.
* *
* \e lat0 should be in the range [&minus;90&deg;, 90&deg;]; \e * \e lat0 should be in the range [&minus;90&deg;, 90&deg;]; \e
* lon0 should be in the range [&minus;540&deg;, 540&deg;). * lon0 should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void Reset(real lat0, real lon0, real h0 = 0) throw(); void Reset(real lat0, real lon0, real h0 = 0);
/** /**
* Convert from geodetic to local cartesian coordinates. * Convert from geodetic to local cartesian coordinates.
* *
* @param[in] lat latitude of point (degrees). * @param[in] lat latitude of point (degrees).
* @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 [&minus;90&deg;, 90&deg;]; \e lon * \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
* should be in the range [&minus;540&deg;, 540&deg;). * should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
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 {
IntForward(lat, lon, h, x, y, z, NULL); IntForward(lat, lon, h, x, y, z, NULL);
} }
/** /**
* Convert from geodetic to local cartesian coordinates and return rota tion * Convert from geodetic to local cartesian coordinates and return rota tion
* matrix. * matrix.
* *
* @param[in] lat latitude of point (degrees). * @param[in] lat latitude of point (degrees).
* @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).
skipping to change at line 142 skipping to change at line 141
* local coordinate system at (\e lat, \e lon, \e h)); call this * local coordinate system at (\e lat, \e lon, \e h)); call this
* representation \e v1. * representation \e v1.
* - in \e x, \e y, \e z coordinates (where the components are relative to * - in \e x, \e y, \e z coordinates (where the components are relative to
* the local coordinate system at (\e lat0, \e lon0, \e h0)); call th is * the local coordinate system at (\e lat0, \e lon0, \e h0)); call th is
* representation \e v0. * representation \e v0.
* . * .
* Then we have \e v0 = \e M &sdot; \e v1. * Then we have \e v0 = \e M &sdot; \e v1.
********************************************************************** / ********************************************************************** /
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,
std::vector<real>& M) std::vector<real>& M)
const throw() { const {
if (M.end() == M.begin() + dim2_) { if (M.end() == M.begin() + dim2_) {
real t[dim2_]; real t[dim2_];
IntForward(lat, lon, h, x, y, z, t); IntForward(lat, lon, h, x, y, z, t);
copy(t, t + dim2_, M.begin()); std::copy(t, t + dim2_, M.begin());
} else } else
IntForward(lat, lon, h, x, y, z, NULL); IntForward(lat, lon, h, x, y, z, NULL);
} }
/** /**
* Convert from local cartesian to geodetic coordinates. * 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 [&minus;180&deg;, * The value of \e lon returned is in the range [&minus;180&deg;,
* 180&deg;). * 180&deg;).
********************************************************************** / ********************************************************************** /
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 {
IntReverse(x, y, z, lat, lon, h, NULL); IntReverse(x, y, z, lat, lon, h, NULL);
} }
/** /**
* Convert from local cartesian to geodetic coordinates and return rota tion * Convert from local cartesian to geodetic coordinates and return rota tion
* matrix. * matrix.
* *
* @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).
skipping to change at line 196 skipping to change at line 195
* representation \e v1. * representation \e v1.
* - in \e x, \e y, \e z coordinates (where the components are relative to * - in \e x, \e y, \e z coordinates (where the components are relative to
* the local coordinate system at (\e lat0, \e lon0, \e h0)); call th is * the local coordinate system at (\e lat0, \e lon0, \e h0)); call th is
* representation \e v0. * representation \e v0.
* . * .
* Then we have \e v1 = \e M<sup>T</sup> &sdot; \e v0, where \e * Then we have \e v1 = \e M<sup>T</sup> &sdot; \e v0, where \e
* M<sup>T</sup> is the transpose of \e M. * M<sup>T</sup> is the transpose of \e M.
********************************************************************** / ********************************************************************** /
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,
std::vector<real>& M) std::vector<real>& M)
const throw() { const {
if (M.end() == M.begin() + dim2_) { if (M.end() == M.begin() + dim2_) {
real t[dim2_]; real t[dim2_];
IntReverse(x, y, z, lat, lon, h, t); IntReverse(x, y, z, lat, lon, h, t);
copy(t, t + dim2_, M.begin()); std::copy(t, t + dim2_, M.begin());
} else } else
IntReverse(x, y, z, lat, lon, h, NULL); IntReverse(x, y, z, lat, lon, h, NULL);
} }
/** \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 { return _lat0; }
/** /**
* @return longitude of the origin (degrees). * @return longitude of the origin (degrees).
********************************************************************** / ********************************************************************** /
Math::real LongitudeOrigin() const throw() { return _lon0; } Math::real LongitudeOrigin() const { return _lon0; }
/** /**
* @return height of the origin (meters). * @return height of the origin (meters).
********************************************************************** / ********************************************************************** /
Math::real HeightOrigin() const throw() { return _h0; } Math::real HeightOrigin() const { return _h0; }
/** /**
* @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 of \e a inherited from the Geocentric object used in the * the value of \e a inherited from the Geocentric object used in the
* constructor. * constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() { return _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geocentric object used in the constructor. * inherited from the Geocentric object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() Math::real InverseFlattening() const
{ return _earth.InverseFlattening(); } { return _earth.InverseFlattening(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_LOCALCARTESIAN_HPP #endif // GEOGRAPHICLIB_LOCALCARTESIAN_HPP
 End of changes. 17 change blocks. 
18 lines changed or deleted 17 lines changed or added


 MGRS.hpp   MGRS.hpp 
skipping to change at line 30 skipping to change at line 30
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Convert between UTM/UPS and %MGRS * \brief Convert between UTM/UPS and %MGRS
* *
* MGRS is defined in Chapter 3 of * MGRS is defined in Chapter 3 of
* - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill, * - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill,
* <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/T M8358_1.pdf"> * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/T M8358_1.pdf">
* Datums, Ellipsoids, Grids, and Grid Reference Systems</a>, * Datums, Ellipsoids, Grids, and Grid Reference Systems</a>,
* Defense Mapping Agency, Technical Manual TM8358.1 (1990). * Defense Mapping Agency, Technical Manual TM8358.1 (1990).
* .
* This document has been updated by the two NGA documents
* - <a href="https://nsgreg.nga.mil/doc/view?i=4057"> Universal Grids an
d
* Grid Reference Systems</a>, NGA.STND.0037_2.0.0_GRIDS (2014).
* - <a href="https://nsgreg.nga.mil/doc/view?i=4056"> The Universal Grid
s
* and the Transverse Mercator and Polar Stereographic Map Projections<
/a>,
* NGA.SIG.0012_2.0.0_UTMUPS (2014).
* *
* This implementation has the following properties: * This implementation has the following properties:
* - The conversions are closed, i.e., output from Forward is legal input for * - The conversions are closed, i.e., output from Forward is legal input for
* Reverse and vice versa. Conversion in both directions preserve the * Reverse and vice versa. Conversion in both directions preserve the
* UTM/UPS selection and the UTM zone. * UTM/UPS selection and the UTM zone.
* - Forward followed by Reverse and vice versa is approximately the * - Forward followed by Reverse and vice versa is approximately the
* identity. (This is affected in predictable ways by errors in * identity. (This is affected in predictable ways by errors in
* determining the latitude band and by loss of precision in the MGRS * determining the latitude band and by loss of precision in the MGRS
* coordinates.) * coordinates.)
* - All MGRS coordinates truncate to legal 100 km blocks. All MGRS * - All MGRS coordinates truncate to legal 100 km blocks. All MGRS
skipping to change at line 94 skipping to change at line 100
// Top-level tiles are 10^5 m = 100 km on a side // Top-level tiles are 10^5 m = 100 km on a side
tilelevel_ = 5, tilelevel_ = 5,
// Period of UTM row letters // Period of UTM row letters
utmrowperiod_ = 20, utmrowperiod_ = 20,
// Row letters are shifted by 5 for even zones // Row letters are shifted by 5 for even zones
utmevenrowshift_ = 5, utmevenrowshift_ = 5,
// Maximum precision is um // Maximum precision is um
maxprec_ = 5 + 6, maxprec_ = 5 + 6,
}; };
static void CheckCoords(bool utmp, bool& northp, real& x, real& y); static void CheckCoords(bool utmp, bool& northp, real& x, real& y);
static int UTMRow(int iband, int icol, int irow) throw(); static int UTMRow(int iband, int icol, int irow);
friend class UTMUPS; // UTMUPS::StandardZone calls LatitudeBand friend class UTMUPS; // UTMUPS::StandardZone calls LatitudeBand
// Return latitude band number [-10, 10) for the given latitude (degree s). // Return latitude band number [-10, 10) for the given latitude (degree s).
// The bands are reckoned in include their southern edges. // The bands are reckoned in include their southern edges.
static int LatitudeBand(real lat) throw() { static int LatitudeBand(real lat) {
int ilat = int(std::floor(lat)); int ilat = int(std::floor(lat));
return (std::max)(-10, (std::min)(9, (ilat + 80)/8 - 10)); return (std::max)(-10, (std::min)(9, (ilat + 80)/8 - 10));
} }
// Return approximate latitude band number [-10, 10) for the given nort hing // Return approximate latitude band number [-10, 10) for the given nort hing
// (meters). With this rule, each 100km tile would have a unique band // (meters). With this rule, each 100km tile would have a unique band
// letter corresponding to the latitude at the center of the tile. Thi s // letter corresponding to the latitude at the center of the tile. Thi s
// function isn't currently used. // function isn't currently used.
static int ApproxLatitudeBand(real y) throw() { static int ApproxLatitudeBand(real y) {
// northing at tile center in units of tile = 100km // northing at tile center in units of tile = 100km
real ya = std::floor( (std::min)(real(88), std::abs(y/tile_)) ) + real ya = std::floor( (std::min)(real(88), std::abs(y/tile_)) ) +
real(0.5); real(0.5);
// convert to lat (mult by 90/100) and then to band (divide by 8) // convert to lat (mult by 90/100) and then to band (divide by 8)
// the +1 fine tunes the boundary between bands 3 and 4 // the +1 fine tunes the boundary between bands 3 and 4
int b = int(std::floor( ((ya * 9 + 1) / 10) / 8 )); int b = int(std::floor( ((ya * 9 + 1) / 10) / 8 ));
// For the northern hemisphere we have // For the northern hemisphere we have
// band rows num // band rows num
// N 0 0:8 9 // N 0 0:8 9
// P 1 9:17 9 // P 1 9:17 9
skipping to change at line 165 skipping to change at line 171
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (meters).
* @param[in] prec precision relative to 100 km. * @param[in] prec precision relative to 100 km.
* @param[out] mgrs MGRS string. * @param[out] mgrs MGRS string.
* @exception GeographicErr if \e zone, \e x, or \e y is outside its * @exception GeographicErr if \e zone, \e x, or \e y is outside its
* allowed range. * allowed range.
* @exception GeographicErr if the memory for the MGRS string can't be * @exception GeographicErr if the memory for the MGRS string can't be
* allocated. * allocated.
* *
* \e prec specifies the precision of the MGRS string as follows: * \e prec specifies the precision of the MGRS string as follows:
* - prec = &minus;1 (min), only the grid zone is returned
* - prec = 0 (min), 100 km * - prec = 0 (min), 100 km
* - prec = 1, 10 km * - prec = 1, 10 km
* - prec = 2, 1 km * - prec = 2, 1 km
* - prec = 3, 100 m * - prec = 3, 100 m
* - prec = 4, 10 m * - prec = 4, 10 m
* - prec = 5, 1 m * - prec = 5, 1 m
* - prec = 6, 0.1 m * - prec = 6, 0.1 m
* - prec = 11 (max), 1 &mu;m * - prec = 11 (max), 1 &mu;m
* *
* UTM eastings are allowed to be in the range [100 km, 900 km], northi ngs * UTM eastings are allowed to be in the range [100 km, 900 km], northi ngs
skipping to change at line 200 skipping to change at line 207
* at least 0.5 degree extension into standard UPS zones. The upper en ds * at least 0.5 degree extension into standard UPS zones. The upper en ds
* of the ranges for the UPS coordinates is dictated by requiring symme try * of the ranges for the UPS coordinates is dictated by requiring symme try
* about the meridians 0E and 90E. * about the meridians 0E and 90E.
* *
* All allowed UTM and UPS coordinates may now be converted to legal MG RS * All allowed UTM and UPS coordinates may now be converted to legal MG RS
* coordinates with the proviso that eastings and northings on the uppe r * coordinates with the proviso that eastings and northings on the uppe r
* boundaries are silently reduced by about 4 nm (4 nanometers) to plac e * boundaries are silently reduced by about 4 nm (4 nanometers) to plac e
* them \e within the allowed range. (This includes reducing a souther n * them \e within the allowed range. (This includes reducing a souther n
* hemisphere northing of 10000 km by 4 nm so that it is placed in lati tude * hemisphere northing of 10000 km by 4 nm so that it is placed in lati tude
* band M.) The UTM or UPS coordinates are truncated to requested * band M.) The UTM or UPS coordinates are truncated to requested
* precision to determine the MGRS coordinate. Thus in UTM zone 38N, t he * precision to determine the MGRS coordinate. Thus in UTM zone 38n, t he
* square area with easting in [444 km, 445 km) and northing in [3688 k m, * square area with easting in [444 km, 445 km) and northing in [3688 k m,
* 3689 km) maps to MGRS coordinate 38SMB4488 (at \e prec = 2, 1 km), * 3689 km) maps to MGRS coordinate 38SMB4488 (at \e prec = 2, 1 km),
* Khulani Sq., Baghdad. * Khulani Sq., Baghdad.
* *
* The UTM/UPS selection and the UTM zone is preserved in the conversio n to * The UTM/UPS selection and the UTM zone is preserved in the conversio n to
* MGRS coordinate. Thus for \e zone > 0, the MGRS coordinate begins w ith * MGRS coordinate. Thus for \e zone > 0, the MGRS coordinate begins w ith
* the zone number followed by one of [C--M] for the southern * the zone number followed by one of [C--M] for the southern
* hemisphere and [N--X] for the northern hemisphere. For \e zone = * hemisphere and [N--X] for the northern hemisphere. For \e zone =
* 0, the MGRS coordinates begins with one of [AB] for the southern * 0, the MGRS coordinates begins with one of [AB] for the southern
* hemisphere and [XY] for the northern hemisphere. * hemisphere and [XY] for the northern hemisphere.
* *
* The conversion to the MGRS is exact for prec in [0, 5] except that a * The conversion to the MGRS is exact for prec in [0, 5] except that a
* neighboring latitude band letter may be given if the point is within 5nm * neighboring latitude band letter may be given if the point is within 5nm
* of a band boundary. For prec in [6, 11], the conversion is accurate to * of a band boundary. For prec in [6, 11], the conversion is accurate to
* roundoff. * roundoff.
* *
* If \e prec = -1, then the "grid zone designation", e.g., 18T, is
* returned. This consists of the UTM zone number (absent for UPS) and
the
* first letter of the MGRS string which labels the latitude band for U
TM
* and the hemisphere for UPS.
*
* If \e x or \e y is NaN or if \e zone is UTMUPS::INVALID, the returne d * If \e x or \e y is NaN or if \e zone is UTMUPS::INVALID, the returne d
* MGRS string is "INVALID". * MGRS string is "INVALID".
* *
* Return the result via a reference argument to avoid the overhead of * Return the result via a reference argument to avoid the overhead of
* allocating a potentially large number of small strings. If an error is * allocating a potentially large number of small strings. If an error is
* thrown, then \e mgrs is unchanged. * thrown, then \e mgrs is unchanged.
********************************************************************** / ********************************************************************** /
static void Forward(int zone, bool northp, real x, real y, static void Forward(int zone, bool northp, real x, real y,
int prec, std::string& mgrs); int prec, std::string& mgrs);
skipping to change at line 284 skipping to change at line 296
* block). * block).
* - Similarly ZAB and YZB are permitted (they straddle the prime * - Similarly ZAB and YZB are permitted (they straddle the prime
* meridian); but YAB and ZZB are not (the prime meridian does not * meridian); but YAB and ZZB are not (the prime meridian does not
* intersect either block). * intersect either block).
* *
* The UTM/UPS selection and the UTM zone is preserved in the conversio n * The UTM/UPS selection and the UTM zone is preserved in the conversio n
* from MGRS coordinate. The conversion is exact for prec in [0, 5]. With * from MGRS coordinate. The conversion is exact for prec in [0, 5]. With
* centerp = true the conversion from MGRS to geographic and back is * centerp = true the conversion from MGRS to geographic and back is
* stable. This is not assured if \e centerp = false. * stable. This is not assured if \e centerp = false.
* *
* If a "grid zone designation" (for example, 18T or A) is given, then
some
* suitable (but essentially arbitrary) point within that grid zone is
* returned. The main utility of the conversion is to allow \e zone an
d \e
* northp to be determined. In this case, the \e centerp parameter is
* ignored.
*
* If the first 3 characters of \e mgrs are "INV", then \e x and \e y a re * If the first 3 characters of \e mgrs are "INV", then \e x and \e y a re
* set to NaN and \e zone is set to UTMUPS::INVALID. * set to NaN and \e zone is set to UTMUPS::INVALID.
* *
* If an exception is thrown, then the arguments are unchanged. * If an exception is thrown, then the arguments are unchanged.
********************************************************************** / ********************************************************************** /
static void Reverse(const std::string& mgrs, static void Reverse(const std::string& mgrs,
int& zone, bool& northp, real& x, real& y, int& zone, bool& northp, real& x, real& y,
int& prec, bool centerp = true); int& prec, bool centerp = true);
/** \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 UTMUPS::MajorRadius(); } static Math::real MajorRadius() { return UTMUPS::MajorRadius(); }
/** /**
* @return \e f the flattening of the WGS84 ellipsoid. * @return \e f the 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 Flattening() throw() { return UTMUPS::Flattening(); } static Math::real Flattening() { return UTMUPS::Flattening(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the WGS84 ellipsoid. * @return \e r the inverse flattening of the WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
static Math::real InverseFlattening() throw() static Math::real InverseFlattening()
{ return UTMUPS::InverseFlattening(); } { return UTMUPS::InverseFlattening(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning (pop) # pragma warning (pop)
#endif #endif
 End of changes. 12 change blocks. 
8 lines changed or deleted 33 lines changed or added


 MagneticCircle.hpp   MagneticCircle.hpp 
skipping to change at line 65 skipping to change at line 65
, _sphi(sphi) , _sphi(sphi)
, _t1(t1) , _t1(t1)
, _dt0(dt0) , _dt0(dt0)
, _interpolate(interpolate) , _interpolate(interpolate)
, _circ0(circ0) , _circ0(circ0)
, _circ1(circ1) , _circ1(circ1)
{} {}
void Field(real lon, bool diffp, void Field(real lon, bool diffp,
real& Bx, real& By, real& Bz, real& Bx, real& By, real& Bz,
real& Bxt, real& Byt, real& Bzt) const throw(); real& Bxt, real& Byt, real& Bzt) const;
friend class MagneticModel; // MagneticModel calls the private construc tor friend class MagneticModel; // MagneticModel calls the private construc tor
public: public:
/** /**
* A default constructor for the normal gravity. This sets up an * A default constructor for the normal gravity. This sets up an
* uninitialized object which can be later replaced by the * uninitialized object which can be later replaced by the
* MagneticModel::Circle. * MagneticModel::Circle.
********************************************************************** / ********************************************************************** /
skipping to change at line 91 skipping to change at line 91
/** /**
* Evaluate the components of the geomagnetic field at a particular * Evaluate the components of the geomagnetic field at a particular
* longitude. * longitude.
* *
* @param[in] lon longitude of the point (degrees). * @param[in] lon longitude of the point (degrees).
* @param[out] Bx the easterly component of the magnetic field (nanotes la). * @param[out] Bx the easterly component of the magnetic field (nanotes la).
* @param[out] By the northerly component of the magnetic field (nanote sla). * @param[out] By the northerly component of the magnetic field (nanote sla).
* @param[out] Bz the vertical (up) component of the magnetic field * @param[out] Bz the vertical (up) component of the magnetic field
* (nanotesla). * (nanotesla).
********************************************************************** / ********************************************************************** /
void operator()(real lon, real& Bx, real& By, real& Bz) const throw() { void operator()(real lon, real& Bx, real& By, real& Bz) const {
real dummy; real dummy;
Field(lon, false, Bx, By, Bz, dummy, dummy, dummy); Field(lon, false, Bx, By, Bz, dummy, dummy, dummy);
} }
/** /**
* Evaluate the components of the geomagnetic field and their time * Evaluate the components of the geomagnetic field and their time
* derivatives at a particular longitude. * derivatives at a particular longitude.
* *
* @param[in] lon longitude of the point (degrees). * @param[in] lon longitude of the point (degrees).
* @param[out] Bx the easterly component of the magnetic field (nanotes la). * @param[out] Bx the easterly component of the magnetic field (nanotes la).
* @param[out] By the northerly component of the magnetic field (nanote sla). * @param[out] By the northerly component of the magnetic field (nanote sla).
* @param[out] Bz the vertical (up) component of the magnetic field * @param[out] Bz the vertical (up) component of the magnetic field
* (nanotesla). * (nanotesla).
* @param[out] Bxt the rate of change of \e Bx (nT/yr). * @param[out] Bxt the rate of change of \e Bx (nT/yr).
* @param[out] Byt the rate of change of \e By (nT/yr). * @param[out] Byt the rate of change of \e By (nT/yr).
* @param[out] Bzt the rate of change of \e Bz (nT/yr). * @param[out] Bzt the rate of change of \e Bz (nT/yr).
********************************************************************** / ********************************************************************** /
void operator()(real lon, real& Bx, real& By, real& Bz, void operator()(real lon, real& Bx, real& By, real& Bz,
real& Bxt, real& Byt, real& Bzt) const throw() { real& Bxt, real& Byt, real& Bzt) const {
Field(lon, true, Bx, By, Bz, Bxt, Byt, Bzt); Field(lon, true, Bx, By, Bz, Bxt, Byt, Bzt);
} }
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _a > 0; } bool Init() const { return _a > 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 MagneticModel object used in the * the value inherited from the MagneticModel object used in the
* constructor. * constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() Math::real MajorRadius() const
{ return Init() ? _a : Math::NaN<real>(); } { return Init() ? _a : Math::NaN<real>(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the MagneticModel object used in the constructor. * inherited from the MagneticModel object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
/** /**
* @return the latitude of the circle (degrees). * @return the latitude of the circle (degrees).
********************************************************************** / ********************************************************************** /
Math::real Latitude() const throw() Math::real Latitude() const
{ return Init() ? _lat : Math::NaN<real>(); } { return Init() ? _lat : Math::NaN<real>(); }
/** /**
* @return the height of the circle (meters). * @return the height of the circle (meters).
********************************************************************** / ********************************************************************** /
Math::real Height() const throw() Math::real Height() const
{ return Init() ? _h : Math::NaN<real>(); } { return Init() ? _h : Math::NaN<real>(); }
/** /**
* @return the time (fractional years). * @return the time (fractional years).
********************************************************************** / ********************************************************************** /
Math::real Time() const throw() Math::real Time() const
{ return Init() ? _t : Math::NaN<real>(); } { return Init() ? _t : Math::NaN<real>(); }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_MAGNETICCIRCLE_HPP #endif // GEOGRAPHICLIB_MAGNETICCIRCLE_HPP
 End of changes. 9 change blocks. 
9 lines changed or deleted 9 lines changed or added


 MagneticModel.hpp   MagneticModel.hpp 
skipping to change at line 74 skipping to change at line 74
std::string _name, _dir, _description, _date, _filename, _id; std::string _name, _dir, _description, _date, _filename, _id;
real _t0, _dt0, _tmin, _tmax, _a, _hmin, _hmax; real _t0, _dt0, _tmin, _tmax, _a, _hmin, _hmax;
int _Nmodels; int _Nmodels;
SphericalHarmonic::normalization _norm; SphericalHarmonic::normalization _norm;
Geocentric _earth; Geocentric _earth;
std::vector< std::vector<real> > _G; std::vector< std::vector<real> > _G;
std::vector< std::vector<real> > _H; std::vector< std::vector<real> > _H;
std::vector<SphericalHarmonic> _harm; std::vector<SphericalHarmonic> _harm;
void Field(real t, real lat, real lon, real h, bool diffp, void Field(real t, real lat, real lon, real h, bool diffp,
real& Bx, real& By, real& Bz, real& Bx, real& By, real& Bz,
real& Bxt, real& Byt, real& Bzt) const throw(); real& Bxt, real& Byt, real& Bzt) const;
void ReadMetadata(const std::string& name); void ReadMetadata(const std::string& name);
MagneticModel(const MagneticModel&); // copy constructor not allowed MagneticModel(const MagneticModel&); // copy constructor not allowed
MagneticModel& operator=(const MagneticModel&); // nor copy assignment MagneticModel& operator=(const MagneticModel&); // nor copy assignment
public: public:
/** \name Setting up the magnetic model /** \name Setting up the magnetic model
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Construct a magnetic model. * Construct a magnetic model.
skipping to change at line 131 skipping to change at line 131
* @param[in] t the time (years). * @param[in] t the time (years).
* @param[in] lat latitude of the point (degrees). * @param[in] lat latitude of the point (degrees).
* @param[in] lon longitude of the point (degrees). * @param[in] lon longitude of the point (degrees).
* @param[in] h the height of the point above the ellipsoid (meters). * @param[in] h the height of the point above the ellipsoid (meters).
* @param[out] Bx the easterly component of the magnetic field (nanotes la). * @param[out] Bx the easterly component of the magnetic field (nanotes la).
* @param[out] By the northerly component of the magnetic field (nanote sla). * @param[out] By the northerly component of the magnetic field (nanote sla).
* @param[out] Bz the vertical (up) component of the magnetic field * @param[out] Bz the vertical (up) component of the magnetic field
* (nanotesla). * (nanotesla).
********************************************************************** / ********************************************************************** /
void operator()(real t, real lat, real lon, real h, void operator()(real t, real lat, real lon, real h,
real& Bx, real& By, real& Bz) const throw() { real& Bx, real& By, real& Bz) const {
real dummy; real dummy;
Field(t, lat, lon, h, false, Bx, By, Bz, dummy, dummy, dummy); Field(t, lat, lon, h, false, Bx, By, Bz, dummy, dummy, dummy);
} }
/** /**
* Evaluate the components of the geomagnetic field and their time * Evaluate the components of the geomagnetic field and their time
* derivatives * derivatives
* *
* @param[in] t the time (years). * @param[in] t the time (years).
* @param[in] lat latitude of the point (degrees). * @param[in] lat latitude of the point (degrees).
skipping to change at line 154 skipping to change at line 154
* @param[out] Bx the easterly component of the magnetic field (nanotes la). * @param[out] Bx the easterly component of the magnetic field (nanotes la).
* @param[out] By the northerly component of the magnetic field (nanote sla). * @param[out] By the northerly component of the magnetic field (nanote sla).
* @param[out] Bz the vertical (up) component of the magnetic field * @param[out] Bz the vertical (up) component of the magnetic field
* (nanotesla). * (nanotesla).
* @param[out] Bxt the rate of change of \e Bx (nT/yr). * @param[out] Bxt the rate of change of \e Bx (nT/yr).
* @param[out] Byt the rate of change of \e By (nT/yr). * @param[out] Byt the rate of change of \e By (nT/yr).
* @param[out] Bzt the rate of change of \e Bz (nT/yr). * @param[out] Bzt the rate of change of \e Bz (nT/yr).
********************************************************************** / ********************************************************************** /
void operator()(real t, real lat, real lon, real h, void operator()(real t, real lat, real lon, real h,
real& Bx, real& By, real& Bz, real& Bx, real& By, real& Bz,
real& Bxt, real& Byt, real& Bzt) const throw() { real& Bxt, real& Byt, real& Bzt) const {
Field(t, lat, lon, h, true, Bx, By, Bz, Bxt, Byt, Bzt); Field(t, lat, lon, h, true, Bx, By, Bz, Bxt, Byt, Bzt);
} }
/** /**
* Create a MagneticCircle object to allow the geomagnetic field at man y * Create a MagneticCircle object to allow the geomagnetic field at man y
* points with constant \e lat, \e h, and \e t and varying \e lon to be * points with constant \e lat, \e h, and \e t and varying \e lon to be
* computed efficiently. * computed efficiently.
* *
* @param[in] t the time (years). * @param[in] t the time (years).
* @param[in] lat latitude of the point (degrees). * @param[in] lat latitude of the point (degrees).
skipping to change at line 192 skipping to change at line 192
* @param[in] By the \e y (northerly) component of the magnetic field ( nT). * @param[in] By the \e y (northerly) component of the magnetic field ( nT).
* @param[in] Bz the \e z (vertical, up positive) component of the magn etic * @param[in] Bz the \e z (vertical, up positive) component of the magn etic
* field (nT). * field (nT).
* @param[out] H the horizontal magnetic field (nT). * @param[out] H the horizontal magnetic field (nT).
* @param[out] F the total magnetic field (nT). * @param[out] F the total magnetic field (nT).
* @param[out] D the declination of the field (degrees east of north). * @param[out] D the declination of the field (degrees east of north).
* @param[out] I the inclination of the field (degrees down from * @param[out] I the inclination of the field (degrees down from
* horizontal). * horizontal).
********************************************************************** / ********************************************************************** /
static void FieldComponents(real Bx, real By, real Bz, static void FieldComponents(real Bx, real By, real Bz,
real& H, real& F, real& D, real& I) throw() { real& H, real& F, real& D, real& I) {
real Ht, Ft, Dt, It; real Ht, Ft, Dt, It;
FieldComponents(Bx, By, Bz, real(0), real(1), real(0), FieldComponents(Bx, By, Bz, real(0), real(1), real(0),
H, F, D, I, Ht, Ft, Dt, It); H, F, D, I, Ht, Ft, Dt, It);
} }
/** /**
* Compute various quantities dependent on the magnetic field and its r ate * Compute various quantities dependent on the magnetic field and its r ate
* of change. * of change.
* *
* @param[in] Bx the \e x (easterly) component of the magnetic field (n T). * @param[in] Bx the \e x (easterly) component of the magnetic field (n T).
skipping to change at line 222 skipping to change at line 222
* @param[out] I the inclination of the field (degrees down from * @param[out] I the inclination of the field (degrees down from
* horizontal). * horizontal).
* @param[out] Ht the rate of change of \e H (nT/yr). * @param[out] Ht the rate of change of \e H (nT/yr).
* @param[out] Ft the rate of change of \e F (nT/yr). * @param[out] Ft the rate of change of \e F (nT/yr).
* @param[out] Dt the rate of change of \e D (degrees/yr). * @param[out] Dt the rate of change of \e D (degrees/yr).
* @param[out] It the rate of change of \e I (degrees/yr). * @param[out] It the rate of change of \e I (degrees/yr).
********************************************************************** / ********************************************************************** /
static void FieldComponents(real Bx, real By, real Bz, static void FieldComponents(real Bx, real By, real Bz,
real Bxt, real Byt, real Bzt, real Bxt, real Byt, real Bzt,
real& H, real& F, real& D, real& I, real& H, real& F, real& D, real& I,
real& Ht, real& Ft, real& Dt, real& It) thr ow(); real& Ht, real& Ft, real& Dt, real& It);
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return the description of the magnetic model, if available, from th e * @return the description of the magnetic model, if available, from th e
* Description file in the data file; if absent, return "NONE". * Description file in the data file; if absent, return "NONE".
********************************************************************** / ********************************************************************** /
const std::string& Description() const throw() { return _description; } const std::string& Description() const { return _description; }
/** /**
* @return date of the model, if available, from the ReleaseDate field in * @return date of the model, if available, from the ReleaseDate field in
* the data file; if absent, return "UNKNOWN". * the data file; if absent, return "UNKNOWN".
********************************************************************** / ********************************************************************** /
const std::string& DateTime() const throw() { return _date; } const std::string& DateTime() const { return _date; }
/** /**
* @return full file name used to load the magnetic model. * @return full file name used to load the magnetic model.
********************************************************************** / ********************************************************************** /
const std::string& MagneticFile() const throw() { return _filename; } const std::string& MagneticFile() const { return _filename; }
/** /**
* @return "name" used to load the magnetic model (from the first argum ent * @return "name" used to load the magnetic model (from the first argum ent
* of the constructor, but this may be overridden by the model file). * of the constructor, but this may be overridden by the model file).
********************************************************************** / ********************************************************************** /
const std::string& MagneticModelName() const throw() { return _name; } const std::string& MagneticModelName() const { return _name; }
/** /**
* @return directory used to load the magnetic model. * @return directory used to load the magnetic model.
********************************************************************** / ********************************************************************** /
const std::string& MagneticModelDirectory() const throw() { return _dir ; } const std::string& MagneticModelDirectory() const { return _dir; }
/** /**
* @return the minimum height above the ellipsoid (in meters) for which * @return the minimum height above the ellipsoid (in meters) for which
* this MagneticModel should be used. * this MagneticModel should be used.
* *
* Because the model will typically provide useful results * Because the model will typically provide useful results
* slightly outside the range of allowed heights, no check of \e t * slightly outside the range of allowed heights, no check of \e t
* argument is made by MagneticModel::operator()() or * argument is made by MagneticModel::operator()() or
* MagneticModel::Circle. * MagneticModel::Circle.
********************************************************************** / ********************************************************************** /
Math::real MinHeight() const throw() { return _hmin; } Math::real MinHeight() const { return _hmin; }
/** /**
* @return the maximum height above the ellipsoid (in meters) for which * @return the maximum height above the ellipsoid (in meters) for which
* this MagneticModel should be used. * this MagneticModel should be used.
* *
* Because the model will typically provide useful results * Because the model will typically provide useful results
* slightly outside the range of allowed heights, no check of \e t * slightly outside the range of allowed heights, no check of \e t
* argument is made by MagneticModel::operator()() or * argument is made by MagneticModel::operator()() or
* MagneticModel::Circle. * MagneticModel::Circle.
********************************************************************** / ********************************************************************** /
Math::real MaxHeight() const throw() { return _hmax; } Math::real MaxHeight() const { return _hmax; }
/** /**
* @return the minimum time (in years) for which this MagneticModel sho uld * @return the minimum time (in years) for which this MagneticModel sho uld
* be used. * be used.
* *
* Because the model will typically provide useful results * Because the model will typically provide useful results
* slightly outside the range of allowed times, no check of \e t * slightly outside the range of allowed times, no check of \e t
* argument is made by MagneticModel::operator()() or * argument is made by MagneticModel::operator()() or
* MagneticModel::Circle. * MagneticModel::Circle.
********************************************************************** / ********************************************************************** /
Math::real MinTime() const throw() { return _tmin; } Math::real MinTime() const { return _tmin; }
/** /**
* @return the maximum time (in years) for which this MagneticModel sho uld * @return the maximum time (in years) for which this MagneticModel sho uld
* be used. * be used.
* *
* Because the model will typically provide useful results * Because the model will typically provide useful results
* slightly outside the range of allowed times, no check of \e t * slightly outside the range of allowed times, no check of \e t
* argument is made by MagneticModel::operator()() or * argument is made by MagneticModel::operator()() or
* MagneticModel::Circle. * MagneticModel::Circle.
********************************************************************** / ********************************************************************** /
Math::real MaxTime() const throw() { return _tmax; } Math::real MaxTime() const { return _tmax; }
/** /**
* @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 of \e a inherited from the Geocentric object used in the * the value of \e a inherited from the Geocentric object used in the
* constructor. * constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() { return _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geocentric object used in the constructor. * inherited from the Geocentric object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
///@} ///@}
/** /**
* @return the default path for magnetic model data files. * @return the default path for magnetic model data files.
* *
* This is the value of the environment variable MAGNETIC_PATH, if set; * This is the value of the environment variable MAGNETIC_PATH, if set;
* otherwise, it is $GEOGRAPHICLIB_DATA/magnetic if the environment * otherwise, it is $GEOGRAPHICLIB_DATA/magnetic if the environment
* variable GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time * variable GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time
* default (/usr/local/share/GeographicLib/magnetic on non-Windows syst ems * default (/usr/local/share/GeographicLib/magnetic on non-Windows syst ems
* and C:/Documents and Settings/All Users/Application * and C:/Documents and Settings/All Users/Application
 End of changes. 16 change blocks. 
16 lines changed or deleted 16 lines changed or added


 Math.hpp   Math.hpp 
skipping to change at line 21 skipping to change at line 21
// include guard to enforce this ordering. // include guard to enforce this ordering.
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if !defined(GEOGRAPHICLIB_MATH_HPP) #if !defined(GEOGRAPHICLIB_MATH_HPP)
#define GEOGRAPHICLIB_MATH_HPP 1 #define GEOGRAPHICLIB_MATH_HPP 1
/** /**
* Are C++11 math functions available? * Are C++11 math functions available?
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_CPLUSPLUS11_MATH) #if !defined(GEOGRAPHICLIB_CPLUSPLUS11_MATH)
// Recent versions of g++ -std=c++11 (4.7 and later?) set __cplusplus to 20
1103
// and support the new C++11 mathematical functions, std::atanh, etc. Howe
ver
// the Android toolchain, which uses g++ -std=c++11 (4.8 as of 2014-03-11,
// according to Pullan Lu), does not support std::atanh. Android toolchain
s
// might define __ANDROID__ or ANDROID; so need to check both.
# if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 \ # if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 \
&& __cplusplus >= 201103 && !(defined(__ANDROID__) || defined(ANDROID)) && __cplusplus >= 201103 && !(defined(__ANDROID__) || defined(ANDROID))
// The android toolchain uses g++ and supports C++11, but not, apparently,
the
// new mathematical functions introduced with C++11. Android toolchains mi
ght
// define __ANDROID__ or ANDROID; so need to check both.
# define GEOGRAPHICLIB_CPLUSPLUS11_MATH 1 # define GEOGRAPHICLIB_CPLUSPLUS11_MATH 1
// Visual C++ 12 supports these functions
# elif defined(_MSC_VER) && _MSC_VER >= 1800 # elif defined(_MSC_VER) && _MSC_VER >= 1800
# define GEOGRAPHICLIB_CPLUSPLUS11_MATH 1 # define GEOGRAPHICLIB_CPLUSPLUS11_MATH 1
# else # else
# define GEOGRAPHICLIB_CPLUSPLUS11_MATH 0 # define GEOGRAPHICLIB_CPLUSPLUS11_MATH 0
# endif # endif
#endif #endif
#if !defined(WORDS_BIGENDIAN) #if !defined(WORDS_BIGENDIAN)
# define WORDS_BIGENDIAN 0 # define WORDS_BIGENDIAN 0
#endif #endif
skipping to change at line 128 skipping to change at line 131
/** /**
* true if the machine is big-endian. * true if the machine is big-endian.
********************************************************************** / ********************************************************************** /
static const bool bigendian = WORDS_BIGENDIAN; static const bool bigendian = WORDS_BIGENDIAN;
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return &pi;. * @return &pi;.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T pi() throw() template<typename T> static inline T pi()
{ return std::atan2(T(0), -T(1)); } { return std::atan2(T(0), -T(1)); }
/** /**
* A synonym for pi<real>(). * A synonym for pi<real>().
********************************************************************** / ********************************************************************** /
static inline real pi() throw() { return pi<real>(); } static inline real pi() { return pi<real>(); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return the number of radians in a degree. * @return the number of radians in a degree.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T degree() throw() template<typename T> static inline T degree()
{ return pi<T>() / T(180); } { return pi<T>() / T(180); }
/** /**
* A synonym for degree<real>(). * A synonym for degree<real>().
********************************************************************** / ********************************************************************** /
static inline real degree() throw() { return degree<real>(); } static inline real degree() { return degree<real>(); }
/** /**
* Square a number. * Square a number.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return <i>x</i><sup>2</sup>. * @return <i>x</i><sup>2</sup>.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T sq(T x) throw() template<typename T> static inline T sq(T x)
{ return x * x; } { return x * x; }
#if defined(DOXYGEN) #if defined(DOXYGEN)
/** /**
* The hypotenuse function avoiding underflow and overflow. * The hypotenuse function avoiding underflow and overflow.
* *
* @tparam T the type of the arguments and the returned value. * @tparam T the type of the arguments and the returned value.
* @param[in] x * @param[in] x
* @param[in] y * @param[in] y
* @return sqrt(<i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>). * @return sqrt(<i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T hypot(T x, T y) throw() { template<typename T> static inline T hypot(T x, T y) {
x = std::abs(x); y = std::abs(y); x = std::abs(x); y = std::abs(y);
T a = (std::max)(x, y), b = (std::min)(x, y) / (a ? a : 1); T a = (std::max)(x, y), b = (std::min)(x, y) / (a ? a : 1);
return a * std::sqrt(1 + b * b); return a * std::sqrt(1 + b * b);
// For an alternative (square-root free) method see // For an alternative (square-root free) method see
// C. Moler and D. Morrision (1983) http://dx.doi.org/10.1147/rd.276. 0577 // C. Moler and D. Morrision (1983) http://dx.doi.org/10.1147/rd.276. 0577
// and A. A. Dubrulle (1983) http://dx.doi.org/10.1147/rd.276.0582 // and A. A. Dubrulle (1983) http://dx.doi.org/10.1147/rd.276.0582
} }
#elif GEOGRAPHICLIB_CPLUSPLUS11_MATH || (defined(_MSC_VER) && _MSC_VER >= 1 700) #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH || (defined(_MSC_VER) && _MSC_VER >= 1 700)
template<typename T> static inline T hypot(T x, T y) throw() template<typename T> static inline T hypot(T x, T y)
{ return std::hypot(x, y); } { return std::hypot(x, y); }
# if HAVE_LONG_DOUBLE && defined(_MSC_VER) && _MSC_VER == 1700 # if HAVE_LONG_DOUBLE && defined(_MSC_VER) && _MSC_VER == 1700
// Visual C++ 11 doesn't have a long double overload for std::hypot -- // Visual C++ 11 doesn't have a long double overload for std::hypot --
// reported to MS on 2013-07-18 // reported to MS on 2013-07-18
// http://connect.microsoft.com/VisualStudio/feedback/details/794416 // http://connect.microsoft.com/VisualStudio/feedback/details/794416
// suppress the resulting "loss of data warning" with // (Visual C++ 12 is OK) Suppress the resulting "loss of data warning"
static inline long double hypot(long double x, long double y) throw() with
static inline long double hypot(long double x, long double y)
{ return std::hypot(double(x), double(y)); } { return std::hypot(double(x), double(y)); }
# endif # endif
#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)
{ return _hypot(x, y); } { return _hypot(x, y); }
# if _MSC_VER < 1400 # if _MSC_VER < 1400
// Visual C++ 7.1/VS .NET 2003 does not have _hypotf() // Visual C++ 7.1/VS .NET 2003 does not have _hypotf()
static inline float hypot(float x, float y) throw() static inline float hypot(float x, float y)
{ return float(_hypot(x, y)); } { return float(_hypot(x, y)); }
# else # else
static inline float hypot(float x, float y) throw() static inline float hypot(float x, float y)
{ return _hypotf(x, y); } { return _hypotf(x, y); }
# endif # endif
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double hypot(long double x, long double y) throw() static inline long double hypot(long double x, long double y)
{ return _hypot(double(x), double(y)); } // Suppress loss of data warni ng { return _hypot(double(x), double(y)); } // Suppress loss of data warni ng
# endif # endif
#else #else
// Use overloading to define generic versions // Use overloading to define generic versions
static inline double hypot(double x, double y) throw() static inline double hypot(double x, double y)
{ 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)
{ return ::hypotf(x, y); } { return ::hypotf(x, y); }
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double hypot(long double x, long double y) throw() static inline long double hypot(long double x, long double y)
{ return ::hypotl(x, y); } { return ::hypotl(x, y); }
# endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH) #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH)
/** /**
* exp(\e x) &minus; 1 accurate near \e x = 0. This is taken from * exp(\e x) &minus; 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.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return exp(\e x) &minus; 1. * @return exp(\e x) &minus; 1.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T expm1(T x) throw() { template<typename T> static inline T expm1(T x) {
volatile T 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_CPLUSPLUS11_MATH #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH
template<typename T> static inline T expm1(T x) throw() template<typename T> static inline T expm1(T x)
{ return std::expm1(x); } { return std::expm1(x); }
#else #else
static inline double expm1(double x) throw() { return ::expm1(x); } static inline double expm1(double x) { return ::expm1(x); }
static inline float expm1(float x) throw() { return ::expm1f(x); } static inline float expm1(float x) { return ::expm1f(x); }
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double expm1(long double x) throw() static inline long double expm1(long double x)
{ return ::expm1l(x); } { return ::expm1l(x); }
# endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH) #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH)
/** /**
* log(1 + \e x) accurate near \e x = 0. * log(1 + \e x) accurate near \e x = 0.
* *
* This is taken from D. Goldberg, * This is taken from D. Goldberg,
* <a href="http://dx.doi.org/10.1145/103162.103163">What every compute r * <a href="http://dx.doi.org/10.1145/103162.103163">What every compute r
* scientist should know about floating-point arithmetic</a> (1991), * scientist should know about floating-point arithmetic</a> (1991),
* Theorem 4. See also, Higham (op. cit.), Answer to Problem 1.5, p 52 8. * Theorem 4. See also, Higham (op. cit.), Answer to Problem 1.5, p 52 8.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return log(1 + \e x). * @return log(1 + \e x).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T log1p(T x) throw() { template<typename T> static inline T log1p(T x) {
volatile T 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_CPLUSPLUS11_MATH #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH
template<typename T> static inline T log1p(T x) throw() template<typename T> static inline T log1p(T x)
{ return std::log1p(x); } { return std::log1p(x); }
#else #else
static inline double log1p(double x) throw() { return ::log1p(x); } static inline double log1p(double x) { return ::log1p(x); }
static inline float log1p(float x) throw() { return ::log1pf(x); } static inline float log1p(float x) { return ::log1pf(x); }
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double log1p(long double x) throw() static inline long double log1p(long double x)
{ return ::log1pl(x); } { return ::log1pl(x); }
# endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH) #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_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.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return asinh(\e x). * @return asinh(\e x).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T asinh(T x) throw() { template<typename T> static inline T asinh(T x) {
T y = std::abs(x); // Enforce odd parity T y = std::abs(x); // Enforce odd parity
y = log1p(y * (1 + y/(hypot(T(1), y) + 1))); y = log1p(y * (1 + y/(hypot(T(1), y) + 1)));
return x < 0 ? -y : y; return x < 0 ? -y : y;
} }
#elif GEOGRAPHICLIB_CPLUSPLUS11_MATH #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH
template<typename T> static inline T asinh(T x) throw() template<typename T> static inline T asinh(T x)
{ return std::asinh(x); } { return std::asinh(x); }
#else #else
static inline double asinh(double x) throw() { return ::asinh(x); } static inline double asinh(double x) { return ::asinh(x); }
static inline float asinh(float x) throw() { return ::asinhf(x); } static inline float asinh(float x) { return ::asinhf(x); }
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double asinh(long double x) throw() static inline long double asinh(long double x)
{ return ::asinhl(x); } { return ::asinhl(x); }
# endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH) #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_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.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return atanh(\e x). * @return atanh(\e x).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T atanh(T x) throw() { template<typename T> static inline T atanh(T x) {
T y = std::abs(x); // Enforce odd parity 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_CPLUSPLUS11_MATH #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH
template<typename T> static inline T atanh(T x) throw() template<typename T> static inline T atanh(T x)
{ return std::atanh(x); } { return std::atanh(x); }
#else #else
static inline double atanh(double x) throw() { return ::atanh(x); } static inline double atanh(double x) { return ::atanh(x); }
static inline float atanh(float x) throw() { return ::atanhf(x); } static inline float atanh(float x) { return ::atanhf(x); }
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double atanh(long double x) throw() static inline long double atanh(long double x)
{ return ::atanhl(x); } { return ::atanhl(x); }
# endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH) #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH)
/** /**
* The cube root function. * The cube root function.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return the real cube root of \e x. * @return the real cube root of \e x.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T cbrt(T x) throw() { template<typename T> static inline T cbrt(T x) {
T y = std::pow(std::abs(x), 1/T(3)); // Return the real cube root 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_CPLUSPLUS11_MATH #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH
template<typename T> static inline T cbrt(T x) throw() template<typename T> static inline T cbrt(T x)
{ return std::cbrt(x); } { return std::cbrt(x); }
#else #else
static inline double cbrt(double x) throw() { return ::cbrt(x); } static inline double cbrt(double x) { return ::cbrt(x); }
static inline float cbrt(float x) throw() { return ::cbrtf(x); } static inline float cbrt(float x) { return ::cbrtf(x); }
# if HAVE_LONG_DOUBLE # if HAVE_LONG_DOUBLE
static inline long double cbrt(long double x) throw() { return ::cbrtl( x); } static inline long double cbrt(long double x) { return ::cbrtl(x); }
# endif # endif
#endif #endif
/** /**
* The error-free sum of two numbers. * The error-free sum of two numbers.
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] u * @param[in] u
* @param[in] v * @param[in] v
* @param[out] t the exact error given by (\e u + \e v) - \e s. * @param[out] t the exact error given by (\e u + \e v) - \e s.
* @return \e s = round(\e u + \e v). * @return \e s = round(\e u + \e v).
* *
* See D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B. (Note that \e t ca n be * See D. E. Knuth, TAOCP, Vol 2, 4.2.2, Theorem B. (Note that \e t ca n be
* the same as one of the first two arguments.) * the same as one of the first two arguments.)
********************************************************************** / ********************************************************************** /
template<typename T> static inline T sum(T u, T v, T& t) throw() { template<typename T> static inline T sum(T u, T v, T& t) {
volatile T s = u + v; volatile T s = u + v;
volatile T up = s - v; volatile T up = s - v;
volatile T vpp = s - up; volatile T vpp = s - up;
up -= u; up -= u;
vpp -= v; vpp -= v;
t = -(up + vpp); t = -(up + vpp);
// u + v = s + t // u + v = s + t
// = round(u + v) + t // = round(u + v) + t
return s; return s;
} }
/** /**
* Normalize an angle (restricted input range). * Normalize an angle (restricted input range).
* *
* @tparam T the type of the argument and returned value. * @tparam T the type of the argument and returned value.
* @param[in] x the angle in degrees. * @param[in] x the angle in degrees.
* @return the angle reduced to the range [&minus;180&deg;, 180&deg;). * @return the angle reduced to the range [&minus;180&deg;, 180&deg;).
* *
* \e x must lie in [&minus;540&deg;, 540&deg;). * \e x must lie in [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T AngNormalize(T x) throw() template<typename T> static inline T AngNormalize(T x)
{ return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); } { return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); }
/** /**
* Normalize an arbitrary angle. * Normalize an arbitrary angle.
* *
* @tparam T the type of the argument and returned value. * @tparam T the type of the argument and returned value.
* @param[in] x the angle in degrees. * @param[in] x the angle in degrees.
* @return the angle reduced to the range [&minus;180&deg;, 180&deg;). * @return the angle reduced to the range [&minus;180&deg;, 180&deg;).
* *
* The range of \e x is unrestricted. * The range of \e x is unrestricted.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T AngNormalize2(T x) throw() template<typename T> static inline T AngNormalize2(T x)
{ return AngNormalize<T>(std::fmod(x, T(360))); } { return AngNormalize<T>(std::fmod(x, T(360))); }
/** /**
* Difference of two angles reduced to [&minus;180&deg;, 180&deg;] * Difference of two angles reduced to [&minus;180&deg;, 180&deg;]
* *
* @tparam T the type of the arguments and returned value. * @tparam T the type of the arguments and returned value.
* @param[in] x the first angle in degrees. * @param[in] x the first angle in degrees.
* @param[in] y the second angle in degrees. * @param[in] y the second angle in degrees.
* @return \e y &minus; \e x, reduced to the range [&minus;180&deg;, * @return \e y &minus; \e x, reduced to the range [&minus;180&deg;,
* 180&deg;]. * 180&deg;].
* *
* \e x and \e y must both lie in [&minus;180&deg;, 180&deg;]. The res ult * \e x and \e y must both lie in [&minus;180&deg;, 180&deg;]. The res ult
* is equivalent to computing the difference exactly, reducing it to * is equivalent to computing the difference exactly, reducing it to
* (&minus;180&deg;, 180&deg;] and rounding the result. Note that this * (&minus;180&deg;, 180&deg;] and rounding the result. Note that this
* prescription allows &minus;180&deg; to be returned (e.g., if \e x is * prescription allows &minus;180&deg; to be returned (e.g., if \e x is
* tiny and negative and \e y = 180&deg;). * tiny and negative and \e y = 180&deg;).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T AngDiff(T x, T y) throw() { template<typename T> static inline T AngDiff(T x, T y) {
T t, d = sum(-x, y, t); T t, d = sum(-x, y, t);
if ((d - T(180)) + t > T(0)) // y - x > 180 if ((d - T(180)) + t > T(0)) // y - x > 180
d -= T(360); // exact d -= T(360); // exact
else if ((d + T(180)) + t <= T(0)) // y - x <= -180 else if ((d + T(180)) + t <= T(0)) // y - x <= -180
d += T(360); // exact d += T(360); // exact
return d + t; return d + t;
} }
#if defined(DOXYGEN) #if defined(DOXYGEN)
/** /**
* Test for finiteness. * Test for finiteness.
* *
* @tparam T the type of the argument. * @tparam T the type of the argument.
* @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.
********************************************************************** / ********************************************************************** /
template<typename T> static inline bool isfinite(T x) throw() { template<typename T> static inline bool isfinite(T x) {
return std::abs(x) <= (std::numeric_limits<T>::max)(); return std::abs(x) <= (std::numeric_limits<T>::max)();
} }
#elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH) #elif (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MATH)
template<typename T> static inline bool isfinite(T x) throw() { template<typename T> static inline bool isfinite(T x) {
return _finite(double(x)) != 0; return _finite(double(x)) != 0;
} }
#elif defined(_LIBCPP_VERSION) #elif defined(_LIBCPP_VERSION)
// libc++ implements std::isfinite() as a template that only allows // libc++ implements std::isfinite() as a template that only allows
// floating-point types. isfinite is invoked by Utility::str to format // floating-point types. isfinite is invoked by Utility::str to format
// numbers conveniently and this allows integer arguments, so we need t o // numbers conveniently and this allows integer arguments, so we need t o
// allow Math::isfinite to work on integers. // allow Math::isfinite to work on integers.
template<typename T> static inline template<typename T> static inline
typename std::enable_if<std::is_floating_point<T>::value, bool>::type typename std::enable_if<std::is_floating_point<T>::value, bool>::type
isfinite(T x) throw() { isfinite(T x) {
return std::isfinite(x); return std::isfinite(x);
} }
template<typename T> static inline template<typename T> static inline
typename std::enable_if<!std::is_floating_point<T>::value, bool>::type typename std::enable_if<!std::is_floating_point<T>::value, bool>::type
isfinite(T /*x*/) throw() { isfinite(T /*x*/) {
return true; return true;
} }
#else #else
template<typename T> static inline bool isfinite(T x) throw() { template<typename T> static inline bool isfinite(T x) {
return std::isfinite(x); return std::isfinite(x);
} }
#endif #endif
/** /**
* The NaN (not a number) * The NaN (not a number)
* *
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return NaN if available, otherwise return the max real of type T. * @return NaN if available, otherwise return the max real of type T.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T NaN() throw() { template<typename T> static inline T NaN() {
return std::numeric_limits<T>::has_quiet_NaN ? return std::numeric_limits<T>::has_quiet_NaN ?
std::numeric_limits<T>::quiet_NaN() : std::numeric_limits<T>::quiet_NaN() :
(std::numeric_limits<T>::max)(); (std::numeric_limits<T>::max)();
} }
/** /**
* A synonym for NaN<real>(). * A synonym for NaN<real>().
********************************************************************** / ********************************************************************** /
static inline real NaN() throw() { return NaN<real>(); } static inline real NaN() { return NaN<real>(); }
/** /**
* Test for NaN. * Test for NaN.
* *
* @tparam T the type of the argument. * @tparam T the type of the argument.
* @param[in] x * @param[in] x
* @return true if argument is a NaN. * @return true if argument is a NaN.
********************************************************************** / ********************************************************************** /
template<typename T> static inline bool isnan(T x) throw() { template<typename T> static inline bool isnan(T x) {
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH) #if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_CPLUSPLUS11_MA TH)
return x != x; return x != x;
#else #else
return std::isnan(x); return std::isnan(x);
#endif #endif
} }
/** /**
* Infinity * Infinity
* *
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
* @return infinity if available, otherwise return the max real. * @return infinity if available, otherwise return the max real.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T infinity() throw() { template<typename T> static inline T infinity() {
return std::numeric_limits<T>::has_infinity ? return std::numeric_limits<T>::has_infinity ?
std::numeric_limits<T>::infinity() : std::numeric_limits<T>::infinity() :
(std::numeric_limits<T>::max)(); (std::numeric_limits<T>::max)();
} }
/** /**
* A synonym for infinity<real>(). * A synonym for infinity<real>().
********************************************************************** / ********************************************************************** /
static inline real infinity() throw() { return infinity<real>(); } static inline real infinity() { return infinity<real>(); }
/** /**
* Swap the bytes of a quantity * Swap the bytes of a quantity
* *
* @tparam T the type of the argument and the returned value. * @tparam T the type of the argument and the returned value.
* @param[in] x * @param[in] x
* @return x with its bytes swapped. * @return x with its bytes swapped.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T swab(T x) { template<typename T> static inline T swab(T x) {
union { union {
 End of changes. 52 change blocks. 
60 lines changed or deleted 65 lines changed or added


 NormalGravity.hpp   NormalGravity.hpp 
skipping to change at line 68 skipping to change at line 68
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT NormalGravity { class GEOGRAPHICLIB_EXPORT NormalGravity {
private: private:
static const int maxit_ = 10; static const int maxit_ = 10;
typedef Math::real real; typedef Math::real real;
friend class GravityModel; friend class GravityModel;
real _a, _GM, _omega, _f, _J2, _omega2, _aomega2; real _a, _GM, _omega, _f, _J2, _omega2, _aomega2;
real _e2, _ep2, _b, _E, _U0, _gammae, _gammap, _q0, _m, _k, _fstar; real _e2, _ep2, _b, _E, _U0, _gammae, _gammap, _q0, _m, _k, _fstar;
Geocentric _earth; Geocentric _earth;
static Math::real qf(real ep2) throw(); static Math::real qf(real ep2);
static Math::real qpf(real ep2) throw(); static Math::real qpf(real ep2);
Math::real Jn(int n) const throw(); Math::real Jn(int n) const;
public: public:
/** \name Setting up the normal gravity /** \name Setting up the normal gravity
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Constructor for the normal gravity. * Constructor for the normal gravity.
* *
* @param[in] a equatorial radius (meters). * @param[in] a equatorial radius (meters).
* @param[in] GM mass constant of the ellipsoid * @param[in] GM mass constant of the ellipsoid
skipping to change at line 126 skipping to change at line 126
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
* @return &gamma; the acceleration due to gravity, positive downwards * @return &gamma; the acceleration due to gravity, positive downwards
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* *
* Due to the axial symmetry of the ellipsoid, the result is independen t of * Due to the axial symmetry of the ellipsoid, the result is independen t of
* the value of the longitude. This acceleration is perpendicular to t he * the value of the longitude. This acceleration is perpendicular to t he
* surface of the ellipsoid. It includes the effects of the earth's * surface of the ellipsoid. It includes the effects of the earth's
* rotation. * rotation.
********************************************************************** / ********************************************************************** /
Math::real SurfaceGravity(real lat) const throw(); Math::real SurfaceGravity(real lat) const;
/** /**
* Evaluate the gravity at an arbitrary point above (or below) the * Evaluate the gravity at an arbitrary point above (or below) the
* ellipsoid. * ellipsoid.
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
* @param[in] h the height above the ellipsoid (meters). * @param[in] h the height above the ellipsoid (meters).
* @param[out] gammay the northerly component of the acceleration * @param[out] gammay the northerly component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gammaz the upward component of the acceleration * @param[out] gammaz the upward component of the acceleration
* (m s<sup>&minus;2</sup>); this is usually negative. * (m s<sup>&minus;2</sup>); this is usually negative.
* @return \e U the corresponding normal potential. * @return \e U the corresponding normal potential.
* *
* Due to the axial symmetry of the ellipsoid, the result is independen t of * Due to the axial symmetry of the ellipsoid, the result is independen t of
* the value of the longitude and the easterly component of the * the value of the longitude and the easterly component of the
* acceleration vanishes, \e gammax = 0. The function includes the eff ects * acceleration vanishes, \e gammax = 0. The function includes the eff ects
* of the earth's rotation. When \e h = 0, this function gives \e gamm ay = * of the earth's rotation. When \e h = 0, this function gives \e gamm ay =
* 0 and the returned value matches that of NormalGravity::SurfaceGravi ty. * 0 and the returned value matches that of NormalGravity::SurfaceGravi ty.
********************************************************************** / ********************************************************************** /
Math::real Gravity(real lat, real h, real& gammay, real& gammaz) Math::real Gravity(real lat, real h, real& gammay, real& gammaz)
const throw(); const;
/** /**
* Evaluate the components of the acceleration due to gravity and the * Evaluate the components of the acceleration due to gravity and the
* centrifugal acceleration in geocentric coordinates. * centrifugal acceleration in geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[in] Z geocentric coordinate of point (meters). * @param[in] Z geocentric coordinate of point (meters).
* @param[out] gammaX the \e X component of the acceleration * @param[out] gammaX the \e X component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
skipping to change at line 170 skipping to change at line 170
* @param[out] gammaZ the \e Z component of the acceleration * @param[out] gammaZ the \e Z component of the acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e U = <i>V</i><sub>0</sub> + &Phi; the sum of the * @return \e U = <i>V</i><sub>0</sub> + &Phi; the sum of the
* gravitational and centrifugal potentials * gravitational and centrifugal potentials
* (m<sup>2</sup> s<sup>&minus;2</sup>). * (m<sup>2</sup> s<sup>&minus;2</sup>).
* *
* The acceleration given by <b>&gamma;</b> = &nabla;\e U = * The acceleration given by <b>&gamma;</b> = &nabla;\e U =
* &nabla;<i>V</i><sub>0</sub> + &nabla;&Phi; = <b>&Gamma;</b> + <b>f</ b>. * &nabla;<i>V</i><sub>0</sub> + &nabla;&Phi; = <b>&Gamma;</b> + <b>f</ b>.
********************************************************************** / ********************************************************************** /
Math::real U(real X, real Y, real Z, Math::real U(real X, real Y, real Z,
real& gammaX, real& gammaY, real& gammaZ) const throw(); real& gammaX, real& gammaY, real& gammaZ) const;
/** /**
* Evaluate the components of the acceleration due to gravity alone in * Evaluate the components of the acceleration due to gravity alone in
* geocentric coordinates. * geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[in] Z geocentric coordinate of point (meters). * @param[in] Z geocentric coordinate of point (meters).
* @param[out] GammaX the \e X component of the acceleration due to gra vity * @param[out] GammaX the \e X component of the acceleration due to gra vity
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
skipping to change at line 194 skipping to change at line 194
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return <i>V</i><sub>0</sub> the gravitational potential * @return <i>V</i><sub>0</sub> the gravitational potential
* (m<sup>2</sup> s<sup>&minus;2</sup>). * (m<sup>2</sup> s<sup>&minus;2</sup>).
* *
* This function excludes the centrifugal acceleration and is appropria te * This function excludes the centrifugal acceleration and is appropria te
* to use for space applications. In terrestrial applications, the * to use for space applications. In terrestrial applications, the
* function NormalGravity::U (which includes this effect) should usuall y be * function NormalGravity::U (which includes this effect) should usuall y be
* used. * used.
********************************************************************** / ********************************************************************** /
Math::real V0(real X, real Y, real Z, Math::real V0(real X, real Y, real Z,
real& GammaX, real& GammaY, real& GammaZ) const throw(); real& GammaX, real& GammaY, real& GammaZ) const;
/** /**
* Evaluate the centrifugal acceleration in geocentric coordinates. * Evaluate the centrifugal acceleration in geocentric coordinates.
* *
* @param[in] X geocentric coordinate of point (meters). * @param[in] X geocentric coordinate of point (meters).
* @param[in] Y geocentric coordinate of point (meters). * @param[in] Y geocentric coordinate of point (meters).
* @param[out] fX the \e X component of the centrifugal acceleration * @param[out] fX the \e X component of the centrifugal acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] fY the \e Y component of the centrifugal acceleration * @param[out] fY the \e Y component of the centrifugal acceleration
* (m s<sup>&minus;2</sup>). * (m s<sup>&minus;2</sup>).
* @return &Phi; the centrifugal potential (m<sup>2</sup> * @return &Phi; the centrifugal potential (m<sup>2</sup>
* s<sup>&minus;2</sup>). * s<sup>&minus;2</sup>).
* *
* &Phi; is independent of \e Z, thus \e fZ = 0. This function * &Phi; is independent of \e Z, thus \e fZ = 0. This function
* NormalGravity::U sums the results of NormalGravity::V0 and * NormalGravity::U sums the results of NormalGravity::V0 and
* NormalGravity::Phi. * NormalGravity::Phi.
********************************************************************** / ********************************************************************** /
Math::real Phi(real X, real Y, real& fX, real& fY) const throw(); Math::real Phi(real X, real Y, real& fX, real& fY) const;
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return true if the object has been initialized. * @return true if the object has been initialized.
********************************************************************** / ********************************************************************** /
bool Init() const throw() { return _a > 0; } bool Init() const { return _a > 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 used in the constructor. * the value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() Math::real MajorRadius() const
{ return Init() ? _a : Math::NaN<real>(); } { return Init() ? _a : Math::NaN<real>(); }
/** /**
* @return \e GM the mass constant of the ellipsoid * @return \e GM the mass constant of the ellipsoid
* (m<sup>3</sup> s<sup>&minus;2</sup>). This is the value used in t he * (m<sup>3</sup> s<sup>&minus;2</sup>). This is the value used in t he
* constructor. * constructor.
********************************************************************** / ********************************************************************** /
Math::real MassConstant() const throw() Math::real MassConstant() const
{ return Init() ? _GM : Math::NaN<real>(); } { return Init() ? _GM : Math::NaN<real>(); }
/** /**
* @return \e J<sub>n</sub> the dynamical form factors of the ellipsoid . * @return \e J<sub>n</sub> the dynamical form factors of the ellipsoid .
* *
* If \e n = 2 (the default), this is the value of <i>J</i><sub>2</sub> * If \e n = 2 (the default), this is the value of <i>J</i><sub>2</sub>
* used in the constructor. Otherwise it is the zonal coefficient of t he * used in the constructor. Otherwise it is the zonal coefficient of t he
* Legendre harmonic sum of the normal gravitational potential. Note t hat * Legendre harmonic sum of the normal gravitational potential. Note t hat
* \e J<sub>n</sub> = 0 if \e n is odd. In most gravity applications, * \e J<sub>n</sub> = 0 if \e n is odd. In most gravity applications,
* fully normalized Legendre functions are used and the corresponding * fully normalized Legendre functions are used and the corresponding
* coefficient is <i>C</i><sub><i>n</i>0</sub> = &minus;\e J<sub>n</sub > / * coefficient is <i>C</i><sub><i>n</i>0</sub> = &minus;\e J<sub>n</sub > /
* sqrt(2 \e n + 1). * sqrt(2 \e n + 1).
********************************************************************** / ********************************************************************** /
Math::real DynamicalFormFactor(int n = 2) const throw() Math::real DynamicalFormFactor(int n = 2) const
{ return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN<real>(); } { return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN<real>(); }
/** /**
* @return &omega; the angular velocity of the ellipsoid (rad * @return &omega; the angular velocity of the ellipsoid (rad
* s<sup>&minus;1</sup>). This is the value used in the constructor. * s<sup>&minus;1</sup>). This is the value used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real AngularVelocity() const throw() Math::real AngularVelocity() const
{ return Init() ? _omega : Math::NaN<real>(); } { return Init() ? _omega : Math::NaN<real>(); }
/** /**
* @return <i>f</i> the flattening of the ellipsoid (\e a &minus; \e b) /\e * @return <i>f</i> the flattening of the ellipsoid (\e a &minus; \e b) /\e
* a. * a.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
/** /**
* @return &gamma;<sub>e</sub> the normal gravity at equator (m * @return &gamma;<sub>e</sub> the normal gravity at equator (m
* s<sup>&minus;2</sup>). * s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real EquatorialGravity() const throw() Math::real EquatorialGravity() const
{ return Init() ? _gammae : Math::NaN<real>(); } { return Init() ? _gammae : Math::NaN<real>(); }
/** /**
* @return &gamma;<sub>p</sub> the normal gravity at poles (m * @return &gamma;<sub>p</sub> the normal gravity at poles (m
* s<sup>&minus;2</sup>). * s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real PolarGravity() const throw() Math::real PolarGravity() const
{ return Init() ? _gammap : Math::NaN<real>(); } { return Init() ? _gammap : Math::NaN<real>(); }
/** /**
* @return <i>f*</i> the gravity flattening (&gamma;<sub>p</sub> &minus ; * @return <i>f*</i> the gravity flattening (&gamma;<sub>p</sub> &minus ;
* &gamma;<sub>e</sub>) / &gamma;<sub>e</sub>. * &gamma;<sub>e</sub>) / &gamma;<sub>e</sub>.
********************************************************************** / ********************************************************************** /
Math::real GravityFlattening() const throw() Math::real GravityFlattening() const
{ return Init() ? _fstar : Math::NaN<real>(); } { return Init() ? _fstar : Math::NaN<real>(); }
/** /**
* @return <i>U</i><sub>0</sub> the constant normal potential for the * @return <i>U</i><sub>0</sub> the constant normal potential for the
* surface of the ellipsoid (m<sup>2</sup> s<sup>&minus;2</sup>). * surface of the ellipsoid (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real SurfacePotential() const throw() Math::real SurfacePotential() const
{ return Init() ? _U0 : Math::NaN<real>(); } { return Init() ? _U0 : Math::NaN<real>(); }
/** /**
* @return the Geocentric object used by this instance. * @return the Geocentric object used by this instance.
********************************************************************** / ********************************************************************** /
const Geocentric& Earth() const throw() { return _earth; } const Geocentric& Earth() const { return _earth; }
///@} ///@}
/** /**
* A global instantiation of NormalGravity for the WGS84 ellipsoid. * A global instantiation of NormalGravity for the WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
static const NormalGravity WGS84; static const NormalGravity WGS84;
/** /**
* A global instantiation of NormalGravity for the GRS80 ellipsoid. * A global instantiation of NormalGravity for the GRS80 ellipsoid.
********************************************************************** / ********************************************************************** /
 End of changes. 17 change blocks. 
19 lines changed or deleted 19 lines changed or added


 OSGB.hpp   OSGB.hpp 
skipping to change at line 66 skipping to change at line 66
tilegrid_ = 5, tilegrid_ = 5,
tileoffx_ = 2 * tilegrid_, tileoffx_ = 2 * tilegrid_,
tileoffy_ = 1 * tilegrid_, tileoffy_ = 1 * tilegrid_,
minx_ = - tileoffx_ * tile_, minx_ = - tileoffx_ * tile_,
miny_ = - tileoffy_ * tile_, miny_ = - tileoffy_ * tile_,
maxx_ = (tilegrid_*tilegrid_ - tileoffx_) * tile_, maxx_ = (tilegrid_*tilegrid_ - tileoffx_) * tile_,
maxy_ = (tilegrid_*tilegrid_ - tileoffy_) * tile_, maxy_ = (tilegrid_*tilegrid_ - tileoffy_) * tile_,
// Maximum precision is um // Maximum precision is um
maxprec_ = 5 + 6, maxprec_ = 5 + 6,
}; };
static real computenorthoffset() throw(); static real computenorthoffset();
static void CheckCoords(real x, real y); static void CheckCoords(real x, real y);
OSGB(); // Disable constructor OSGB(); // Disable constructor
public: public:
/** /**
* Forward projection, from geographic to OSGB coordinates. * Forward projection, from geographic to OSGB coordinates.
* *
* @param[in] lat latitude of point (degrees). * @param[in] lat latitude of point (degrees).
* @param[in] lon longitude of point (degrees). * @param[in] lon longitude of point (degrees).
* @param[out] x easting of point (meters). * @param[out] x easting of point (meters).
* @param[out] y northing of point (meters). * @param[out] y northing of point (meters).
* @param[out] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon * \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
* should be in the range [&minus;540&deg;, 540&deg;). * should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
static void Forward(real lat, real lon, static void Forward(real lat, real lon,
real& x, real& y, real& gamma, real& k) throw() { real& x, real& y, real& gamma, real& k) {
OSGBTM_.Forward(OriginLongitude(), lat, lon, x, y, gamma, k); OSGBTM_.Forward(OriginLongitude(), lat, lon, x, y, gamma, k);
x += FalseEasting(); x += FalseEasting();
y += computenorthoffset(); y += computenorthoffset();
} }
/** /**
* Reverse projection, from OSGB coordinates to geographic. * Reverse projection, from OSGB coordinates to geographic.
* *
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* The value of \e lon returned is in the range [&minus;180&deg;, * The value of \e lon returned is in the range [&minus;180&deg;,
* 180&deg;). * 180&deg;).
********************************************************************** / ********************************************************************** /
static void Reverse(real x, real y, static void Reverse(real x, real y,
real& lat, real& lon, real& gamma, real& k) throw() { real& lat, real& lon, real& gamma, real& k) {
x -= FalseEasting(); x -= FalseEasting();
y -= computenorthoffset(); y -= computenorthoffset();
OSGBTM_.Reverse(OriginLongitude(), x, y, lat, lon, gamma, k); OSGBTM_.Reverse(OriginLongitude(), x, y, lat, lon, gamma, k);
} }
/** /**
* OSGB::Forward without returning the convergence and scale. * OSGB::Forward without returning the convergence and scale.
********************************************************************** / ********************************************************************** /
static void Forward(real lat, real lon, real& x, real& y) throw() { static void Forward(real lat, real lon, real& x, real& y) {
real gamma, k; real gamma, k;
Forward(lat, lon, x, y, gamma, k); Forward(lat, lon, x, y, gamma, k);
} }
/** /**
* OSGB::Reverse without returning the convergence and scale. * OSGB::Reverse without returning the convergence and scale.
********************************************************************** / ********************************************************************** /
static void Reverse(real x, real y, real& lat, real& lon) throw() { static void Reverse(real x, real y, real& lat, real& lon) {
real gamma, k; real gamma, k;
Reverse(x, y, lat, lon, gamma, k); Reverse(x, y, lat, lon, gamma, k);
} }
/** /**
* Convert OSGB coordinates to a grid reference. * Convert OSGB coordinates to a grid reference.
* *
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (meters).
* @param[in] prec precision relative to 100 km. * @param[in] prec precision relative to 100 km.
skipping to change at line 185 skipping to change at line 185
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @return \e a the equatorial radius of the Airy 1830 ellipsoid (meter s). * @return \e a the equatorial radius of the Airy 1830 ellipsoid (meter s).
* *
* This is 20923713 ft converted to meters using the rule 1 ft = * This is 20923713 ft converted to meters using the rule 1 ft =
* 10<sup>9.48401603&minus;10</sup> m. (The Airy 1830 value is returne d * 10<sup>9.48401603&minus;10</sup> m. (The Airy 1830 value is returne d
* because the OSGB projection is based on this ellipsoid.) * because the OSGB projection is based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
static Math::real MajorRadius() throw() static Math::real MajorRadius()
// result is about 6377563.3960320664406 m // result is about 6377563.3960320664406 m
{ return real(20923713) * std::pow(real(10), real(0.48401603L) - 1); } { return real(20923713) * std::pow(real(10), real(0.48401603L) - 1); }
/** /**
* @return \e f the inverse flattening of the Airy 1830 ellipsoid. * @return \e f the inverse flattening of the Airy 1830 ellipsoid.
* *
* For the Airy 1830 ellipsoid, \e a = 20923713 ft and \e b = 20853810 ft; * For the Airy 1830 ellipsoid, \e a = 20923713 ft and \e b = 20853810 ft;
* thus the flattening = (20923713 &minus; 20853810)/20923713 = * thus the flattening = (20923713 &minus; 20853810)/20923713 =
* 7767/2324857 = 1/299.32496459... (The Airy 1830 value is returned * 7767/2324857 = 1/299.32496459... (The Airy 1830 value is returned
* because the OSGB projection is based on this ellipsoid.) * because the OSGB projection is based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
static Math::real Flattening() throw() static Math::real Flattening()
{ return real(20923713 - 20853810) / real(20923713); } { return real(20923713 - 20853810) / real(20923713); }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the Airy 1830 ellipsoid. * @return \e r the inverse flattening of the Airy 1830 ellipsoid.
********************************************************************** / ********************************************************************** /
static Math::real InverseFlattening() throw() { return 1/Flattening(); } static Math::real InverseFlattening() { return 1/Flattening(); }
/// \endcond /// \endcond
/** /**
* @return \e k0 central scale for the OSGB projection (0.9996012717... ). * @return \e k0 central scale for the OSGB projection (0.9996012717... ).
* *
* C. J. Mugnier, Grids &amp; Datums, PE&amp;RS, Oct. 2003, states that * C. J. Mugnier, Grids &amp; Datums, PE&amp;RS, Oct. 2003, states that
* this is defined as 10<sup>9.9998268&minus;10</sup>. * this is defined as 10<sup>9.9998268&minus;10</sup>.
********************************************************************** / ********************************************************************** /
static Math::real CentralScale() throw() static Math::real CentralScale()
{ return std::pow(real(10), real(9998268 - 10000000) / real(10000000)); } { return std::pow(real(10), real(9998268 - 10000000) / real(10000000)); }
/** /**
* @return latitude of the origin for the OSGB projection (49 degrees). * @return latitude of the origin for the OSGB projection (49 degrees).
********************************************************************** / ********************************************************************** /
static Math::real OriginLatitude() throw() { return real(49); } static Math::real OriginLatitude() { return real(49); }
/** /**
* @return longitude of the origin for the OSGB projection (&minus;2 * @return longitude of the origin for the OSGB projection (&minus;2
* degrees). * degrees).
********************************************************************** / ********************************************************************** /
static Math::real OriginLongitude() throw() { return real(-2); } static Math::real OriginLongitude() { return real(-2); }
/** /**
* @return false northing the OSGB projection (&minus;100000 meters). * @return false northing the OSGB projection (&minus;100000 meters).
********************************************************************** / ********************************************************************** /
static Math::real FalseNorthing() throw() { return real(-100000); } static Math::real FalseNorthing() { return real(-100000); }
/** /**
* @return false easting the OSGB projection (400000 meters). * @return false easting the OSGB projection (400000 meters).
********************************************************************** / ********************************************************************** /
static Math::real FalseEasting() throw() { return real(400000); } static Math::real FalseEasting() { return real(400000); }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning (pop) # pragma warning (pop)
#endif #endif
 End of changes. 13 change blocks. 
13 lines changed or deleted 13 lines changed or added


 PolarStereographic.hpp   PolarStereographic.hpp 
skipping to change at line 42 skipping to change at line 42
class GEOGRAPHICLIB_EXPORT PolarStereographic { class GEOGRAPHICLIB_EXPORT PolarStereographic {
private: private:
typedef Math::real real; typedef Math::real real;
// _Cx used to be _C but g++ 3.4 has a macro of that name // _Cx used to be _C but g++ 3.4 has a macro of that name
real _a, _f, _e2, _e, _e2m, _Cx, _c; real _a, _f, _e2, _e, _e2m, _Cx, _c;
real _k0; real _k0;
static const real tol_; static const real tol_;
static const real overflow_; static const real overflow_;
static const int numit_ = 5; static const int numit_ = 5;
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) throw() { static inline real tanx(real x) {
real t = std::tan(x); real t = std::tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN() // Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl ow_); return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl ow_);
} }
// Return e * atanh(e * x) for f >= 0, else return // Return e * atanh(e * x) for f >= 0, else return
// - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0 // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
inline real eatanhe(real x) const throw() inline real eatanhe(real x) const
{ return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); } { return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); }
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] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re. * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re.
* Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing
* to 1/\e f. * to 1/\e f.
skipping to change at line 95 skipping to change at line 95
* @param[out] y northing of point (meters). * @param[out] y northing of point (meters).
* @param[out] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* No false easting or northing is added. \e lat should be in the rang e * No false easting or northing is added. \e lat should be in the rang e
* (&minus;90&deg;, 90&deg;] for \e northp = true and in the range * (&minus;90&deg;, 90&deg;] for \e northp = true and in the range
* [&minus;90&deg;, 90&deg;) for \e northp = false; \e lon should * [&minus;90&deg;, 90&deg;) for \e northp = false; \e lon should
* be in the range [&minus;540&deg;, 540&deg;). * be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void Forward(bool northp, real lat, real lon, void Forward(bool northp, real lat, real lon,
real& x, real& y, real& gamma, real& k) const throw(); real& x, real& y, real& gamma, real& k) const;
/** /**
* Reverse projection, from polar stereographic to geographic. * Reverse projection, from polar stereographic to geographic.
* *
* @param[in] northp the pole which is the center of projection (true m eans * @param[in] northp the pole which is the center of projection (true m eans
* north, false means south). * north, false means south).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* No false easting or northing is added. The value of \e lon returned is * No false easting or northing is added. The value of \e lon returned is
* in the range [&minus;180&deg;, 180&deg;). * in the range [&minus;180&deg;, 180&deg;).
********************************************************************** / ********************************************************************** /
void Reverse(bool northp, real x, real y, void Reverse(bool northp, real x, real y,
real& lat, real& lon, real& gamma, real& k) const throw(); real& lat, real& lon, real& gamma, real& k) const;
/** /**
* PolarStereographic::Forward without returning the convergence and sc ale. * PolarStereographic::Forward without returning the convergence and sc ale.
********************************************************************** / ********************************************************************** /
void Forward(bool northp, real lat, real lon, void Forward(bool northp, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real gamma, k; real gamma, k;
Forward(northp, lat, lon, x, y, gamma, k); Forward(northp, lat, lon, x, y, gamma, k);
} }
/** /**
* PolarStereographic::Reverse without returning the convergence and sc ale. * PolarStereographic::Reverse without returning the convergence and sc ale.
********************************************************************** / ********************************************************************** /
void Reverse(bool northp, real x, real y, void Reverse(bool northp, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real gamma, k; real gamma, k;
Reverse(northp, x, y, lat, lon, gamma, k); Reverse(northp, x, y, lat, lon, gamma, k);
} }
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value use d in * @return \e f the flattening of the ellipsoid. This is the value use d in
* the constructor. * the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* The central scale for the projection. This is the value of \e k0 us ed * The central scale for the projection. This is the value of \e k0 us ed
* in the constructor and is the scale at the pole unless overridden by * in the constructor and is the scale at the pole unless overridden by
* PolarStereographic::SetScale. * PolarStereographic::SetScale.
********************************************************************** / ********************************************************************** /
Math::real CentralScale() const throw() { return _k0; } Math::real CentralScale() const { return _k0; }
///@} ///@}
/** /**
* A global instantiation of PolarStereographic with the WGS84 ellipsoi d * A global instantiation of PolarStereographic with the WGS84 ellipsoi d
* and the UPS scale factor. However, unlike UPS, no false easting or * and the UPS scale factor. However, unlike UPS, no false easting or
* northing is added. * northing is added.
********************************************************************** / ********************************************************************** /
static const PolarStereographic UPS; static const PolarStereographic UPS;
}; };
 End of changes. 10 change blocks. 
10 lines changed or deleted 10 lines changed or added


 PolygonArea.hpp   PolygonArea.hpp 
skipping to change at line 66 skipping to change at line 66
private: private:
typedef Math::real real; typedef Math::real real;
Geodesic _earth; Geodesic _earth;
real _area0; // Full ellipsoid area real _area0; // Full ellipsoid area
bool _polyline; // Assume polyline (don't close and skip ar ea) bool _polyline; // Assume polyline (don't close and skip ar ea)
unsigned _mask; unsigned _mask;
unsigned _num; unsigned _num;
int _crossings; int _crossings;
Accumulator<real> _areasum, _perimetersum; Accumulator<real> _areasum, _perimetersum;
real _lat0, _lon0, _lat1, _lon1; real _lat0, _lon0, _lat1, _lon1;
static inline int transit(real lon1, real lon2) throw() { static inline int transit(real lon1, real lon2) {
// Return 1 or -1 if crossing prime meridian in east or west directio n. // Return 1 or -1 if crossing prime meridian in east or west directio n.
// Otherwise return zero. // Otherwise return zero.
// Compute lon12 the same way as Geodesic::Inverse. // Compute lon12 the same way as Geodesic::Inverse.
lon1 = Math::AngNormalize(lon1); lon1 = Math::AngNormalize(lon1);
lon2 = Math::AngNormalize(lon2); lon2 = Math::AngNormalize(lon2);
real lon12 = Math::AngDiff(lon1, lon2); real lon12 = Math::AngDiff(lon1, lon2);
int cross = int cross =
lon1 < 0 && lon2 >= 0 && lon12 > 0 ? 1 : lon1 < 0 && lon2 >= 0 && lon12 > 0 ? 1 :
(lon2 < 0 && lon1 >= 0 && lon12 < 0 ? -1 : 0); (lon2 < 0 && lon1 >= 0 && lon12 < 0 ? -1 : 0);
return cross; return cross;
skipping to change at line 88 skipping to change at line 88
public: public:
/** /**
* Constructor for PolygonArea. * Constructor for PolygonArea.
* *
* @param[in] earth the Geodesic object to use for geodesic calculation s. * @param[in] earth the Geodesic object to use for geodesic calculation s.
* By default this uses the WGS84 ellipsoid. * By default this uses the WGS84 ellipsoid.
* @param[in] polyline if true that treat the points as defining a poly line * @param[in] polyline if true that treat the points as defining a poly line
* instead of a polygon (default = false). * instead of a polygon (default = false).
********************************************************************** / ********************************************************************** /
PolygonArea(const Geodesic& earth, bool polyline = false) throw() PolygonArea(const Geodesic& earth, bool polyline = false)
: _earth(earth) : _earth(earth)
, _area0(_earth.EllipsoidArea()) , _area0(_earth.EllipsoidArea())
, _polyline(polyline) , _polyline(polyline)
, _mask(Geodesic::LATITUDE | Geodesic::LONGITUDE | Geodesic::DISTANCE | , _mask(Geodesic::LATITUDE | Geodesic::LONGITUDE | Geodesic::DISTANCE |
(_polyline ? Geodesic::NONE : Geodesic::AREA)) (_polyline ? Geodesic::NONE : Geodesic::AREA))
{ Clear(); } { Clear(); }
/** /**
* Clear PolygonArea, allowing a new polygon to be started. * Clear PolygonArea, allowing a new polygon to be started.
********************************************************************** / ********************************************************************** /
void Clear() throw() { void Clear() {
_num = 0; _num = 0;
_crossings = 0; _crossings = 0;
_areasum = 0; _areasum = 0;
_perimetersum = 0; _perimetersum = 0;
_lat0 = _lon0 = _lat1 = _lon1 = Math::NaN<real>(); _lat0 = _lon0 = _lat1 = _lon1 = Math::NaN<real>();
} }
/** /**
* Add a point to the polygon or polyline. * Add a point to the polygon or polyline.
* *
* @param[in] lat the latitude of the point (degrees). * @param[in] lat the latitude of the point (degrees).
* @param[in] lon the longitude of the point (degrees). * @param[in] lon the longitude of the point (degrees).
* *
* \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
* lon should be in the range [&minus;540&deg;, 540&deg;). * lon should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void AddPoint(real lat, real lon) throw(); void AddPoint(real lat, real lon);
/** /**
* Add an edge to the polygon or polyline. * Add an edge to the polygon or polyline.
* *
* @param[in] azi azimuth at current point (degrees). * @param[in] azi azimuth at current point (degrees).
* @param[in] s distance from current point to next point (meters). * @param[in] s distance from current point to next point (meters).
* *
* \e azi should be in the range [&minus;540&deg;, 540&deg;). This doe s * \e azi should be in the range [&minus;540&deg;, 540&deg;). This doe s
* nothing if no points have been added yet. Use PolygonArea::CurrentP oint * nothing if no points have been added yet. Use PolygonArea::CurrentP oint
* to determine the position of the new vertex. * to determine the position of the new vertex.
********************************************************************** / ********************************************************************** /
void AddEdge(real azi, real s) throw(); void AddEdge(real azi, real s);
/** /**
* Return the results so far. * Return the results so far.
* *
* @param[in] reverse if true then clockwise (instead of counter-clockw ise) * @param[in] reverse if true then clockwise (instead of counter-clockw ise)
* traversal counts as a positive area. * traversal counts as a positive area.
* @param[in] sign if true then return a signed result for the area if * @param[in] sign if true then return a signed result for the area if
* the polygon is traversed in the "wrong" direction instead of retur ning * the polygon is traversed in the "wrong" direction instead of retur ning
* the area for the rest of the earth. * the area for the rest of the earth.
* @param[out] perimeter the perimeter of the polygon or length of the * @param[out] perimeter the perimeter of the polygon or length of the
* polyline (meters). * polyline (meters).
* @param[out] area the area of the polygon (meters<sup>2</sup>); only set * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
* if \e polyline is false in the constructor. * if \e polyline is false in the constructor.
* @return the number of points. * @return the number of points.
********************************************************************** / ********************************************************************** /
unsigned Compute(bool reverse, bool sign, unsigned Compute(bool reverse, bool sign,
real& perimeter, real& area) const throw(); real& perimeter, real& area) const;
/** /**
* Return the results assuming a tentative final test point is added; * Return the results assuming a tentative final test point is added;
* however, the data for the test point is not saved. This lets you re port * however, the data for the test point is not saved. This lets you re port
* a running result for the perimeter and area as the user moves the mo use * a running result for the perimeter and area as the user moves the mo use
* cursor. Ordinary floating point arithmetic is used to accumulate th e * cursor. Ordinary floating point arithmetic is used to accumulate th e
* data for the test point; thus the area and perimeter returned are le ss * data for the test point; thus the area and perimeter returned are le ss
* accurate than if PolygonArea::AddPoint and PolygonArea::Compute are * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are
* used. * used.
* *
skipping to change at line 174 skipping to change at line 174
* of the polyline (meters). * of the polyline (meters).
* @param[out] area the approximate area of the polygon * @param[out] area the approximate area of the polygon
* (meters<sup>2</sup>); only set if polyline is false in the * (meters<sup>2</sup>); only set if polyline is false in the
* constructor. * constructor.
* @return the number of points. * @return the number of points.
* *
* \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
* lon should be in the range [&minus;540&deg;, 540&deg;). * lon should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
unsigned TestPoint(real lat, real lon, bool reverse, bool sign, unsigned TestPoint(real lat, real lon, bool reverse, bool sign,
real& perimeter, real& area) const throw(); real& perimeter, real& area) const;
/** /**
* Return the results assuming a tentative final test point is added vi a an * Return the results assuming a tentative final test point is added vi a an
* azimuth and distance; however, the data for the test point is not sa ved. * azimuth and distance; however, the data for the test point is not sa ved.
* This lets you report a running result for the perimeter and area as the * This lets you report a running result for the perimeter and area as the
* user moves the mouse cursor. Ordinary floating point arithmetic is used * user moves the mouse cursor. Ordinary floating point arithmetic is used
* to accumulate the data for the test point; thus the area and perimet er * to accumulate the data for the test point; thus the area and perimet er
* returned are less accurate than if PolygonArea::AddEdge and * returned are less accurate than if PolygonArea::AddEdge and
* PolygonArea::Compute are used. * PolygonArea::Compute are used.
* *
skipping to change at line 202 skipping to change at line 202
* @param[out] perimeter the approximate perimeter of the polygon or le ngth * @param[out] perimeter the approximate perimeter of the polygon or le ngth
* of the polyline (meters). * of the polyline (meters).
* @param[out] area the approximate area of the polygon * @param[out] area the approximate area of the polygon
* (meters<sup>2</sup>); only set if polyline is false in the * (meters<sup>2</sup>); only set if polyline is false in the
* constructor. * constructor.
* @return the number of points. * @return the number of points.
* *
* \e azi should be in the range [&minus;540&deg;, 540&deg;). * \e azi should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
unsigned TestEdge(real azi, real s, bool reverse, bool sign, unsigned TestEdge(real azi, real s, bool reverse, bool sign,
real& perimeter, real& area) const throw(); real& perimeter, real& area) const;
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* The old name for PolygonArea::TestPoint. * The old name for PolygonArea::TestPoint.
********************************************************************** / ********************************************************************** /
unsigned TestCompute(real lat, real lon, bool reverse, bool sign, unsigned TestCompute(real lat, real lon, bool reverse, bool sign,
real& perimeter, real& area) const throw() { real& perimeter, real& area) const {
return TestPoint(lat, lon, reverse, sign, perimeter, area); return TestPoint(lat, lon, reverse, sign, perimeter, area);
} }
/// \endcond /// \endcond
/** \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 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 _earth.MajorRadius(); } Math::real MajorRadius() const { return _earth.MajorRadius(); }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value * @return \e f the flattening of the ellipsoid. This is the value
* inherited from the Geodesic object used in the constructor. * inherited from the Geodesic object used in the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _earth.Flattening(); } Math::real Flattening() const { return _earth.Flattening(); }
/** /**
* Report the previous vertex added to the polygon or polyline. * Report the previous vertex added to the polygon or polyline.
* *
* @param[out] lat the latitude of the point (degrees). * @param[out] lat the latitude of the point (degrees).
* @param[out] lon the longitude of the point (degrees). * @param[out] lon the longitude of the point (degrees).
* *
* If no points have been added, then NaNs are returned. Otherwise, \e lon * If no points have been added, then NaNs are returned. Otherwise, \e lon
* will be in the range [&minus;180&deg;, 180&deg;). * will be in the range [&minus;180&deg;, 180&deg;).
********************************************************************** / ********************************************************************** /
void CurrentPoint(real& lat, real& lon) const throw() void CurrentPoint(real& lat, real& lon) const
{ lat = _lat1; lon = _lon1; } { lat = _lat1; lon = _lon1; }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_POLYGONAREA_HPP #endif // GEOGRAPHICLIB_POLYGONAREA_HPP
 End of changes. 12 change blocks. 
12 lines changed or deleted 12 lines changed or added


 SphericalEngine.hpp   SphericalEngine.hpp 
skipping to change at line 168 skipping to change at line 168
if (!(_Nx >= -1)) if (!(_Nx >= -1))
throw GeographicErr("Bad indices for coeff"); throw GeographicErr("Bad indices for coeff");
if (!(index(_nmx, _mmx) < int(C.size()) && if (!(index(_nmx, _mmx) < int(C.size()) &&
index(_nmx, _mmx) < int(S.size()) + (_Nx + 1))) index(_nmx, _mmx) < int(S.size()) + (_Nx + 1)))
throw GeographicErr("Arrays too small in coeff"); throw GeographicErr("Arrays too small in coeff");
SphericalEngine::RootTable(_nmx); SphericalEngine::RootTable(_nmx);
} }
/** /**
* @return \e N the degree giving storage layout for \e C and \e S. * @return \e N the degree giving storage layout for \e C and \e S.
******************************************************************** **/ ******************************************************************** **/
inline int N() const throw() { return _Nx; } inline int N() const { return _Nx; }
/** /**
* @return \e nmx the maximum degree to be used. * @return \e nmx the maximum degree to be used.
******************************************************************** **/ ******************************************************************** **/
inline int nmx() const throw() { return _nmx; } inline int nmx() const { return _nmx; }
/** /**
* @return \e mmx the maximum order to be used. * @return \e mmx the maximum order to be used.
******************************************************************** **/ ******************************************************************** **/
inline int mmx() const throw() { return _mmx; } inline int mmx() const { return _mmx; }
/** /**
* The one-dimensional index into \e C and \e S. * The one-dimensional index into \e C and \e S.
* *
* @param[in] n the degree. * @param[in] n the degree.
* @param[in] m the order. * @param[in] m the order.
* @return the one-dimensional index. * @return the one-dimensional index.
******************************************************************** **/ ******************************************************************** **/
inline int index(int n, int m) const throw() inline int index(int n, int m) const
{ return m * _Nx - m * (m - 1) / 2 + n; } { return m * _Nx - m * (m - 1) / 2 + n; }
/** /**
* An element of \e C. * An element of \e C.
* *
* @param[in] k the one-dimensional index. * @param[in] k the one-dimensional index.
* @return the value of the \e C coefficient. * @return the value of the \e C coefficient.
******************************************************************** **/ ******************************************************************** **/
inline Math::real Cv(int k) const { return *(_Cnm + k); } inline Math::real Cv(int k) const { return *(_Cnm + k); }
/** /**
* An element of \e S. * An element of \e S.
skipping to change at line 233 skipping to change at line 233
{ return m > _mmx || n > _nmx ? 0 : *(_Snm + (k - (_Nx + 1))) * f; } { return m > _mmx || n > _nmx ? 0 : *(_Snm + (k - (_Nx + 1))) * f; }
/** /**
* The size of the coefficient vector for the cosine terms. * The size of the coefficient vector for the cosine terms.
* *
* @param[in] N the maximum degree. * @param[in] N the maximum degree.
* @param[in] M the maximum order. * @param[in] M the maximum order.
* @return the size of the vector of cosine terms as stored in column * @return the size of the vector of cosine terms as stored in column
* major order. * major order.
******************************************************************** **/ ******************************************************************** **/
static inline int Csize(int N, int M) throw() static inline int Csize(int N, int M)
{ return (M + 1) * (2 * N - M + 2) / 2; } { return (M + 1) * (2 * N - M + 2) / 2; }
/** /**
* The size of the coefficient vector for the sine terms. * The size of the coefficient vector for the sine terms.
* *
* @param[in] N the maximum degree. * @param[in] N the maximum degree.
* @param[in] M the maximum order. * @param[in] M the maximum order.
* @return the size of the vector of cosine terms as stored in column * @return the size of the vector of cosine terms as stored in column
* major order. * major order.
******************************************************************** **/ ******************************************************************** **/
static inline int Ssize(int N, int M) throw () static inline int Ssize(int N, int M)
{ return Csize(N, M) - (N + 1); } { return Csize(N, M) - (N + 1); }
/** /**
* Load coefficients from a binary stream. * Load coefficients from a binary stream.
* *
* @param[in] stream the input stream. * @param[in] stream the input stream.
* @param[out] N The maximum degree of the coefficients. * @param[out] N The maximum degree of the coefficients.
* @param[out] M The maximum order of the coefficients. * @param[out] M The maximum order of the coefficients.
* @param[out] C The vector of cosine coefficients. * @param[out] C The vector of cosine coefficients.
* @param[out] S The vector of sine coefficients. * @param[out] S The vector of sine coefficients.
skipping to change at line 304 skipping to change at line 304
* coefficients. The parameters \e gradp, \e norm, and \e L are templa te * coefficients. The parameters \e gradp, \e norm, and \e L are templa te
* parameters, to allow more optimization to be done at compile time. * parameters, to allow more optimization to be done at compile time.
* *
* Clenshaw summation is used which permits the evaluation of the sum * Clenshaw summation is used which permits the evaluation of the sum
* without the need to allocate temporary arrays. Thus this function n ever * without the need to allocate temporary arrays. Thus this function n ever
* throws an exception. * throws an exception.
********************************************************************** / ********************************************************************** /
template<bool gradp, normalization norm, int L> template<bool gradp, normalization norm, int L>
static Math::real Value(const coeff c[], const real f[], static Math::real Value(const coeff c[], const real f[],
real x, real y, real z, real a, real x, real y, real z, real a,
real& gradx, real& grady, real& gradz) throw( ); real& gradx, real& grady, real& gradz);
/** /**
* Create a CircularEngine object * Create a CircularEngine object
* *
* @tparam gradp should the gradient be calculated. * @tparam gradp should the gradient be calculated.
* @tparam norm the normalization for the associated Legendre polynomia ls. * @tparam norm the normalization for the associated Legendre polynomia ls.
* @tparam L the number of terms in the coefficients. * @tparam L the number of terms in the coefficients.
* @param[in] c an array of coeff objects. * @param[in] c an array of coeff objects.
* @param[in] f array of coefficient multipliers. f[0] should be 1. * @param[in] f array of coefficient multipliers. f[0] should be 1.
* @param[in] p the radius of the circle = sqrt(<i>x</i><sup>2</sup> + * @param[in] p the radius of the circle = sqrt(<i>x</i><sup>2</sup> +
 End of changes. 7 change blocks. 
7 lines changed or deleted 7 lines changed or added


 SphericalHarmonic.hpp   SphericalHarmonic.hpp 
skipping to change at line 221 skipping to change at line 221
* Compute the spherical harmonic sum. * Compute the spherical harmonic sum.
* *
* @param[in] x cartesian coordinate. * @param[in] x cartesian coordinate.
* @param[in] y cartesian coordinate. * @param[in] y cartesian coordinate.
* @param[in] z cartesian coordinate. * @param[in] z cartesian coordinate.
* @return \e V the spherical harmonic sum. * @return \e V the spherical harmonic sum.
* *
* This routine requires constant memory and thus never throws an * This routine requires constant memory and thus never throws an
* exception. * exception.
********************************************************************** / ********************************************************************** /
Math::real operator()(real x, real y, real z) const throw() { Math::real operator()(real x, real y, real z) const {
real f[] = {1}; real f[] = {1};
real v = 0; real v = 0;
real dummy; real dummy;
switch (_norm) { switch (_norm) {
case FULL: case FULL:
v = SphericalEngine::Value<false, SphericalEngine::FULL, 1> v = SphericalEngine::Value<false, SphericalEngine::FULL, 1>
(_c, f, x, y, z, _a, dummy, dummy, dummy); (_c, f, x, y, z, _a, dummy, dummy, dummy);
break; break;
case SCHMIDT: case SCHMIDT:
v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 1> v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 1>
skipping to change at line 255 skipping to change at line 255
* @param[out] grady \e y component of the gradient * @param[out] grady \e y component of the gradient
* @param[out] gradz \e z component of the gradient * @param[out] gradz \e z component of the gradient
* @return \e V the spherical harmonic sum. * @return \e V the spherical harmonic sum.
* *
* This is the same as the previous function, except that the component s of * This is the same as the previous function, except that the component s of
* the gradients of the sum in the \e x, \e y, and \e z directions are * the gradients of the sum in the \e x, \e y, and \e z directions are
* computed. This routine requires constant memory and thus never thro ws * computed. This routine requires constant memory and thus never thro ws
* an exception. * an exception.
********************************************************************** / ********************************************************************** /
Math::real operator()(real x, real y, real z, Math::real operator()(real x, real y, real z,
real& gradx, real& grady, real& gradz) const thro w() { real& gradx, real& grady, real& gradz) const {
real f[] = {1}; real f[] = {1};
real v = 0; real v = 0;
switch (_norm) { switch (_norm) {
case FULL: case FULL:
v = SphericalEngine::Value<true, SphericalEngine::FULL, 1> v = SphericalEngine::Value<true, SphericalEngine::FULL, 1>
(_c, f, x, y, z, _a, gradx, grady, gradz); (_c, f, x, y, z, _a, gradx, grady, gradz);
break; break;
case SCHMIDT: case SCHMIDT:
v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 1> v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 1>
(_c, f, x, y, z, _a, gradx, grady, gradz); (_c, f, x, y, z, _a, gradx, grady, gradz);
skipping to change at line 344 skipping to change at line 344
(_c, f, p, z, _a) : (_c, f, p, z, _a) :
SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 1> SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 1>
(_c, f, p, z, _a); (_c, f, p, z, _a);
break; break;
} }
} }
/** /**
* @return the zeroth SphericalEngine::coeff object. * @return the zeroth SphericalEngine::coeff object.
********************************************************************** / ********************************************************************** /
const SphericalEngine::coeff& Coefficients() const throw() const SphericalEngine::coeff& Coefficients() const
{ return _c[0]; } { return _c[0]; }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_SPHERICALHARMONIC_HPP #endif // GEOGRAPHICLIB_SPHERICALHARMONIC_HPP
 End of changes. 3 change blocks. 
3 lines changed or deleted 3 lines changed or added


 SphericalHarmonic1.hpp   SphericalHarmonic1.hpp 
skipping to change at line 173 skipping to change at line 173
* *
* @param[in] tau multiplier for correction coefficients \e C' and \e S '. * @param[in] tau multiplier for correction coefficients \e C' and \e S '.
* @param[in] x cartesian coordinate. * @param[in] x cartesian coordinate.
* @param[in] y cartesian coordinate. * @param[in] y cartesian coordinate.
* @param[in] z cartesian coordinate. * @param[in] z cartesian coordinate.
* @return \e V the spherical harmonic sum. * @return \e V the spherical harmonic sum.
* *
* This routine requires constant memory and thus never throws * This routine requires constant memory and thus never throws
* an exception. * an exception.
********************************************************************** / ********************************************************************** /
Math::real operator()(real tau, real x, real y, real z) const throw() { Math::real operator()(real tau, real x, real y, real z) const {
real f[] = {1, tau}; real f[] = {1, tau};
real v = 0; real v = 0;
real dummy; real dummy;
switch (_norm) { switch (_norm) {
case FULL: case FULL:
v = SphericalEngine::Value<false, SphericalEngine::FULL, 2> v = SphericalEngine::Value<false, SphericalEngine::FULL, 2>
(_c, f, x, y, z, _a, dummy, dummy, dummy); (_c, f, x, y, z, _a, dummy, dummy, dummy);
break; break;
case SCHMIDT: case SCHMIDT:
v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 2> v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 2>
skipping to change at line 209 skipping to change at line 209
* @param[out] grady \e y component of the gradient * @param[out] grady \e y component of the gradient
* @param[out] gradz \e z component of the gradient * @param[out] gradz \e z component of the gradient
* @return \e V the spherical harmonic sum. * @return \e V the spherical harmonic sum.
* *
* This is the same as the previous function, except that the component s of * This is the same as the previous function, except that the component s of
* the gradients of the sum in the \e x, \e y, and \e z directions are * the gradients of the sum in the \e x, \e y, and \e z directions are
* computed. This routine requires constant memory and thus never thro ws * computed. This routine requires constant memory and thus never thro ws
* an exception. * an exception.
********************************************************************** / ********************************************************************** /
Math::real operator()(real tau, real x, real y, real z, Math::real operator()(real tau, real x, real y, real z,
real& gradx, real& grady, real& gradz) const thro w() { real& gradx, real& grady, real& gradz) const {
real f[] = {1, tau}; real f[] = {1, tau};
real v = 0; real v = 0;
switch (_norm) { switch (_norm) {
case FULL: case FULL:
v = SphericalEngine::Value<true, SphericalEngine::FULL, 2> v = SphericalEngine::Value<true, SphericalEngine::FULL, 2>
(_c, f, x, y, z, _a, gradx, grady, gradz); (_c, f, x, y, z, _a, gradx, grady, gradz);
break; break;
case SCHMIDT: case SCHMIDT:
v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 2> v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 2>
(_c, f, x, y, z, _a, gradx, grady, gradz); (_c, f, x, y, z, _a, gradx, grady, gradz);
skipping to change at line 272 skipping to change at line 272
(_c, f, p, z, _a) : (_c, f, p, z, _a) :
SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 2> SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 2>
(_c, f, p, z, _a); (_c, f, p, z, _a);
break; break;
} }
} }
/** /**
* @return the zeroth SphericalEngine::coeff object. * @return the zeroth SphericalEngine::coeff object.
********************************************************************** / ********************************************************************** /
const SphericalEngine::coeff& Coefficients() const throw() const SphericalEngine::coeff& Coefficients() const
{ return _c[0]; } { return _c[0]; }
/** /**
* @return the first SphericalEngine::coeff object. * @return the first SphericalEngine::coeff object.
********************************************************************** / ********************************************************************** /
const SphericalEngine::coeff& Coefficients1() const throw() const SphericalEngine::coeff& Coefficients1() const
{ return _c[1]; } { return _c[1]; }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP #endif // GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP
 End of changes. 4 change blocks. 
4 lines changed or deleted 4 lines changed or added


 SphericalHarmonic2.hpp   SphericalHarmonic2.hpp 
skipping to change at line 198 skipping to change at line 198
* @param[in] tau2 multiplier for correction coefficients \e C'' and \e S''. * @param[in] tau2 multiplier for correction coefficients \e C'' and \e S''.
* @param[in] x cartesian coordinate. * @param[in] x cartesian coordinate.
* @param[in] y cartesian coordinate. * @param[in] y cartesian coordinate.
* @param[in] z cartesian coordinate. * @param[in] z cartesian coordinate.
* @return \e V the spherical harmonic sum. * @return \e V the spherical harmonic sum.
* *
* This routine requires constant memory and thus never throws an * This routine requires constant memory and thus never throws an
* exception. * exception.
********************************************************************** / ********************************************************************** /
Math::real operator()(real tau1, real tau2, real x, real y, real z) Math::real operator()(real tau1, real tau2, real x, real y, real z)
const throw() { const {
real f[] = {1, tau1, tau2}; real f[] = {1, tau1, tau2};
real v = 0; real v = 0;
real dummy; real dummy;
switch (_norm) { switch (_norm) {
case FULL: case FULL:
v = SphericalEngine::Value<false, SphericalEngine::FULL, 3> v = SphericalEngine::Value<false, SphericalEngine::FULL, 3>
(_c, f, x, y, z, _a, dummy, dummy, dummy); (_c, f, x, y, z, _a, dummy, dummy, dummy);
break; break;
case SCHMIDT: case SCHMIDT:
v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 3> v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 3>
skipping to change at line 235 skipping to change at line 235
* @param[out] grady \e y component of the gradient * @param[out] grady \e y component of the gradient
* @param[out] gradz \e z component of the gradient * @param[out] gradz \e z component of the gradient
* @return \e V the spherical harmonic sum. * @return \e V the spherical harmonic sum.
* *
* This is the same as the previous function, except that the component s of * This is the same as the previous function, except that the component s of
* the gradients of the sum in the \e x, \e y, and \e z directions are * the gradients of the sum in the \e x, \e y, and \e z directions are
* computed. This routine requires constant memory and thus never thro ws * computed. This routine requires constant memory and thus never thro ws
* an exception. * an exception.
********************************************************************** / ********************************************************************** /
Math::real operator()(real tau1, real tau2, real x, real y, real z, Math::real operator()(real tau1, real tau2, real x, real y, real z,
real& gradx, real& grady, real& gradz) const thro w() { real& gradx, real& grady, real& gradz) const {
real f[] = {1, tau1, tau2}; real f[] = {1, tau1, tau2};
real v = 0; real v = 0;
switch (_norm) { switch (_norm) {
case FULL: case FULL:
v = SphericalEngine::Value<true, SphericalEngine::FULL, 3> v = SphericalEngine::Value<true, SphericalEngine::FULL, 3>
(_c, f, x, y, z, _a, gradx, grady, gradz); (_c, f, x, y, z, _a, gradx, grady, gradz);
break; break;
case SCHMIDT: case SCHMIDT:
v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 3> v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 3>
(_c, f, x, y, z, _a, gradx, grady, gradz); (_c, f, x, y, z, _a, gradx, grady, gradz);
skipping to change at line 300 skipping to change at line 300
(_c, f, p, z, _a) : (_c, f, p, z, _a) :
SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 3> SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 3>
(_c, f, p, z, _a); (_c, f, p, z, _a);
break; break;
} }
} }
/** /**
* @return the zeroth SphericalEngine::coeff object. * @return the zeroth SphericalEngine::coeff object.
********************************************************************** / ********************************************************************** /
const SphericalEngine::coeff& Coefficients() const throw() const SphericalEngine::coeff& Coefficients() const
{ return _c[0]; } { return _c[0]; }
/** /**
* @return the first SphericalEngine::coeff object. * @return the first SphericalEngine::coeff object.
********************************************************************** / ********************************************************************** /
const SphericalEngine::coeff& Coefficients1() const throw() const SphericalEngine::coeff& Coefficients1() const
{ return _c[1]; } { return _c[1]; }
/** /**
* @return the second SphericalEngine::coeff object. * @return the second SphericalEngine::coeff object.
********************************************************************** / ********************************************************************** /
const SphericalEngine::coeff& Coefficients2() const throw() const SphericalEngine::coeff& Coefficients2() const
{ return _c[2]; } { return _c[2]; }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP #endif // GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP
 End of changes. 5 change blocks. 
5 lines changed or deleted 5 lines changed or added


 TransverseMercator.hpp   TransverseMercator.hpp 
skipping to change at line 90 skipping to change at line 90
private: private:
typedef Math::real real; typedef Math::real real;
static const int maxpow_ = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER; static const int maxpow_ = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER;
static const real tol_; static const real tol_;
static const real overflow_; static const real overflow_;
static const int numit_ = 5; static const int numit_ = 5;
real _a, _f, _k0, _e2, _e, _e2m, _c, _n; real _a, _f, _k0, _e2, _e, _e2m, _c, _n;
// _alp[0] and _bet[0] unused // _alp[0] and _bet[0] unused
real _a1, _b1, _alp[maxpow_ + 1], _bet[maxpow_ + 1]; real _a1, _b1, _alp[maxpow_ + 1], _bet[maxpow_ + 1];
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) throw() { static inline real tanx(real x) {
real t = std::tan(x); real t = std::tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN() // Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl ow_); return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl ow_);
} }
// Return e * atanh(e * x) for f >= 0, else return // Return e * atanh(e * x) for f >= 0, else return
// - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0 // - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
inline real eatanhe(real x) const throw() inline real eatanhe(real x) const
{ return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); } { return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * std::atan(_e * x); }
real taupf(real tau) const throw(); real taupf(real tau) const;
real tauf(real taup) const throw(); real tauf(real taup) const;
friend class Ellipsoid; // For access to taupf, tauf. friend class Ellipsoid; // For access to taupf, tauf.
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] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re. * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphe re.
* Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flatten ing
skipping to change at line 134 skipping to change at line 134
* @param[out] x easting of point (meters). * @param[out] x easting of point (meters).
* @param[out] y northing of point (meters). * @param[out] y northing of point (meters).
* @param[out] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* No false easting or northing is added. \e lat should be in the range * No false easting or northing is added. \e lat should be in the range
* [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
* range [&minus;540&deg;, 540&deg;). * range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y, real& gamma, real& k) const throw(); real& x, real& y, real& gamma, real& k) const;
/** /**
* Reverse projection, from transverse Mercator to geographic. * Reverse projection, from transverse Mercator to geographic.
* *
* @param[in] lon0 central meridian of the projection (degrees). * @param[in] lon0 central meridian of the projection (degrees).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* No false easting or northing is added. \e lon0 should be in the ran ge * No false easting or northing is added. \e lon0 should be in the ran ge
* [&minus;540&deg;, 540&deg;). The value of \e lon returned is in * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
* the range [&minus;180&deg;, 180&deg;). * the range [&minus;180&deg;, 180&deg;).
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon, real& gamma, real& k) const throw(); real& lat, real& lon, real& gamma, real& k) const;
/** /**
* TransverseMercator::Forward without returning the convergence and sc ale. * TransverseMercator::Forward without returning the convergence and sc ale.
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real gamma, k; real gamma, k;
Forward(lon0, lat, lon, x, y, gamma, k); Forward(lon0, lat, lon, x, y, gamma, k);
} }
/** /**
* TransverseMercator::Reverse without returning the convergence and sc ale. * TransverseMercator::Reverse without returning the convergence and sc ale.
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real gamma, k; real gamma, k;
Reverse(lon0, x, y, lat, lon, gamma, k); Reverse(lon0, x, y, lat, lon, gamma, k);
} }
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value use d in * @return \e f the flattening of the ellipsoid. This is the value use d in
* the constructor. * the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* @return \e k0 central scale for the projection. This is the value o f \e * @return \e k0 central scale for the projection. This is the value o f \e
* k0 used in the constructor and is the scale on the central meridia n. * k0 used in the constructor and is the scale on the central meridia n.
********************************************************************** / ********************************************************************** /
Math::real CentralScale() const throw() { return _k0; } Math::real CentralScale() const { return _k0; }
///@} ///@}
/** /**
* A global instantiation of TransverseMercator with the WGS84 ellipsoi d * A global instantiation of TransverseMercator with the WGS84 ellipsoi d
* and the UTM scale factor. However, unlike UTM, no false easting or * and the UTM scale factor. However, unlike UTM, no false easting or
* northing is added. * northing is added.
********************************************************************** / ********************************************************************** /
static const TransverseMercator UTM; static const TransverseMercator UTM;
}; };
 End of changes. 11 change blocks. 
12 lines changed or deleted 12 lines changed or added


 TransverseMercatorExact.hpp   TransverseMercatorExact.hpp 
skipping to change at line 92 skipping to change at line 92
static const real tol_; static const real tol_;
static const real tol1_; static const real tol1_;
static const real tol2_; static const real tol2_;
static const real taytol_; static const real taytol_;
static const real overflow_; static const real overflow_;
static const int numit_ = 10; static const int numit_ = 10;
real _a, _f, _k0, _mu, _mv, _e; real _a, _f, _k0, _mu, _mv, _e;
bool _extendp; bool _extendp;
EllipticFunction _Eu, _Ev; EllipticFunction _Eu, _Ev;
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right // tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) throw() { static inline real tanx(real x) {
real t = std::tan(x); real t = std::tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN() // Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl ow_); return x >= 0 ? (!(t < 0) ? t : overflow_) : (!(t >= 0) ? t : -overfl ow_);
} }
real taup(real tau) const throw(); real taup(real tau) const;
real taupinv(real taup) const throw(); real taupinv(real taup) const;
void zeta(real u, real snu, real cnu, real dnu, void zeta(real u, real snu, real cnu, real dnu,
real v, real snv, real cnv, real dnv, real v, real snv, real cnv, real dnv,
real& taup, real& lam) const throw(); real& taup, real& lam) const;
void dwdzeta(real u, real snu, real cnu, real dnu, void dwdzeta(real u, real snu, real cnu, real dnu,
real v, real snv, real cnv, real dnv, real v, real snv, real cnv, real dnv,
real& du, real& dv) const throw(); real& du, real& dv) const;
bool zetainv0(real psi, real lam, real& u, real& v) const throw(); bool zetainv0(real psi, real lam, real& u, real& v) const;
void zetainv(real taup, real lam, real& u, real& v) const throw(); void zetainv(real taup, real lam, real& u, real& v) const;
void sigma(real u, real snu, real cnu, real dnu, void sigma(real u, real snu, real cnu, real dnu,
real v, real snv, real cnv, real dnv, real v, real snv, real cnv, real dnv,
real& xi, real& eta) const throw(); real& xi, real& eta) const;
void dwdsigma(real u, real snu, real cnu, real dnu, void dwdsigma(real u, real snu, real cnu, real dnu,
real v, real snv, real cnv, real dnv, real v, real snv, real cnv, real dnv,
real& du, real& dv) const throw(); real& du, real& dv) const;
bool sigmainv0(real xi, real eta, real& u, real& v) const throw(); bool sigmainv0(real xi, real eta, real& u, real& v) const;
void sigmainv(real xi, real eta, real& u, real& v) const throw(); void sigmainv(real xi, real eta, real& u, real& v) const;
void Scale(real tau, real lam, void Scale(real tau, real lam,
real snu, real cnu, real dnu, real snu, real cnu, real dnu,
real snv, real cnv, real dnv, real snv, real cnv, real dnv,
real& gamma, real& k) const throw(); real& gamma, real& k) const;
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] f flattening of ellipsoid. If \e f > 1, set flattening * @param[in] f flattening of ellipsoid. If \e f > 1, set flattening
* to 1/\e f. * to 1/\e f.
* @param[in] k0 central scale factor. * @param[in] k0 central scale factor.
skipping to change at line 198 skipping to change at line 198
* @param[out] x easting of point (meters). * @param[out] x easting of point (meters).
* @param[out] y northing of point (meters). * @param[out] y northing of point (meters).
* @param[out] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* No false easting or northing is added. \e lat should be in the range * No false easting or northing is added. \e lat should be in the range
* [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
* range [&minus;540&deg;, 540&deg;). * range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y, real& gamma, real& k) const throw(); real& x, real& y, real& gamma, real& k) const;
/** /**
* Reverse projection, from transverse Mercator to geographic. * Reverse projection, from transverse Mercator to geographic.
* *
* @param[in] lon0 central meridian of the projection (degrees). * @param[in] lon0 central meridian of the projection (degrees).
* @param[in] x easting of point (meters). * @param[in] x easting of point (meters).
* @param[in] y northing of point (meters). * @param[in] y northing of point (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] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* No false easting or northing is added. \e lon0 should be in the ran ge * No false easting or northing is added. \e lon0 should be in the ran ge
* [&minus;540&deg;, 540&deg;). The value of \e lon returned is in * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
* the range [&minus;180&deg;, 180&deg;). * the range [&minus;180&deg;, 180&deg;).
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon, real& gamma, real& k) const throw(); real& lat, real& lon, real& gamma, real& k) const;
/** /**
* TransverseMercatorExact::Forward without returning the convergence a nd * TransverseMercatorExact::Forward without returning the convergence a nd
* scale. * scale.
********************************************************************** / ********************************************************************** /
void Forward(real lon0, real lat, real lon, void Forward(real lon0, real lat, real lon,
real& x, real& y) const throw() { real& x, real& y) const {
real gamma, k; real gamma, k;
Forward(lon0, lat, lon, x, y, gamma, k); Forward(lon0, lat, lon, x, y, gamma, k);
} }
/** /**
* TransverseMercatorExact::Reverse without returning the convergence a nd * TransverseMercatorExact::Reverse without returning the convergence a nd
* scale. * scale.
********************************************************************** / ********************************************************************** /
void Reverse(real lon0, real x, real y, void Reverse(real lon0, real x, real y,
real& lat, real& lon) const throw() { real& lat, real& lon) const {
real gamma, k; real gamma, k;
Reverse(lon0, x, y, lat, lon, gamma, k); Reverse(lon0, x, y, lat, lon, gamma, k);
} }
/** \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 { return _a; }
/** /**
* @return \e f the flattening of the ellipsoid. This is the value use d in * @return \e f the flattening of the ellipsoid. This is the value use d in
* the constructor. * the constructor.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() { return _f; } Math::real Flattening() const { return _f; }
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the ellipsoid. * @return \e r the inverse flattening of the ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real InverseFlattening() const throw() { return 1/_f; } Math::real InverseFlattening() const { return 1/_f; }
/// \endcond /// \endcond
/** /**
* @return \e k0 central scale for the projection. This is the value o f \e * @return \e k0 central scale for the projection. This is the value o f \e
* k0 used in the constructor and is the scale on the central meridia n. * k0 used in the constructor and is the scale on the central meridia n.
********************************************************************** / ********************************************************************** /
Math::real CentralScale() const throw() { return _k0; } Math::real CentralScale() const { return _k0; }
///@} ///@}
/** /**
* A global instantiation of TransverseMercatorExact with the WGS84 * A global instantiation of TransverseMercatorExact with the WGS84
* ellipsoid and the UTM scale factor. However, unlike UTM, no false * ellipsoid and the UTM scale factor. However, unlike UTM, no false
* easting or northing is added. * easting or northing is added.
********************************************************************** / ********************************************************************** /
static const TransverseMercatorExact UTM; static const TransverseMercatorExact UTM;
}; };
 End of changes. 17 change blocks. 
20 lines changed or deleted 20 lines changed or added


 UTMUPS.hpp   UTMUPS.hpp 
skipping to change at line 32 skipping to change at line 32
* <a href="http://earth-info.nga.mil/GandG/publications/tm8358.2/TM835 8_2.pdf"> * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.2/TM835 8_2.pdf">
* The Universal Grids: Universal Transverse Mercator (UTM) and Univers al * The Universal Grids: Universal Transverse Mercator (UTM) and Univers al
* Polar Stereographic (UPS)</a>, Defense Mapping Agency, Technical Man ual * Polar Stereographic (UPS)</a>, Defense Mapping Agency, Technical Man ual
* TM8358.2 (1989). * TM8358.2 (1989).
* . * .
* Section 2-3 defines UTM and section 3-2.4 defines UPS. This document also * Section 2-3 defines UTM and section 3-2.4 defines UPS. This document also
* includes approximate algorithms for the computation of the underlying * includes approximate algorithms for the computation of the underlying
* transverse Mercator and polar stereographic projections. Here we * transverse Mercator and polar stereographic projections. Here we
* substitute much more accurate algorithms given by * substitute much more accurate algorithms given by
* GeographicLib:TransverseMercator and GeographicLib:PolarStereographic. * GeographicLib:TransverseMercator and GeographicLib:PolarStereographic.
* These are the algorithms recommended by the NGA document
* - <a href="https://nsgreg.nga.mil/doc/view?i=4056"> The Universal Grid
s
* and the Transverse Mercator and Polar Stereographic Map Projections<
/a>,
* NGA.SIG.0012_2.0.0_UTMUPS (2014).
* *
* In this implementation, the conversions are closed, i.e., output from * In this implementation, the conversions are closed, i.e., output from
* Forward is legal input for Reverse and vice versa. The error is about 5nm * Forward is legal input for Reverse and vice versa. The error is about 5nm
* in each direction. However, the conversion from legal UTM/UPS coordin ates * in each direction. However, the conversion from legal UTM/UPS coordin ates
* to geographic coordinates and back might throw an error if the initial * to geographic coordinates and back might throw an error if the initial
* point is within 5nm of the edge of the allowed range for the UTM/UPS * point is within 5nm of the edge of the allowed range for the UTM/UPS
* coordinates. * coordinates.
* *
* The simplest way to guarantee the closed property is to define allowed * The simplest way to guarantee the closed property is to define allowed
* ranges for the eastings and northings for UTM and UPS coordinates. Th e * ranges for the eastings and northings for UTM and UPS coordinates. Th e
skipping to change at line 58 skipping to change at line 62
* generous overlap between UTM and UPS and between UTM zones. * generous overlap between UTM and UPS and between UTM zones.
* *
* The <a href="http://www.nga.mil">NGA</a> software package * The <a href="http://www.nga.mil">NGA</a> software package
* <a href="http://earth-info.nga.mil/GandG/geotrans/index.html">geotrans </a> * <a href="http://earth-info.nga.mil/GandG/geotrans/index.html">geotrans </a>
* also provides conversions to and from UTM and UPS. Version 2.4.2 (and * also provides conversions to and from UTM and UPS. Version 2.4.2 (and
* earlier) suffers from some drawbacks: * earlier) suffers from some drawbacks:
* - Inconsistent rules are used to determine the whether a particular UT M or * - Inconsistent rules are used to determine the whether a particular UT M or
* UPS coordinate is legal. A more systematic approach is taken here. * UPS coordinate is legal. A more systematic approach is taken here.
* - The underlying projections are not very accurately implemented. * - The underlying projections are not very accurately implemented.
* *
* The GeographicLib::UTMUPS::EncodeZone encodes the UTM zone and hemisph
ere
* to allow UTM/UPS coordinated to be displayed as, for example, "38N 444
500
* 3688500". According to NGA.SIG.0012_2.0.0_UTMUPS the use of "N" to de
note
* "north" in the context is not allowed (since a upper case letter in th
is
* context denotes the MGRS latitude band). Consequently, as of version
* 1.36, EncodeZone uses the lower case letters "n" and "s" to denote the
* hemisphere. In addition EncodeZone accepts an optional final argument
\e
* abbrev, which, if false, results in the hemisphere being spelled out a
s in
* "38north".
*
* Example of use: * Example of use:
* \include example-UTMUPS.cpp * \include example-UTMUPS.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT UTMUPS { class GEOGRAPHICLIB_EXPORT UTMUPS {
private: private:
typedef Math::real real; typedef Math::real real;
static const real falseeasting_[4]; static const real falseeasting_[4];
static const real falsenorthing_[4]; static const real falsenorthing_[4];
static const real mineasting_[4]; static const real mineasting_[4];
static const real maxeasting_[4]; static const real maxeasting_[4];
static const real minnorthing_[4]; static const real minnorthing_[4];
static const real maxnorthing_[4]; static const real maxnorthing_[4];
static const int epsg01N = 32601; // EPSG code for UTM 01N static const int epsg01N = 32601; // EPSG code for UTM 01N
static const int epsg60N = 32660; // EPSG code for UTM 60N static const int epsg60N = 32660; // EPSG code for UTM 60N
static const int epsgN = 32661; // EPSG code for UPS N static const int epsgN = 32661; // EPSG code for UPS N
static const int epsg01S = 32701; // EPSG code for UTM 01S static const int epsg01S = 32701; // EPSG code for UTM 01S
static const int epsg60S = 32760; // EPSG code for UTM 60S static const int epsg60S = 32760; // EPSG code for UTM 60S
static const int epsgS = 32761; // EPSG code for UPS S static const int epsgS = 32761; // EPSG code for UPS S
static real CentralMeridian(int zone) throw() static real CentralMeridian(int zone)
{ return real(6 * zone - 183); } { return real(6 * zone - 183); }
static void CheckLatLon(real lat, real lon); static void CheckLatLon(real lat, real lon);
// Throw an error if easting or northing are outside standard ranges. If // Throw an error if easting or northing are outside standard ranges. If
// throwp = false, return bool instead. // throwp = false, return bool instead.
static bool CheckCoords(bool utmp, bool northp, real x, real y, static bool CheckCoords(bool utmp, bool northp, real x, real y,
bool msgrlimits = false, bool throwp = true); bool msgrlimits = false, bool throwp = true);
UTMUPS(); // Disable constructor UTMUPS(); // Disable constructor
public: public:
skipping to change at line 321 skipping to change at line 335
/** /**
* Decode a UTM/UPS zone string. * Decode a UTM/UPS zone string.
* *
* @param[in] zonestr string representation of zone and hemisphere. * @param[in] zonestr string representation of zone and hemisphere.
* @param[out] zone the UTM zone (zero means UPS). * @param[out] zone the UTM zone (zero means UPS).
* @param[out] northp hemisphere (true means north, false means south). * @param[out] northp hemisphere (true means north, false means south).
* @exception GeographicErr if \e zonestr is malformed. * @exception GeographicErr if \e zonestr is malformed.
* *
* For UTM, \e zonestr has the form of a zone number in the range * For UTM, \e zonestr has the form of a zone number in the range
* [UTMUPS::MINUTMZONE, UTMUPS::MAXUTMZONE] = [1, 60] followed by a * [UTMUPS::MINUTMZONE, UTMUPS::MAXUTMZONE] = [1, 60] followed by a
* hemisphere letter, N or S. For UPS, it consists just of the hemisph * hemisphere letter, n or s (or "north" or "south" spelled out). For
ere UPS,
* letter. The returned value of \e zone is UTMUPS::UPS = 0 for UPS. * it consists just of the hemisphere letter (or the spelled out
Note * hemisphere). The returned value of \e zone is UTMUPS::UPS = 0 for U
* well that "38S" indicates the southern hemisphere of zone 38 and not PS.
* latitude band S, [32, 40]. N, 01S, 2N, 38S are legal. 0N, 001S, 61 * Note well that "38s" indicates the southern hemisphere of zone 38 an
N, d
* 38P are illegal. INV is a special value for which the returned valu * not latitude band S, 32&deg; &le; \e lat &lt; 40&deg;. n, 01s, 2n,
e of 38s,
* \e is UTMUPS::INVALID. * south, 3north are legal. 0n, 001s, +3n, 61n, 38P are illegal. INV
is a
* special value for which the returned value of \e is UTMUPS::INVALID.
********************************************************************** / ********************************************************************** /
static void DecodeZone(const std::string& zonestr, int& zone, bool& nor thp); static void DecodeZone(const std::string& zonestr, int& zone, bool& nor thp);
/** /**
* Encode a UTM/UPS zone string. * Encode a UTM/UPS zone string.
* *
* @param[in] zone the UTM zone (zero means UPS). * @param[in] zone the UTM zone (zero means UPS).
* @param[in] northp hemisphere (true means north, false means south). * @param[in] northp hemisphere (true means north, false means south).
* @param[in] abbrev if true (the default) use abbreviated (n/s) notati
on
* for hemisphere; otherwise spell out the hemisphere (north/south)
* @exception GeographicErr if \e zone is out of range (see below). * @exception GeographicErr if \e zone is out of range (see below).
* @exception std::bad_alloc if memoy for the string can't be allocated . * @exception std::bad_alloc if memoy for the string can't be allocated .
* @return string representation of zone and hemisphere. * @return string representation of zone and hemisphere.
* *
* \e zone must be in the range [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0 , * \e zone must be in the range [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0 ,
* 60] with \e zone = UTMUPS::UPS, 0, indicating UPS (but the resulting * 60] with \e zone = UTMUPS::UPS, 0, indicating UPS (but the resulting
* string does not contain "0"). \e zone may also be UTMUPS::INVALID, in * string does not contain "0"). \e zone may also be UTMUPS::INVALID, in
* which case the returned string is "INV". This reverses * which case the returned string is "inv". This reverses
* UTMUPS::DecodeZone. * UTMUPS::DecodeZone.
********************************************************************** / ********************************************************************** /
static std::string EncodeZone(int zone, bool northp); static std::string EncodeZone(int zone, bool northp, bool abbrev = true );
/** /**
* Decode EPSG. * Decode EPSG.
* *
* @param[in] epsg the EPSG code. * @param[in] epsg the EPSG code.
* @param[out] zone the UTM zone (zero means UPS). * @param[out] zone the UTM zone (zero means UPS).
* @param[out] northp hemisphere (true means north, false means south). * @param[out] northp hemisphere (true means north, false means south).
* *
* EPSG (European Petroleum Survery Group) codes are a way to refer to many * EPSG (European Petroleum Survery Group) codes are a way to refer to many
* different projections. DecodeEPSG decodes those refering to UTM or UPS * different projections. DecodeEPSG decodes those refering to UTM or UPS
* projections for the WGS84 ellipsoid. If the code does not refer to one * projections for the WGS84 ellipsoid. If the code does not refer to one
* of these projections, \e zone is set to UTMUPS::INVALID. See * of these projections, \e zone is set to UTMUPS::INVALID. See
* http://spatialreference.org/ref/epsg/ * http://spatialreference.org/ref/epsg/
********************************************************************** / ********************************************************************** /
static void DecodeEPSG(int epsg, int& zone, bool& northp) throw(); static void DecodeEPSG(int epsg, int& zone, bool& northp);
/** /**
* Encode zone as EPSG. * Encode zone as EPSG.
* *
* @param[in] zone the UTM zone (zero means UPS). * @param[in] zone the UTM zone (zero means UPS).
* @param[in] northp hemisphere (true means north, false means south). * @param[in] northp hemisphere (true means north, false means south).
* @return EPSG code (or -1 if \e zone is not in the range * @return EPSG code (or -1 if \e zone is not in the range
* [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0, 60]) * [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0, 60])
* *
* Convert \e zone and \e northp to the corresponding EPSG (European * Convert \e zone and \e northp to the corresponding EPSG (European
* Petroleum Survery Group) codes * Petroleum Survery Group) codes
********************************************************************** / ********************************************************************** /
static int EncodeEPSG(int zone, bool northp) throw(); static int EncodeEPSG(int zone, bool northp);
/** /**
* @return shift (meters) necessary to align N and S halves of a UTM zo * @return shift (meters) necessary to align north and south halves of
ne a
* (10<sup>7</sup>). * UTM zone (10<sup>7</sup>).
********************************************************************** / ********************************************************************** /
static Math::real UTMShift() throw(); static Math::real UTMShift();
/** \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() static Math::real MajorRadius()
{ return Constants::WGS84_a<real>(); } { return Constants::WGS84_a<real>(); }
/** /**
* @return \e f the flattening of the WGS84 ellipsoid. * @return \e f the 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 Flattening() throw() static Math::real Flattening()
{ return Constants::WGS84_f<real>(); } { return Constants::WGS84_f<real>(); }
///@} ///@}
/// \cond SKIP /// \cond SKIP
/** /**
* <b>DEPRECATED</b> * <b>DEPRECATED</b>
* @return \e r the inverse flattening of the WGS84 ellipsoid. * @return \e r the inverse flattening of the WGS84 ellipsoid.
********************************************************************** / ********************************************************************** /
static Math::real InverseFlattening() throw() static Math::real InverseFlattening()
{ return 1/Constants::WGS84_f<real>(); } { return 1/Constants::WGS84_f<real>(); }
/// \endcond /// \endcond
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_UTMUPS_HPP #endif // GEOGRAPHICLIB_UTMUPS_HPP
 End of changes. 14 change blocks. 
22 lines changed or deleted 49 lines changed or added


 Utility.hpp   Utility.hpp 
skipping to change at line 58 skipping to change at line 58
/** /**
* Convert a date to the day numbering sequentially starting with * Convert a date to the day numbering sequentially starting with
* 0001-01-01 as day 1. * 0001-01-01 as day 1.
* *
* @param[in] y the year (must be positive). * @param[in] y the year (must be positive).
* @param[in] m the month, Jan = 1, etc. (must be positive). Default = 1. * @param[in] m the month, Jan = 1, etc. (must be positive). Default = 1.
* @param[in] d the day of the month (must be positive). Default = 1. * @param[in] d the day of the month (must be positive). Default = 1.
* @return the sequential day number. * @return the sequential day number.
********************************************************************** / ********************************************************************** /
static int day(int y, int m = 1, int d = 1) throw() { static int day(int y, int m = 1, int d = 1) {
// Convert from date to sequential day and vice versa // Convert from date to sequential day and vice versa
// //
// Here is some code to convert a date to sequential day and vice // Here is some code to convert a date to sequential day and vice
// versa. The sequential day is numbered so that January 1, 1 AD is d ay 1 // versa. The sequential day is numbered so that January 1, 1 AD is d ay 1
// (a Saturday). So this is offset from the "Julian" day which starts the // (a Saturday). So this is offset from the "Julian" day which starts the
// numbering with 4713 BC. // numbering with 4713 BC.
// //
// This is inspired by a talk by John Conway at the John von Neumann // This is inspired by a talk by John Conway at the John von Neumann
// National Supercomputer Center when he described his Doomsday algor ithm // National Supercomputer Center when he described his Doomsday algor ithm
// for figuring the day of the week. The code avoids explicitly doing ifs // for figuring the day of the week. The code avoids explicitly doing ifs
skipping to change at line 144 skipping to change at line 144
} }
/** /**
* Given a day (counting from 0001-01-01 as day 1), return the date. * Given a day (counting from 0001-01-01 as day 1), return the date.
* *
* @param[in] s the sequential day number (must be positive) * @param[in] s the sequential day number (must be positive)
* @param[out] y the year. * @param[out] y the year.
* @param[out] m the month, Jan = 1, etc. * @param[out] m the month, Jan = 1, etc.
* @param[out] d the day of the month. * @param[out] d the day of the month.
********************************************************************** / ********************************************************************** /
static void date(int s, int& y, int& m, int& d) throw() { static void date(int s, int& y, int& m, int& d) {
int c = 0; int c = 0;
bool greg = gregorian(s); bool greg = gregorian(s);
s += 305; // s = 0 on March 1, 1BC s += 305; // s = 0 on March 1, 1BC
if (greg) { if (greg) {
s -= 2; // The 2 day Gregorian offset s -= 2; // The 2 day Gregorian offset
// Determine century with the Gregorian rules for leap years. The // Determine century with the Gregorian rules for leap years. The
// Gregorian year is 365 + 1/4 - 1/100 + 1/400 = 146097/400 days. // Gregorian year is 365 + 1/4 - 1/100 + 1/400 = 146097/400 days.
c = (4 * s + 3) / 146097; c = (4 * s + 3) / 146097;
s -= (c * 146097) / 4; // s = 0 at beginning of century s -= (c * 146097) / 4; // s = 0 at beginning of century
} }
skipping to change at line 216 skipping to change at line 216
/** /**
* Given the date, return the day of the week. * Given the date, return the day of the week.
* *
* @param[in] y the year (must be positive). * @param[in] y the year (must be positive).
* @param[in] m the month, Jan = 1, etc. (must be positive). * @param[in] m the month, Jan = 1, etc. (must be positive).
* @param[in] d the day of the month (must be positive). * @param[in] d the day of the month (must be positive).
* @return the day of the week with Sunday, Monday--Saturday = 0, * @return the day of the week with Sunday, Monday--Saturday = 0,
* 1--6. * 1--6.
********************************************************************** / ********************************************************************** /
static int dow(int y, int m, int d) throw() { return dow(day(y, m, d)); } static int dow(int y, int m, int d) { return dow(day(y, m, d)); }
/** /**
* Given the sequential day, return the day of the week. * Given the sequential day, return the day of the week.
* *
* @param[in] s the sequential day (must be positive). * @param[in] s the sequential day (must be positive).
* @return the day of the week with Sunday, Monday--Saturday = 0, * @return the day of the week with Sunday, Monday--Saturday = 0,
* 1--6. * 1--6.
********************************************************************** / ********************************************************************** /
static int dow(int s) throw() { static int dow(int s) {
return (s + 5) % 7; // The 5 offset makes day 1 (0001-01-01) a Satur day. return (s + 5) % 7; // The 5 offset makes day 1 (0001-01-01) a Satur day.
} }
/** /**
* Convert a string representing a date to a fractional year. * Convert a string representing a date to a fractional year.
* *
* @tparam T the type of the argument. * @tparam T the type of the argument.
* @param[in] s the string to be converted. * @param[in] s the string to be converted.
* @exception GeographicErr if \e s can't be interpreted as a date. * @exception GeographicErr if \e s can't be interpreted as a date.
* @return the fractional year. * @return the fractional year.
skipping to change at line 364 skipping to change at line 364
* Lookup up a character in a string. * Lookup up a character in a string.
* *
* @param[in] s the string to be searched. * @param[in] s the string to be searched.
* @param[in] c the character to look for. * @param[in] c the character to look for.
* @return the index of the first occurrence character in the string or * @return the index of the first occurrence character in the string or
* &minus;1 is the character is not present. * &minus;1 is the character is not present.
* *
* \e c is converted to upper case before search \e s. Therefore, it i s * \e c is converted to upper case before search \e s. Therefore, it i s
* intended that \e s should not contain any lower case letters. * intended that \e s should not contain any lower case letters.
********************************************************************** / ********************************************************************** /
static int lookup(const std::string& s, char c) throw() { static int lookup(const std::string& s, char c) {
std::string::size_type r = s.find(char(toupper(c))); std::string::size_type r = s.find(char(toupper(c)));
return r == std::string::npos ? -1 : int(r); return r == std::string::npos ? -1 : int(r);
} }
/** /**
* Read data of type ExtT from a binary stream to an array of type IntT . * Read data of type ExtT from a binary stream to an array of type IntT .
* The data in the file is in (bigendp ? big : little)-endian format. * The data in the file is in (bigendp ? big : little)-endian format.
* *
* @tparam ExtT the type of the objects in the binary stream (external) . * @tparam ExtT the type of the objects in the binary stream (external) .
* @tparam IntT the type of the objects in the array (internal). * @tparam IntT the type of the objects in the array (internal).
 End of changes. 5 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/