CassiniSoldner.hpp   CassiniSoldner.hpp 
/** /**
* \file CassiniSoldner.hpp * \file CassiniSoldner.hpp
* \brief Header for GeographicLib::CassiniSoldner class * \brief Header for GeographicLib::CassiniSoldner class
* *
* Copyright (c) Charles Karney (2009-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_CASSINISOLDNER_HPP) #if !defined(GEOGRAPHICLIB_CASSINISOLDNER_HPP)
#define GEOGRAPHICLIB_CASSINISOLDNER_HPP 1 #define GEOGRAPHICLIB_CASSINISOLDNER_HPP 1
#include <GeographicLib/Geodesic.hpp> #include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicLine.hpp> #include <GeographicLib/GeodesicLine.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
skipping to change at line 78 skipping to change at line 78
class GEOGRAPHICLIB_EXPORT CassiniSoldner { class GEOGRAPHICLIB_EXPORT CassiniSoldner {
private: private:
typedef Math::real real; typedef Math::real real;
real eps1_, tiny_; real eps1_, tiny_;
Geodesic _earth; Geodesic _earth;
GeodesicLine _meridian; GeodesicLine _meridian;
real _sbet0, _cbet0; real _sbet0, _cbet0;
static const unsigned maxit_ = 10; static const unsigned maxit_ = 10;
// The following private helper functions are copied from Geodesic.
static inline real AngRound(real x) {
// 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
// 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
// cases when x is non-zero but tiny (e.g., 1.0e-200).
using std::abs;
const real z = 1/real(16);
GEOGRAPHICLIB_VOLATILE real y = abs(x);
// The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y;
}
static inline void SinCosNorm(real& sinx, real& cosx) {
real r = Math::hypot(sinx, cosx);
sinx /= 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 .
 End of changes. 2 change blocks. 
23 lines changed or deleted 1 lines changed or added


 Config.h   Config.h 
#define GEOGRAPHICLIB_VERSION_MAJOR 1 #define GEOGRAPHICLIB_VERSION_MAJOR 1
#define GEOGRAPHICLIB_VERSION_MINOR 39 #define GEOGRAPHICLIB_VERSION_MINOR 42
#define GEOGRAPHICLIB_VERSION_PATCH 0 #define GEOGRAPHICLIB_VERSION_PATCH 0
#define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 1 #define GEOGRAPHICLIB_HAVE_LONG_DOUBLE 1
#define GEOGRAPHICLIB_VERSION_STRING "1.41" #define GEOGRAPHICLIB_VERSION_STRING "1.42"
/* # undef GEOGRAPHICLIB_WORDS_BIGENDIAN */ /* # undef GEOGRAPHICLIB_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 17 skipping to change at line 17
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_CONSTANTS_HPP) #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP)
#define GEOGRAPHICLIB_CONSTANTS_HPP 1 #define GEOGRAPHICLIB_CONSTANTS_HPP 1
#include <GeographicLib/Config.h> #include <GeographicLib/Config.h>
/** /**
* @relates GeographicLib::Constants * @relates GeographicLib::Constants
* Pack the version components into a single integer. * Pack the version components into a single integer. Users should not rel
y on
* this particular packing of the components of the version number; see the
* documentation for GEOGRAPHICLIB_VERSION, below.
**********************************************************************/ **********************************************************************/
#define GEOGRAPHICLIB_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c) ) #define GEOGRAPHICLIB_VERSION_NUM(a,b,c) ((((a) * 10000 + (b)) * 100) + (c) )
/** /**
* @relates GeographicLib::Constants * @relates GeographicLib::Constants
* The version of GeographicLib as a single integer, packed as MMmmmmpp whe re * The version of GeographicLib as a single integer, packed as MMmmmmpp whe re
* MM is the major version, mmmm is the minor version, and pp is the patch * MM is the major version, mmmm is the minor version, and pp is the patch
* level. * level. Users should not rely on this particular packing of the componen
ts
* of the version number. Instead they should use a test such as \code
#if GEOGRAPHICLIB_VERSION >= GEOGRAPHICLIB_VERSION_NUM(1,37,0)
...
#endif
* \endcode
**********************************************************************/ **********************************************************************/
#define GEOGRAPHICLIB_VERSION \ #define GEOGRAPHICLIB_VERSION \
GEOGRAPHICLIB_VERSION_NUM(GEOGRAPHICLIB_VERSION_MAJOR, \ GEOGRAPHICLIB_VERSION_NUM(GEOGRAPHICLIB_VERSION_MAJOR, \
GEOGRAPHICLIB_VERSION_MINOR, \ GEOGRAPHICLIB_VERSION_MINOR, \
GEOGRAPHICLIB_VERSION_PATCH) GEOGRAPHICLIB_VERSION_PATCH)
/** /**
* @relates GeographicLib::Constants * @relates GeographicLib::Constants
* A compile-time assert. Use C++11 static_assert, if available. * Is the C++11 static_assert available?
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_STATIC_ASSERT) #if !defined(GEOGRAPHICLIB_HAS_STATIC_ASSERT)
# if __cplusplus >= 201103 || defined(__GXX_EXPERIMENTAL_CXX0X__) # if __cplusplus >= 201103 || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define GEOGRAPHICLIB_STATIC_ASSERT static_assert # define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
# elif defined(_MSC_VER) && _MSC_VER >= 1600 # elif defined(_MSC_VER) && _MSC_VER >= 1600
// For reference, here is a table of Visual Studio and _MSC_VER // For reference, here is a table of Visual Studio and _MSC_VER
// correspondences: // correspondences:
// //
// _MSC_VER Visual Studio // _MSC_VER Visual Studio
// 1100 vc5 // 1100 vc5
// 1200 vc6 // 1200 vc6
// 1300 vc7 // 1300 vc7
// 1310 vc7.1 (2003) // 1310 vc7.1 (2003)
// 1400 vc8 (2005) // 1400 vc8 (2005)
// 1500 vc9 (2008) // 1500 vc9 (2008)
// 1600 vc10 (2010) // 1600 vc10 (2010)
// 1700 vc11 (2012) // 1700 vc11 (2012)
// 1800 vc12 (2013) // 1800 vc12 (2013)
// 1900 vc14 (2015) // 1900 vc14 (2015)
# define GEOGRAPHICLIB_HAS_STATIC_ASSERT 1
# else
# define GEOGRAPHICLIB_HAS_STATIC_ASSERT 0
# endif
#endif
/**
* @relates GeographicLib::Constants
* A compile-time assert. Use C++11 static_assert, if available.
**********************************************************************/
#if !defined(GEOGRAPHICLIB_STATIC_ASSERT)
# if GEOGRAPHICLIB_HAS_STATIC_ASSERT
# define GEOGRAPHICLIB_STATIC_ASSERT static_assert # define GEOGRAPHICLIB_STATIC_ASSERT static_assert
# else # else
# define GEOGRAPHICLIB_STATIC_ASSERT(cond,reason) \ # define GEOGRAPHICLIB_STATIC_ASSERT(cond,reason) \
{ enum{ GEOGRAPHICLIB_STATIC_ASSERT_ENUM = 1/int(cond) }; } { enum{ GEOGRAPHICLIB_STATIC_ASSERT_ENUM = 1/int(cond) }; }
# endif # endif
#endif #endif
#if defined(_MSC_VER) && defined(GEOGRAPHICLIB_SHARED_LIB) && \ #if defined(_MSC_VER) && defined(GEOGRAPHICLIB_SHARED_LIB) && \
GEOGRAPHICLIB_SHARED_LIB GEOGRAPHICLIB_SHARED_LIB
# if GEOGRAPHICLIB_SHARED_LIB > 1 # if GEOGRAPHICLIB_SHARED_LIB > 1
 End of changes. 6 change blocks. 
5 lines changed or deleted 26 lines changed or added


 DMS.hpp   DMS.hpp 
/** /**
* \file DMS.hpp * \file DMS.hpp
* \brief Header for GeographicLib::DMS class * \brief Header for GeographicLib::DMS class
* *
* Copyright (c) Charles Karney (2008-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_DMS_HPP) #if !defined(GEOGRAPHICLIB_DMS_HPP)
#define GEOGRAPHICLIB_DMS_HPP 1 #define GEOGRAPHICLIB_DMS_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/Utility.hpp> #include <GeographicLib/Utility.hpp>
skipping to change at line 35 skipping to change at line 35
* \brief Convert between degrees and the %DMS representation * \brief Convert between degrees and the %DMS representation
* *
* Parse a string representing degree, minutes, and seconds and return th e * Parse a string representing degree, minutes, and seconds and return th e
* angle in degrees and format an angle in degrees as degree, minutes, an d * angle in degrees and format an angle in degrees as degree, minutes, an d
* seconds. In addition, handle NANs and infinities on input and output. * seconds. In addition, handle NANs and infinities on input and output.
* *
* Example of use: * Example of use:
* \include example-DMS.cpp * \include example-DMS.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT DMS { class GEOGRAPHICLIB_EXPORT DMS {
private:
typedef Math::real real;
// Replace all occurrences of pat by c
static void replace(std::string& s, const std::string& pat, char c) {
std::string::size_type p = 0;
while (true) {
p = s.find(pat, p);
if (p == std::string::npos)
break;
s.replace(p, pat.length(), 1, c);
}
}
static const std::string hemispheres_;
static const std::string signs_;
static const std::string digits_;
static const std::string dmsindicators_;
static const std::string components_[3];
static Math::real NumMatch(const std::string& s);
DMS(); // Disable constructor
public: public:
/** /**
* Indicator for presence of hemisphere indicator (N/S/E/W) on latitude s * Indicator for presence of hemisphere indicator (N/S/E/W) on latitude s
* and longitudes. * and longitudes.
********************************************************************** / ********************************************************************** /
enum flag { enum flag {
/** /**
* No indicator present. * No indicator present.
* @hideinitializer * @hideinitializer
skipping to change at line 111 skipping to change at line 91
* @hideinitializer * @hideinitializer
******************************************************************** **/ ******************************************************************** **/
MINUTE = 1, MINUTE = 1,
/** /**
* Trailing unit is arc seconds. * Trailing unit is arc seconds.
* @hideinitializer * @hideinitializer
******************************************************************** **/ ******************************************************************** **/
SECOND = 2, SECOND = 2,
}; };
private:
typedef Math::real real;
// Replace all occurrences of pat by c
static void replace(std::string& s, const std::string& pat, char c) {
std::string::size_type p = 0;
while (true) {
p = s.find(pat, p);
if (p == std::string::npos)
break;
s.replace(p, pat.length(), 1, c);
}
}
static const std::string hemispheres_;
static const std::string signs_;
static const std::string digits_;
static const std::string dmsindicators_;
static const std::string components_[3];
static Math::real NumMatch(const std::string& s);
static Math::real InternalDecode(const std::string& dmsa, flag& ind);
DMS(); // Disable constructor
public:
/** /**
* Convert a string in DMS to an angle. * Convert a string in DMS to an angle.
* *
* @param[in] dms string input. * @param[in] dms string input.
* @param[out] ind a DMS::flag value signaling the presence of a * @param[out] ind a DMS::flag value signaling the presence of a
* hemisphere indicator. * hemisphere indicator.
* @exception GeographicErr if \e dms is malformed (see below). * @exception GeographicErr if \e dms is malformed (see below).
* @return angle (degrees). * @return angle (degrees).
* *
* Degrees, minutes, and seconds are indicated by the characters d, ' * Degrees, minutes, and seconds are indicated by the characters d, '
skipping to change at line 133 skipping to change at line 136
* other symbols (e.g., the &deg; symbol for degrees and the unicode pr ime * other symbols (e.g., the &deg; symbol for degrees and the unicode pr ime
* and double prime symbols for minutes and seconds) may be substituted ; * and double prime symbols for minutes and seconds) may be substituted ;
* two single quotes can be used instead of &quot;. The last component * two single quotes can be used instead of &quot;. The last component
* indicator may be omitted and is assumed to be the next smallest unit * indicator may be omitted and is assumed to be the next smallest unit
* (thus 33d10 is interpreted as 33d10'). The final component may be a * (thus 33d10 is interpreted as 33d10'). The final component may be a
* decimal fraction but the non-final components must be integers. Ins tead * decimal fraction but the non-final components must be integers. Ins tead
* of using d, ', and &quot; to indicate degrees, minutes, and seconds, : * of using d, ', and &quot; to indicate degrees, minutes, and seconds, :
* (colon) may be used to <i>separate</i> these components (numbers mus t * (colon) may be used to <i>separate</i> these components (numbers mus t
* appear before and after each colon); thus 50d30'10.3&quot; may be * appear before and after each colon); thus 50d30'10.3&quot; may be
* written as 50:30:10.3, 5.5' may be written 0:5.5, and so on. The * written as 50:30:10.3, 5.5' may be written 0:5.5, and so on. The
* integer parts of the minutes and seconds components must be less tha * integer parts of the minutes and seconds components must be less
n * than 60. A single leading sign is permitted. A hemisphere designat
* 60. A single leading sign is permitted. A hemisphere designator (N or
, E, * (N, E, W, S) may be added to the beginning or end of the string. Th
* W, S) may be added to the beginning or end of the string. The resul e
t is * result is multiplied by the implied sign of the hemisphere designato
* multiplied by the implied sign of the hemisphere designator (negativ r
e * (negative for S and W). In addition \e ind is set to DMS::LATITUDE
* for S and W). In addition \e ind is set to DMS::LATITUDE if N or S if N
is * or S is present, to DMS::LONGITUDE if E or W is present, and to
* present, to DMS::LONGITUDE if E or W is present, and to DMS::NONE * DMS::NONE otherwise. Throws an error on a malformed string. No che
* otherwise. Throws an error on a malformed string. No check is ck
* performed on the range of the result. Examples of legal and illegal * is performed on the range of the result. Examples of legal and ille
gal
* strings are * strings are
* - <i>LEGAL</i> (all the entries on each line are equivalent) * - <i>LEGAL</i> (all the entries on each line are equivalent)
* - -20.51125, 20d30'40.5&quot;S, -20&deg;30'40.5, -20d30.675, * - -20.51125, 20d30'40.5&quot;S, -20&deg;30'40.5, -20d30.675,
* N-20d30'40.5&quot;, -20:30:40.5 * N-20d30'40.5&quot;, -20:30:40.5
* - 4d0'9, 4d9&quot;, 4d9'', 4:0:9, 004:00:09, 4.0025, 4.0025d, 4d0. 15, * - 4d0'9, 4d9&quot;, 4d9'', 4:0:9, 004:00:09, 4.0025, 4.0025d, 4d0. 15,
* 04:.15 * 04:.15
* - <i>ILLEGAL</i> (the exception thrown explains the problem) * - <i>ILLEGAL</i> (the exception thrown explains the problem)
* - 4d5&quot;4', 4::5, 4:5:, :4:5, 4d4.5'4&quot;, -N20.5, 1.8e2d, 4: 60, * - 4d5&quot;4', 4::5, 4:5:, :4:5, 4d4.5'4&quot;, -N20.5, 1.8e2d, 4: 60,
* 4d-5' * 4d-5'
* *
* The decoding operation can also perform a single addition or subtrac
tion
* operation. If the string includes an <i>internal</i> sign (i.e., no
t at
* the beginning nor immediately after an initial hemisphere designator
),
* then the string is split immediately before that sign and each half
is
* decoded according to the above rules and the results added. The sec
ond
* half can include a hemisphere designator, but it must come at the en
d (a
* hemisphere designator is not allowed after the initial sign). If bo
th
* halves include hemisphere designators then these must compatible; e.
g.,
* you cannot mix N and E. Examples of legal and illegal combinations
are
* - <i>LEGAL</i> (these are all equivalent)
* - 070:00:45, 70:01:15W+0:0.5, 70:01:15W-0:0:30W, W70:01:15+0:0:30E
* - <i>ILLEGAL</i> (the exception thrown explains the problem)
* - 70:01:15W+0:0:15N, W70:01:15+W0:0:15
*
* <b>NOTE:</b> At present, all the string handling in the C++ * <b>NOTE:</b> At present, all the string handling in the C++
* implementation %GeographicLib is with 8-bit characters. The support for * implementation %GeographicLib is with 8-bit characters. The support for
* unicode symbols for degrees, minutes, and seconds is therefore via t he * unicode symbols for degrees, minutes, and seconds is therefore via t he
* <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoding. ( The * <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoding. ( The
* JavaScript implementation of this class uses unicode natively, of * JavaScript implementation of this class uses unicode natively, of
* course.) * course.)
* *
* Here is the list of Unicode symbols supported for degrees, minutes, * Here is the list of Unicode symbols supported for degrees, minutes,
* seconds: * seconds, and the sign:
* - degrees: * - degrees:
* - d, D lower and upper case letters * - d, D lower and upper case letters
* - U+00b0 degree symbol (&deg;) * - U+00b0 degree symbol (&deg;)
* - U+00ba masculine ordinal indicator * - U+00ba masculine ordinal indicator
* - U+2070 superscript zero * - U+2070 superscript zero
* - U+02da ring above * - U+02da ring above
* - minutes: * - minutes:
* - ' apostrophe * - ' apostrophe
* - U+2032 prime (&prime;) * - U+2032 prime (&prime;)
* - U+00b4 acute accent * - U+00b4 acute accent
* - U+2019 right single quote (&rsquo;) * - U+2019 right single quote (&rsquo;)
* - seconds: * - seconds:
* - &quot; quotation mark * - &quot; quotation mark
* - U+2033 double prime (&Prime;) * - U+2033 double prime (&Prime;)
* - U+201d right double quote (&rdquo;) * - U+201d right double quote (&rdquo;)
* - '&nbsp;' any two consecutive symbols for minutes * - '&nbsp;' any two consecutive symbols for minutes
* - leading sign:
* - U+2212 minus sign (&minus;)
* . * .
* The codes with a leading zero byte, e.g., U+00b0, are accepted in th eir * The codes with a leading zero byte, e.g., U+00b0, are accepted in th eir
* UTF-8 coded form 0xc2 0xb0 and as a single byte 0xb0. * UTF-8 coded form 0xc2 0xb0 and as a single byte 0xb0.
********************************************************************** / ********************************************************************** /
static Math::real Decode(const std::string& dms, flag& ind); static Math::real Decode(const std::string& dms, flag& ind);
/** /**
* Convert DMS to an angle. * Convert DMS to an angle.
* *
* @param[in] d degrees. * @param[in] d degrees.
 End of changes. 7 change blocks. 
35 lines changed or deleted 64 lines changed or added


 Ellipsoid.hpp   Ellipsoid.hpp 
/** /**
* \file Ellipsoid.hpp * \file Ellipsoid.hpp
* \brief Header for GeographicLib::Ellipsoid class * \brief Header for GeographicLib::Ellipsoid class
* *
* Copyright (c) Charles Karney (2012-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2012-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_ELLIPSOID_HPP) #if !defined(GEOGRAPHICLIB_ELLIPSOID_HPP)
#define GEOGRAPHICLIB_ELLIPSOID_HPP 1 #define GEOGRAPHICLIB_ELLIPSOID_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/TransverseMercator.hpp> #include <GeographicLib/TransverseMercator.hpp>
#include <GeographicLib/EllipticFunction.hpp> #include <GeographicLib/EllipticFunction.hpp>
skipping to change at line 44 skipping to change at line 44
* *
* Example of use: * Example of use:
* \include example-Ellipsoid.cpp * \include example-Ellipsoid.cpp
**********************************************************************/ **********************************************************************/
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;
real stol_; real stol_;
real _a, _f, _f1, _f12, _e2, _e, _e12, _n, _b; real _a, _f, _f1, _f12, _e2, _es, _e12, _n, _b;
TransverseMercator _tm; TransverseMercator _tm;
EllipticFunction _ell; EllipticFunction _ell;
AlbersEqualArea _au; AlbersEqualArea _au;
static inline real tand(real x) {
using std::abs; using std::tan;
return
abs(x) == real(90) ? (x < 0 ?
- TransverseMercator::overflow()
: TransverseMercator::overflow()) :
tan(x * Math::degree());
}
static inline real atand(real x)
{ using std::atan; return atan(x) / Math::degree(); }
// These are the alpha and beta coefficients in the Krueger series from // These are the alpha and beta coefficients in the Krueger series from
// TransverseMercator. Thy are used by RhumbSolve to compute // TransverseMercator. Thy are used by RhumbSolve to compute
// (psi2-psi1)/(mu2-mu1). // (psi2-psi1)/(mu2-mu1).
const Math::real* ConformalToRectifyingCoeffs() const { return _tm._alp ; } const Math::real* ConformalToRectifyingCoeffs() const { return _tm._alp ; }
const Math::real* RectifyingToConformalCoeffs() const { return _tm._bet ; } const Math::real* RectifyingToConformalCoeffs() const { return _tm._bet ; }
friend class Rhumb; friend class RhumbLine; friend class Rhumb; friend class RhumbLine;
public: public:
/** \name Constructor /** \name Constructor
********************************************************************** / ********************************************************************** /
 End of changes. 3 change blocks. 
12 lines changed or deleted 2 lines changed or added


 GeoCoords.hpp   GeoCoords.hpp 
skipping to change at line 136 skipping to change at line 136
* - N40 W75 * - N40 W75
* - -75 N40 * - -75 N40
* - 75W 40N * - 75W 40N
* - E-75 -40S * - E-75 -40S
* . * .
* are all the same position. The coordinates may be given in * are all the same position. The coordinates may be given in
* decimal degrees, degrees and decimal minutes, degrees, minutes, * decimal degrees, degrees and decimal minutes, degrees, minutes,
* seconds, etc. Use d, ', and &quot; to mark off the degrees, * seconds, etc. Use d, ', and &quot; to mark off the degrees,
* minutes and seconds. Various alternative symbols for degrees, minut es, * minutes and seconds. Various alternative symbols for degrees, minut es,
* and seconds are allowed. Alternatively, use : to separate these * and seconds are allowed. Alternatively, use : to separate these
* components. (See DMS::Decode for details.) Thus * components. A single addition or subtraction is allowed. (See
* DMS::Decode for details.) Thus
* - 40d30'30&quot; * - 40d30'30&quot;
* - 40d30'30 * - 40d30'30
* - 40&deg;30'30 * - 40&deg;30'30
* - 40d30.5' * - 40d30.5'
* - 40d30.5 * - 40d30.5
* - 40:30:30 * - 40:30:30
* - 40:30.5 * - 40:30.5
* - 40.508333333 * - 40.508333333
* - 40:30+0:0:30
* - 40:31-0:0.5
* . * .
* all specify the same angle. The leading sign applies to all compone * all specify the same angle. The leading sign applies to the followi
nts ng
* so -1d30 is -(1+30/60) = -1.5. Latitudes must be in the range * components so -1d30 is -(1+30/60) = &minus;1.5. However, note
* [&minus;90&deg;, 90&deg;] and longitudes in the range * that -1:30-0:0:15 is parsed as (-1:30) + (-0:0:15) = &minus;(1+30/60
* [&minus;540&deg;, 540&deg;). Internally longitudes are reduced )
* to the range [&minus;180&deg;, 180&deg;). * &minus; (15/3600). Latitudes must be in the range [&minus;90&deg;,
* 90&deg;] and longitudes in the range [&minus;540&deg;, 540&deg;).
* Internally longitudes are reduced 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 (38north can also be use d). * and a hemisphere letter (n or s), e.g., 38n (38north can also be use d).
* The latitude band designer ([C--M] in the southern hemisphere and [N --X] * The latitude band designer ([C--M] in the southern hemisphere and [N --X]
* in the northern) should NOT be used. (This is part of the MGRS * in the northern) should NOT be used. (This is part of the MGRS
* coordinate.) The zone designator for the poles (where UPS is employ ed) * coordinate.) The zone designator for the poles (where UPS is employ ed)
* is a hemisphere letter by itself, i.e., n or s (north or south can a lso * is a hemisphere letter by itself, i.e., n or s (north or south can a lso
* be used). * be used).
* *
 End of changes. 3 change blocks. 
7 lines changed or deleted 13 lines changed or added


 Geodesic.hpp   Geodesic.hpp 
/** /**
* \file Geodesic.hpp * \file Geodesic.hpp
* \brief Header for GeographicLib::Geodesic class * \brief Header for GeographicLib::Geodesic class
* *
* Copyright (c) Charles Karney (2009-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_GEODESIC_HPP) #if !defined(GEOGRAPHICLIB_GEODESIC_HPP)
#define GEOGRAPHICLIB_GEODESIC_HPP 1 #define GEOGRAPHICLIB_GEODESIC_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if !defined(GEOGRAPHICLIB_GEODESIC_ORDER) #if !defined(GEOGRAPHICLIB_GEODESIC_ORDER)
skipping to change at line 205 skipping to change at line 205
CAP_C3 = 1U<<3, CAP_C3 = 1U<<3,
CAP_C4 = 1U<<4, CAP_C4 = 1U<<4,
CAP_ALL = 0x1FU, CAP_ALL = 0x1FU,
CAP_MASK = CAP_ALL, CAP_MASK = CAP_ALL,
OUT_ALL = 0x7F80U, OUT_ALL = 0x7F80U,
OUT_MASK = 0xFF80U, // Includes LONG_NOWRAP OUT_MASK = 0xFF80U, // Includes LONG_NOWRAP
}; };
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);
static inline real AngRound(real x) {
// 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
// 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
// cases when x is non-zero but tiny (e.g., 1.0e-200).
using std::abs;
const real z = 1/real(16);
GEOGRAPHICLIB_VOLATILE real y = abs(x);
// The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y;
}
static inline void SinCosNorm(real& sinx, real& cosx) {
real r = Math::hypot(sinx, cosx);
sinx /= r;
cosx /= r;
}
static real Astroid(real x, real y); 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,
 End of changes. 2 change blocks. 
22 lines changed or deleted 1 lines changed or added


 GeodesicExact.hpp   GeodesicExact.hpp 
/** /**
* \file GeodesicExact.hpp * \file GeodesicExact.hpp
* \brief Header for GeographicLib::GeodesicExact class * \brief Header for GeographicLib::GeodesicExact class
* *
* Copyright (c) Charles Karney (2012-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2012-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_GEODESICEXACT_HPP) #if !defined(GEOGRAPHICLIB_GEODESICEXACT_HPP)
#define GEOGRAPHICLIB_GEODESICEXACT_HPP 1 #define GEOGRAPHICLIB_GEODESICEXACT_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/EllipticFunction.hpp> #include <GeographicLib/EllipticFunction.hpp>
skipping to change at line 104 skipping to change at line 104
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,
CAP_MASK = CAP_ALL, CAP_MASK = CAP_ALL,
OUT_ALL = 0x7F80U, OUT_ALL = 0x7F80U,
OUT_MASK = 0xFF80U, // Includes LONG_NOWRAP OUT_MASK = 0xFF80U, // Includes LONG_NOWRAP
}; };
static real CosSeries(real sinx, real cosx, const real c[], int n); static real CosSeries(real sinx, real cosx, const real c[], int n);
static inline real AngRound(real x) {
// 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
// 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
// cases when x is non-zero but tiny (e.g., 1.0e-200).
using std::abs;
const real z = 1/real(16);
GEOGRAPHICLIB_VOLATILE real y = abs(x);
// The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y;
}
static inline void SinCosNorm(real& sinx, real& cosx) {
real r = Math::hypot(sinx, cosx);
sinx /= r;
cosx /= r;
}
static real Astroid(real x, real y); 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,
 End of changes. 2 change blocks. 
22 lines changed or deleted 1 lines changed or added


 Geoid.hpp   Geoid.hpp 
/** /**
* \file Geoid.hpp * \file Geoid.hpp
* \brief Header for GeographicLib::Geoid class * \brief Header for GeographicLib::Geoid class
* *
* Copyright (c) Charles Karney (2009-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_GEOID_HPP) #if !defined(GEOGRAPHICLIB_GEOID_HPP)
#define GEOGRAPHICLIB_GEOID_HPP 1 #define GEOGRAPHICLIB_GEOID_HPP 1
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
skipping to change at line 71 skipping to change at line 71
* See \ref geoid for details of how to install the data sets, the data * See \ref geoid for details of how to install the data sets, the data
* format, estimates of the interpolation errors, and how to use caching. * format, estimates of the interpolation errors, and how to use caching.
* *
* In addition to returning the geoid height, the gradient of the geoid c an * In addition to returning the geoid height, the gradient of the geoid c an
* be calculated. The gradient is defined as the rate of change of the g eoid * be calculated. The gradient is defined as the rate of change of the g eoid
* as a function of position on the ellipsoid. This uses the parameters for * as a function of position on the ellipsoid. This uses the parameters for
* the WGS84 ellipsoid. The gradient defined in terms of the interpolate d * the WGS84 ellipsoid. The gradient defined in terms of the interpolate d
* heights. As a result of the way that the geoid data is stored, the * heights. As a result of the way that the geoid data is stored, the
* calculation of gradients can result in large quantization errors. Thi s is * calculation of gradients can result in large quantization errors. Thi s is
* particularly acute for fine grids, at high latitudes, and for the east erly * particularly acute for fine grids, at high latitudes, and for the east erly
* gradient. * gradient. For this reason, the use of this facility is <b>DEPRECATED<
/b>.
* Instead, use the GravityModel class to evaluate the gravity vector.
* *
* This class is typically \e not thread safe in that a single instantiat ion * This class is typically \e not thread safe in that a single instantiat ion
* cannot be safely used by multiple threads because of the way the objec t * cannot be safely used by multiple threads because of the way the objec t
* reads the data set and because it maintains a single-cell cache. If * reads the data set and because it maintains a single-cell cache. If
* multiple threads need to calculate geoid heights they should all const ruct * multiple threads need to calculate geoid heights they should all const ruct
* thread-local instantiations. Alternatively, set the optional \e * thread-local instantiations. Alternatively, set the optional \e
* threadsafe parameter to true in the constructor. This causes the * threadsafe parameter to true in the constructor. This causes the
* constructor to read all the data into memory and to turn off the * constructor to read all the data into memory and to turn off the
* single-cell caching which results in a Geoid object which \e is thread * single-cell caching which results in a Geoid object which \e is thread
* safe. * safe.
skipping to change at line 312 skipping to change at line 313
* Compute the geoid height and gradient at a point * Compute the geoid height and gradient at a point
* *
* @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[out] gradn northerly gradient (dimensionless). * @param[out] gradn northerly gradient (dimensionless).
* @param[out] grade easterly gradient (dimensionless). * @param[out] grade easterly gradient (dimensionless).
* @exception GeographicErr if there's a problem reading the data; this * @exception GeographicErr if there's a problem reading the data; this
* never happens if (\e lat, \e lon) is within a successfully cached area. * never happens if (\e lat, \e lon) is within a successfully cached area.
* @return geoid height (meters). * @return geoid height (meters).
* *
* The latitude should be in [&minus;90&deg;, 90&deg;] and * The latitude should be in [&minus;90&deg;, 90&deg;] and longitude sh
* longitude should be in [&minus;540&deg;, 540&deg;). As a result ould
* of the way that the geoid data is stored, the calculation of gradien * be in [&minus;540&deg;, 540&deg;). As a result of the way that the
ts * geoid data is stored, the calculation of gradients can result in lar
* can result in large quantization errors. This is particularly acute ge
for * quantization errors. This is particularly acute for fine grids, at
* fine grids, at high latitudes, and for the easterly gradient. If yo high
u * latitudes, and for the easterly gradient. For this reason, the
* need to compute the direction of the acceleration due to gravity * computation of the gradient is <b>DEPRECATED</b>. If you need to
* accurately, you should use GravityModel::Gravity. * compute the direction of the acceleration due to gravity accurately,
you
* should use GravityModel::Gravity.
********************************************************************** / ********************************************************************** /
Math::real operator()(real lat, real lon, real& gradn, real& grade) con st { Math::real operator()(real lat, real lon, real& gradn, real& grade) con st {
return height(lat, lon, true, gradn, grade); return height(lat, lon, true, gradn, grade);
} }
/** /**
* Convert a height above the geoid to a height above the ellipsoid and * Convert a height above the geoid to a height above the ellipsoid and
* vice versa. * vice versa.
* *
* @param[in] lat latitude of the point (degrees). * @param[in] lat latitude of the point (degrees).
 End of changes. 3 change blocks. 
12 lines changed or deleted 16 lines changed or added


 LambertConformalConic.hpp   LambertConformalConic.hpp 
/** /**
* \file LambertConformalConic.hpp * \file LambertConformalConic.hpp
* \brief Header for GeographicLib::LambertConformalConic class * \brief Header for GeographicLib::LambertConformalConic class
* *
* Copyright (c) Charles Karney (2010-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2010-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP) #if !defined(GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP)
#define GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP 1 #define GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
skipping to change at line 60 skipping to change at line 60
* EPSG:3364</a>) is obtained by: * EPSG:3364</a>) is obtained by:
* \include example-LambertConformalConic.cpp * \include example-LambertConformalConic.cpp
* *
* <a href="ConicProj.1.html">ConicProj</a> is a command-line utility * <a href="ConicProj.1.html">ConicProj</a> is a command-line utility
* providing access to the functionality of LambertConformalConic and * providing access to the functionality of LambertConformalConic and
* AlbersEqualArea. * AlbersEqualArea.
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT LambertConformalConic { class GEOGRAPHICLIB_EXPORT LambertConformalConic {
private: private:
typedef Math::real real; typedef Math::real real;
real eps_, epsx_, tol_, ahypover_; real eps_, epsx_, ahypover_;
real _a, _f, _fm, _e2, _e, _e2m; real _a, _f, _fm, _e2, _es;
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 int numit_ = 5; static const int numit_ = 5;
static inline real hyp(real x) { 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
// - sqrt(-e2) * atan( sqrt(-e2) * x) if f < 0
inline real eatanhe(real x) const {
using std::atan;
return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * 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)
// https://dx.doi.org/10.1145/334714.334716 // https://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
skipping to change at line 135 skipping to change at line 129
static inline real Dasinh(real x, real y, real hx, real hy) { 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 ? return t ?
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 { 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 ? eatanhe(t / d) / t : _e2 / d; return t ? Math::eatanhe(t / d, _es) / t : _e2 / d;
} }
void Init(real sphi1, real cphi1, real sphi2, real cphi2, real k1); 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 &gt; 1, set * Negative \e f gives a prolate ellipsoid. If \e f &gt; 1, set
 End of changes. 4 change blocks. 
10 lines changed or deleted 4 lines changed or added


 MGRS.hpp   MGRS.hpp 
skipping to change at line 206 skipping to change at line 206
* are allowed to be in in [0 km, 9500 km] for the northern hemisphere and * are allowed to be in in [0 km, 9500 km] for the northern hemisphere and
* in [1000 km, 10000 km] for the southern hemisphere. (However UTM * in [1000 km, 10000 km] for the southern hemisphere. (However UTM
* northings can be continued across the equator. So the actual limits on * northings can be continued across the equator. So the actual limits on
* the northings are [&minus;9000 km, 9500 km] for the "northern" * the northings are [&minus;9000 km, 9500 km] for the "northern"
* hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.) * hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.)
* *
* UPS eastings/northings are allowed to be in the range [1300 km, 2700 km] * UPS eastings/northings are allowed to be in the range [1300 km, 2700 km]
* in the northern hemisphere and in [800 km, 3200 km] in the southern * in the northern hemisphere and in [800 km, 3200 km] in the southern
* hemisphere. * hemisphere.
* *
* The ranges are 100 km more restrictive that for the conversion betwe en * The ranges are 100 km more restrictive than for the conversion betwe en
* geographic coordinates and UTM and UPS given by UTMUPS. These * geographic coordinates and UTM and UPS given by UTMUPS. These
* restrictions are dictated by the allowed letters in MGRS coordinates . * restrictions are dictated by the allowed letters in MGRS coordinates .
* The choice of 9500 km for the maximum northing for northern hemisphe re * The choice of 9500 km for the maximum northing for northern hemisphe re
* and of 1000 km as the minimum northing for southern hemisphere provi de * and of 1000 km as the minimum northing for southern hemisphere provi de
* 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
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 Math.hpp   Math.hpp 
/** /**
* \file Math.hpp * \file Math.hpp
* \brief Header for GeographicLib::Math class * \brief Header for GeographicLib::Math class
* *
* Copyright (c) Charles Karney (2008-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
// Constants.hpp includes Math.hpp. Place this include outside Math.hpp's // Constants.hpp includes Math.hpp. Place this include outside Math.hpp's
// 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
skipping to change at line 65 skipping to change at line 65
* double. * double.
**********************************************************************/ **********************************************************************/
# define GEOGRAPHICLIB_PRECISION 2 # define GEOGRAPHICLIB_PRECISION 2
#endif #endif
#include <cmath> #include <cmath>
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#if GEOGRAPHICLIB_PRECISION == 4 #if GEOGRAPHICLIB_PRECISION == 4
#include <boost/version.hpp>
#if BOOST_VERSION >= 105600
#include <boost/cstdfloat.hpp>
#endif
#include <boost/multiprecision/float128.hpp> #include <boost/multiprecision/float128.hpp>
#include <boost/math/special_functions/hypot.hpp> #include <boost/math/special_functions.hpp>
#include <boost/math/special_functions/expm1.hpp> __float128 fmaq(__float128, __float128, __float128);
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/atanh.hpp>
#include <boost/math/special_functions/asinh.hpp>
#include <boost/math/special_functions/cbrt.hpp>
#elif GEOGRAPHICLIB_PRECISION == 5 #elif GEOGRAPHICLIB_PRECISION == 5
#include <mpreal.h> #include <mpreal.h>
#endif #endif
#if GEOGRAPHICLIB_PRECISION > 3 #if GEOGRAPHICLIB_PRECISION > 3
// volatile keyword makes no sense for multiprec types // volatile keyword makes no sense for multiprec types
#define GEOGRAPHICLIB_VOLATILE #define GEOGRAPHICLIB_VOLATILE
// Signal a convergence failure with multiprec types by throwing an excepti on // Signal a convergence failure with multiprec types by throwing an excepti on
// at loop exit. // at loop exit.
#define GEOGRAPHICLIB_PANIC \ #define GEOGRAPHICLIB_PANIC \
skipping to change at line 368 skipping to change at line 368
#if GEOGRAPHICLIB_CXX11_MATH #if GEOGRAPHICLIB_CXX11_MATH
using std::cbrt; return cbrt(x); using std::cbrt; return cbrt(x);
#else #else
using std::abs; using std::pow; using std::abs; using std::pow;
T y = pow(abs(x), 1/T(3)); // Return the real cube root T y = pow(abs(x), 1/T(3)); // Return the real cube root
return x < 0 ? -y : y; return x < 0 ? -y : y;
#endif #endif
} }
/** /**
* Fused multiply and add.
*
* @tparam T the type of the arguments and the returned value.
* @param[in] x
* @param[in] y
* @param[in] z
* @return <i>xy</i> + <i>z</i>, correctly rounded (on those platforms
with
* support for the fma instruction).
**********************************************************************
/
template<typename T> static inline T fma(T x, T y, T z) {
#if GEOGRAPHICLIB_CXX11_MATH
using std::fma; return fma(x, y, z);
#else
return x * y + z;
#endif
}
/**
* Normalize a two-vector.
*
* @tparam T the type of the argument and the returned value.
* @param[in,out] x on output set to <i>x</i>/hypot(<i>x</i>, <i>y</i>)
.
* @param[in,out] y on output set to <i>y</i>/hypot(<i>x</i>, <i>y</i>)
.
**********************************************************************
/
template<typename T> static inline void norm(T& x, T& y)
{ T h = hypot(x, y); x /= h; y /= h; }
/**
* 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.)
skipping to change at line 440 skipping to change at line 468
template<typename T> static inline T AngDiff(T x, T y) { 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;
} }
/** /**
* Coarsen a value close to zero.
*
* @tparam T the type of the argument and returned value.
* @param[in] x
* @return the coarsened value.
*
* The makes the smallest gap in \e x = 1/16 - nextafter(1/16, 0) =
* 1/2<sup>57</sup> for reals = 0.7 pm on the earth if \e x is an angle
in
* degrees. (This is about 1000 times more resolution than we get with
* angles around 90&deg;.) We use this to avoid having to deal with ne
ar
* singular cases when \e x is non-zero but tiny (e.g.,
* 10<sup>&minus;200</sup>).
**********************************************************************
/
template<typename T> static inline T AngRound(T x) {
using std::abs;
const T z = 1/T(16);
GEOGRAPHICLIB_VOLATILE T y = abs(x);
// The compiler mustn't "simplify" z - (z - y) to y
y = y < z ? z - (z - y) : y;
return x < 0 ? -y : y;
}
/**
* Evaluate the tangent function with the argument in degrees
*
* @tparam T the type of the argument and the returned value.
* @param[in] x in degrees.
* @return tan(<i>x</i>).
*
* If \e x = &plusmn;90&deg;, then a suitably large (but finite) value
is
* returned.
**********************************************************************
/
template<typename T> static inline T tand(T x) {
using std::abs; using std::tan;
static const T overflow = 1 / Math::sq(std::numeric_limits<T>::epsilo
n());
return abs(x) != 90 ? tan(x * Math::degree()) :
(x < 0 ? -overflow : overflow);
}
/**
* Evaluate the atan function with the result in degrees
*
* @tparam T the type of the argument and the returned value.
* @param[in] x
* @return atan(<i>x</i>) in degrees.
*
* Large values for the argument return &plusmn;90&deg;
**********************************************************************
/
template<typename T> static inline T atand(T x) {
using std::abs; using std::atan;
static const T
overflow = 1 / (Math::sq(std::numeric_limits<T>::epsilon()) * 100);
return !(abs(x) >= overflow) ? atan(x) / Math::degree() :
(x > 0 ? 90 : -90);
}
/**
* Evaluate the atan2 function with the result in degrees
*
* @tparam T the type of the arguments and the returned value.
* @param[in] y
* @param[in] x
* @return atan2(<i>y</i>, <i>x</i>) in degrees.
*
* The result is in the range [&minus;180&deg; 180&deg;).
**********************************************************************
/
template<typename T> static inline T atan2d(T y, T x) {
using std::atan2;
return 0 - atan2(-y, x) / Math::degree();
}
/**
* Evaluate <i>e</i> atanh(<i>e x</i>)
*
* @tparam T the type of the argument and the returned value.
* @param[in] x
* @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
* sqrt(|<i>e</i><sup>2</sup>|)
* @return <i>e</i> atanh(<i>e x</i>)
*
* If <i>e</i><sup>2</sup> is negative (<i>e</i> is imaginary), the
* expression is evaluated in terms of atan.
**********************************************************************
/
template<typename T> static T eatanhe(T x, T es);
/**
* tan&chi; in terms of tan&phi;
*
* @tparam T the type of the argument and the returned value.
* @param[in] tau &tau; = tan&phi;
* @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
* sqrt(|<i>e</i><sup>2</sup>|)
* @return &tau;&prime; = tan&chi;
*
* See Eqs. (7--9) of
* C. F. F. Karney,
* <a href="https://dx.doi.org/10.1007/s00190-011-0445-3">
* Transverse Mercator with an accuracy of a few nanometers,</a>
* J. Geodesy 85(8), 475--485 (Aug. 2011)
* (preprint <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</
a>).
**********************************************************************
/
template<typename T> static T taupf(T tau, T es);
/**
* tan&phi; in terms of tan&chi;
*
* @tparam T the type of the argument and the returned value.
* @param[in] taup &tau;&prime; = tan&chi;
* @param[in] es the signed eccentricity = sign(<i>e</i><sup>2</sup>)
* sqrt(|<i>e</i><sup>2</sup>|)
* @return &tau; = tan&phi;
*
* See Eqs. (19--21) of
* C. F. F. Karney,
* <a href="https://dx.doi.org/10.1007/s00190-011-0445-3">
* Transverse Mercator with an accuracy of a few nanometers,</a>
* J. Geodesy 85(8), 475--485 (Aug. 2011)
* (preprint <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</
a>).
**********************************************************************
/
template<typename T> static T tauf(T taup, T es);
/**
* 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) { template<typename T> static inline bool isfinite(T x) {
#if GEOGRAPHICLIB_CXX11_MATH #if GEOGRAPHICLIB_CXX11_MATH
using std::isfinite; return isfinite(x); using std::isfinite; return isfinite(x);
#else #else
skipping to change at line 550 skipping to change at line 700
static inline real asinh(real x) static inline real asinh(real x)
{ return boost::math::asinh(x, boost_special_functions_policy()); } { return boost::math::asinh(x, boost_special_functions_policy()); }
static inline real atanh(real x) static inline real atanh(real x)
{ return boost::math::atanh(x, boost_special_functions_policy()); } { return boost::math::atanh(x, boost_special_functions_policy()); }
static inline real cbrt(real x) static inline real cbrt(real x)
{ return boost::math::cbrt(x, boost_special_functions_policy()); } { return boost::math::cbrt(x, boost_special_functions_policy()); }
static inline real fma(real x, real y, real z)
{ return fmaq(__float128(x), __float128(y), __float128(z)); }
static inline bool isnan(real x) { return boost::math::isnan(x); } static inline bool isnan(real x) { return boost::math::isnan(x); }
static inline bool isfinite(real x) { return boost::math::isfinite(x); } static inline bool isfinite(real x) { return boost::math::isfinite(x); }
#endif #endif
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_MATH_HPP #endif // GEOGRAPHICLIB_MATH_HPP
 End of changes. 6 change blocks. 
7 lines changed or deleted 178 lines changed or added


 PolarStereographic.hpp   PolarStereographic.hpp 
/** /**
* \file PolarStereographic.hpp * \file PolarStereographic.hpp
* \brief Header for GeographicLib::PolarStereographic class * \brief Header for GeographicLib::PolarStereographic class
* *
* Copyright (c) Charles Karney (2008-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP) #if !defined(GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP)
#define GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP 1 #define GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
skipping to change at line 35 skipping to change at line 35
* *
* This is a straightforward implementation of the equations in Snyder ex cept * This is a straightforward implementation of the equations in Snyder ex cept
* that Newton's method is used to invert the projection. * that Newton's method is used to invert the projection.
* *
* Example of use: * Example of use:
* \include example-PolarStereographic.cpp * \include example-PolarStereographic.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT PolarStereographic { class GEOGRAPHICLIB_EXPORT PolarStereographic {
private: private:
typedef Math::real real; typedef Math::real real;
real tol_; real _a, _f, _e2, _es, _e2m, _c;
// _Cx used to be _C but g++ 3.4 has a macro of that name
real _a, _f, _e2, _e, _e2m, _Cx, _c;
real _k0; real _k0;
static const int numit_ = 5;
static inline real overflow() {
// Overflow value s.t. atan(overflow_) = pi/2
static const real
overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
return overflow;
}
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) {
using std::tan;
real t = tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ?
(!(t < 0) ? t : overflow()) :
(!(t >= 0) ? t : -overflow());
}
// Return e * atanh(e * x) for f >= 0, else return
// - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
inline real eatanhe(real x) const {
using std::atan;
return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * 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 &gt; 1, set * Negative \e f gives a prolate ellipsoid. If \e f &gt; 1, set
* flattening to 1/\e f. * flattening to 1/\e f.
* @param[in] k0 central scale factor. * @param[in] k0 central scale factor.
 End of changes. 3 change blocks. 
26 lines changed or deleted 2 lines changed or added


 Rhumb.hpp   Rhumb.hpp 
skipping to change at line 78 skipping to change at line 78
typedef Math::real real; typedef Math::real real;
friend class RhumbLine; friend class RhumbLine;
template <class T> friend class PolygonAreaT; template <class T> friend class PolygonAreaT;
Ellipsoid _ell; Ellipsoid _ell;
bool _exact; bool _exact;
real _c2; real _c2;
static const int tm_maxord = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER; static const int tm_maxord = GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER;
static const int maxpow_ = GEOGRAPHICLIB_RHUMBAREA_ORDER; static const int maxpow_ = GEOGRAPHICLIB_RHUMBAREA_ORDER;
// _R[0] unused // _R[0] unused
real _R[maxpow_ + 1]; real _R[maxpow_ + 1];
static inline real overflow() {
// Overflow value s.t. atan(overflow_) = pi/2
static const real
overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
return overflow;
}
static inline real tano(real x) {
using std::abs; using std::tan;
// Need the volatile declaration for optimized builds on 32-bit cento
s
// with g++ 4.4.7
GEOGRAPHICLIB_VOLATILE real y = 2 * abs(x);
return
y == Math::pi() ? (x < 0 ? - overflow() : overflow()) : tan(x);
}
static inline real gd(real x) static inline real gd(real x)
{ using std::atan; using std::sinh; return atan(sinh(x)); } { using std::atan; using std::sinh; return atan(sinh(x)); }
// Use divided differences to determine (mu2 - mu1) / (psi2 - psi1) // Use divided differences to determine (mu2 - mu1) / (psi2 - psi1)
// accurately // accurately
// //
// Definition: Df(x,y,d) = (f(x) - f(y)) / (x - y) // Definition: Df(x,y,d) = (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)
// https://dx.doi.org/10.1145/334714.334716 // https://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
static inline real Dlog(real x, real y) { static inline real Dlog(real x, real y) {
real t = x - y; real t = x - y;
return t ? 2 * Math::atanh(t / (x + y)) / t : 1 / x; return t ? 2 * Math::atanh(t / (x + y)) / t : 1 / x;
} }
// N.B., x and y are in degrees
static inline real Dtan(real x, real y) { static inline real Dtan(real x, real y) {
real d = x - y, tx = tano(x), ty = tano(y), txy = tx * ty; real d = x - y, tx = Math::tand(x), ty = Math::tand(y), txy = tx * ty
return d ? (2 * txy > -1 ? (1 + txy) * tano(d) : tx - ty) / d : ;
return d ?
(2 * txy > -1 ? (1 + txy) * Math::tand(d) : tx - ty) /
(d * Math::degree()) :
1 + txy; 1 + txy;
} }
static inline real Datan(real x, real y) { static inline real Datan(real x, real y) {
using std::atan; using std::atan;
real d = x - y, xy = x * y; real d = x - y, xy = x * y;
return d ? (2 * xy > -1 ? atan( d / (1 + xy) ) : atan(x) - atan(y)) / d : return d ? (2 * xy > -1 ? atan( d / (1 + xy) ) : atan(x) - atan(y)) / d :
1 / (1 + xy); 1 / (1 + xy);
} }
static inline real Dsin(real x, real y) { static inline real Dsin(real x, real y) {
using std::sin; using std::cos; using std::sin; using std::cos;
skipping to change at line 147 skipping to change at line 136
real d = x - y, real d = x - y,
hx = Math::hypot(real(1), x), hy = Math::hypot(real(1), y); hx = Math::hypot(real(1), x), hy = Math::hypot(real(1), y);
return d ? Math::asinh(x*y > 0 ? d * (x + y) / (x*hy + y*hx) : return d ? Math::asinh(x*y > 0 ? d * (x + y) / (x*hy + y*hx) :
x*hy - y*hx) / d : x*hy - y*hx) / d :
1 / hx; 1 / hx;
} }
static inline real Dgd(real x, real y) { static inline real Dgd(real x, real y) {
using std::sinh; using std::sinh;
return Datan(sinh(x), sinh(y)) * Dsinh(x, y); return Datan(sinh(x), sinh(y)) * Dsinh(x, y);
} }
static inline real Dgdinv(real x, real y) { // N.B., x and y are the tangents of the angles
return Dasinh(tano(x), tano(y)) * Dtan(x, y); static inline real Dgdinv(real x, real y)
} { return Dasinh(x, y) / Datan(x, y); }
// Copied from LambertConformalConic...
// 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
inline real eatanhe(real x) const {
using std::atan;
return _ell._f >= 0 ? _ell._e * Math::atanh(_ell._e * x) :
- _ell._e * atan(_ell._e * x);
}
// Copied from LambertConformalConic... // Copied from LambertConformalConic...
// 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 { inline real Deatanhe(real x, real y) const {
real t = x - y, d = 1 - _ell._e2 * x * y; real t = x - y, d = 1 - _ell._e2 * x * y;
return t ? eatanhe(t / d) / t : _ell._e2 / d; return t ? Math::eatanhe(t / d, _ell._es) / t : _ell._e2 / d;
} }
// (E(x) - E(y)) / (x - y) -- E = incomplete elliptic integral of 2nd k ind // (E(x) - E(y)) / (x - y) -- E = incomplete elliptic integral of 2nd k ind
real DE(real x, real y) const; real DE(real x, real y) const;
// (mux - muy) / (phix - phiy) using elliptic integrals // (mux - muy) / (phix - phiy) using elliptic integrals
real DRectifying(real latx, real laty) const; real DRectifying(real latx, real laty) const;
// (psix - psiy) / (phix - phiy) // (psix - psiy) / (phix - phiy)
real DIsometric(real latx, real laty) const; real DIsometric(real latx, real laty) const;
// (sum(c[j]*sin(2*j*x),j=1..n) - sum(c[j]*sin(2*j*x),j=1..n)) / (x - y ) // (sum(c[j]*sin(2*j*x),j=1..n) - sum(c[j]*sin(2*j*x),j=1..n)) / (x - y )
static real SinCosSeries(bool sinp, static real SinCosSeries(bool sinp,
real x, real y, const real c[], int n); real x, real y, const real c[], int n);
// (mux - muy) / (chix - chiy) using Krueger's series // (mux - muy) / (chix - chiy) using Krueger's series
real DConformalToRectifying(real chix, real chiy) const; real DConformalToRectifying(real chix, real chiy) const;
// (chix - chiy) / (mux - muy) using Krueger's series // (chix - chiy) / (mux - muy) using Krueger's series
real DRectifyingToConformal(real mux, real muy) const; real DRectifyingToConformal(real mux, real muy) const;
// (mux - muy) / (psix - psiy) // (mux - muy) / (psix - psiy)
// N.B., psix and psiy are in degrees
real DIsometricToRectifying(real psix, real psiy) const; real DIsometricToRectifying(real psix, real psiy) const;
// (psix - psiy) / (mux - muy) // (psix - psiy) / (mux - muy)
real DRectifyingToIsometric(real mux, real muy) const; real DRectifyingToIsometric(real mux, real muy) const;
real MeanSinXi(real psi1, real psi2) const; real MeanSinXi(real psi1, real psi2) const;
// The following two functions (with lots of ignored arguments) mimic t he // The following two functions (with lots of ignored arguments) mimic t he
// interface to the corresponding Geodesic function. These are needed by // interface to the corresponding Geodesic function. These are needed by
// PolygonAreaT. // PolygonAreaT.
void GenDirect(real lat1, real lon1, real azi12, void GenDirect(real lat1, real lon1, real azi12,
 End of changes. 6 change blocks. 
29 lines changed or deleted 11 lines changed or added


 TransverseMercator.hpp   TransverseMercator.hpp 
/** /**
* \file TransverseMercator.hpp * \file TransverseMercator.hpp
* \brief Header for GeographicLib::TransverseMercator class * \brief Header for GeographicLib::TransverseMercator class
* *
* Copyright (c) Charles Karney (2008-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP) #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP)
#define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP 1 #define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER) #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER)
skipping to change at line 85 skipping to change at line 85
* <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is a * <a href="TransverseMercatorProj.1.html">TransverseMercatorProj</a> is a
* command-line utility providing access to the functionality of * command-line utility providing access to the functionality of
* TransverseMercator and TransverseMercatorExact. * TransverseMercator and TransverseMercatorExact.
**********************************************************************/ **********************************************************************/
class GEOGRAPHICLIB_EXPORT TransverseMercator { class GEOGRAPHICLIB_EXPORT TransverseMercator {
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 int numit_ = 5; static const int numit_ = 5;
real tol_; real _a, _f, _k0, _e2, _es, _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];
static inline real overflow() {
// Overflow value s.t. atan(overflow_) = pi/2
static const real
overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
return overflow;
}
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) {
using std::tan;
real t = tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ?
(!(t < 0) ? t : overflow()) :
(!(t >= 0) ? t : -overflow());
}
// Return e * atanh(e * x) for f >= 0, else return
// - sqrt(-e2) * atan( sqrt(-e2) * x) for f < 0
inline real eatanhe(real x) const {
using std::atan;
return _f >= 0 ? _e * Math::atanh(_e * x) : - _e * atan(_e * x);
}
real taupf(real tau) const;
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 &gt; 1, set * Negative \e f gives a prolate ellipsoid. If \e f &gt; 1, set
* flattening to 1/\e f. * flattening to 1/\e f.
 End of changes. 3 change blocks. 
27 lines changed or deleted 2 lines changed or added


 TransverseMercatorExact.hpp   TransverseMercatorExact.hpp 
/** /**
* \file TransverseMercatorExact.hpp * \file TransverseMercatorExact.hpp
* \brief Header for GeographicLib::TransverseMercatorExact class * \brief Header for GeographicLib::TransverseMercatorExact class
* *
* Copyright (c) Charles Karney (2008-2014) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licens ed
* under the MIT/X11 License. For more information, see * under the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP) #if !defined(GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP)
#define GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP 1 #define GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP 1
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/EllipticFunction.hpp> #include <GeographicLib/EllipticFunction.hpp>
skipping to change at line 88 skipping to change at line 88
class GEOGRAPHICLIB_EXPORT TransverseMercatorExact { class GEOGRAPHICLIB_EXPORT TransverseMercatorExact {
private: private:
typedef Math::real real; typedef Math::real real;
static const int numit_ = 10; static const int numit_ = 10;
real tol_, tol1_, tol2_, taytol_; real tol_, tol1_, tol2_, taytol_;
real _a, _f, _k0, _mu, _mv, _e; real _a, _f, _k0, _mu, _mv, _e;
bool _extendp; bool _extendp;
EllipticFunction _Eu, _Ev; EllipticFunction _Eu, _Ev;
static inline real overflow() { static inline real overflow() {
// Overflow value s.t. atan(overflow_) = pi/2 // Overflow value s.t. atan(overflow_) = pi/2
static const real static const real
overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon()); overflow = 1 / Math::sq(std::numeric_limits<real>::epsilon());
return overflow; return overflow;
} }
// tan(x) for x in [-pi/2, pi/2] ensuring that the sign is right
static inline real tanx(real x) {
using std::tan;
real t = tan(x);
// Write the tests this way to ensure that tanx(NaN()) is NaN()
return x >= 0 ?
(!(t < 0) ? t : overflow()) :
(!(t >= 0) ? t : -overflow());
}
real taup(real tau) const;
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; 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; real& du, real& dv) const;
bool zetainv0(real psi, real lam, real& u, real& v) const; bool zetainv0(real psi, real lam, real& u, real& v) const;
 End of changes. 3 change blocks. 
14 lines changed or deleted 2 lines changed or added


 UTMUPS.hpp   UTMUPS.hpp 
skipping to change at line 254 skipping to change at line 254
* The accuracy of the conversion is about 5nm. * The accuracy of the conversion is about 5nm.
* *
* UTM eastings are allowed to be in the range [0km, 1000km], northings are * UTM eastings are allowed to be in the range [0km, 1000km], northings are
* allowed to be in in [0km, 9600km] for the northern hemisphere and in * allowed to be in in [0km, 9600km] for the northern hemisphere and in
* [900km, 10000km] for the southern hemisphere. However UTM northings * [900km, 10000km] for the southern hemisphere. However UTM northings
* can be continued across the equator. So the actual limits on the * can be continued across the equator. So the actual limits on the
* northings are [-9100km, 9600km] for the "northern" hemisphere and * northings are [-9100km, 9600km] for the "northern" hemisphere and
* [900km, 19600km] for the "southern" hemisphere. * [900km, 19600km] for the "southern" hemisphere.
* *
* UPS eastings and northings are allowed to be in the range [1200km, * UPS eastings and northings are allowed to be in the range [1200km,
* 2800km] in the northern hemisphere and in [700km, 3100km] in the * 2800km] in the northern hemisphere and in [700km, 3300km] in the
* southern hemisphere. * southern hemisphere.
* *
* These ranges are 100km larger than allowed for the conversions to MG RS. * These ranges are 100km larger than allowed for the conversions to MG RS.
* (100km is the maximum extra padding consistent with eastings remaini ng * (100km is the maximum extra padding consistent with eastings remaini ng
* non-negative.) This allows generous overlaps between zones and UTM and * non-negative.) This allows generous overlaps between zones and UTM and
* UPS. If \e mgrslimits = true, then all the ranges are shrunk by 100 km * UPS. If \e mgrslimits = true, then all the ranges are shrunk by 100 km
* so that they agree with the stricter MGRS ranges. No checks are * so that they agree with the stricter MGRS ranges. No checks are
* performed besides these (e.g., to limit the distance outside the * performed besides these (e.g., to limit the distance outside the
* standard zone boundaries). * standard zone boundaries).
********************************************************************** / ********************************************************************** /
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 Utility.hpp   Utility.hpp 
skipping to change at line 299 skipping to change at line 299
* *
* If \e p &ge; 0, then the number fixed format is used with p bits of * If \e p &ge; 0, then the number fixed format is used with p bits of
* precision. With p < 0, there is no manipulation of the format. Thi s is * precision. With p < 0, there is no manipulation of the format. Thi s is
* an overload of str<T> which deals with inf and nan. * an overload of str<T> which deals with inf and nan.
********************************************************************** / ********************************************************************** /
static std::string str(Math::real x, int p = -1) { static std::string str(Math::real x, int p = -1) {
if (!Math::isfinite(x)) if (!Math::isfinite(x))
return x < 0 ? std::string("-inf") : return x < 0 ? std::string("-inf") :
(x > 0 ? std::string("inf") : std::string("nan")); (x > 0 ? std::string("inf") : std::string("nan"));
std::ostringstream s; std::ostringstream s;
#if GEOGRAPHICLIB_PRECISION == 4
// boost-quadmath treats precision == 0 as "use as many digits as
// necessary", so...
using std::floor;
if (p == 0) {
long long ix = (long long)(floor(x + Math::real(0.5)));
// Implement the "round ties to even" rule
if (Math::real(ix) == x + Math::real(0.5) && (ix % 2) == 1)
--ix;
s << ix;
return s.str();
}
#endif
if (p >= 0) s << std::fixed << std::setprecision(p); if (p >= 0) s << std::fixed << std::setprecision(p);
s << x; return s.str(); s << x; return s.str();
} }
/** /**
* Convert a string to an object of type T. * Convert a string to an object of type T.
* *
* @tparam T the type of the return value. * @tparam T the type of the return value.
* @param[in] s the string to be converted. * @param[in] s the string to be converted.
* @exception GeographicErr is \e s is not readable as a T. * @exception GeographicErr is \e s is not readable as a T.
skipping to change at line 419 skipping to change at line 432
********************************************************************** / ********************************************************************** /
template<typename ExtT, typename IntT, bool bigendp> template<typename ExtT, typename IntT, bool bigendp>
static inline void readarray(std::istream& str, static inline void readarray(std::istream& str,
IntT array[], size_t num) { IntT array[], size_t num) {
#if GEOGRAPHICLIB_PRECISION < 4 #if GEOGRAPHICLIB_PRECISION < 4
if (sizeof(IntT) == sizeof(ExtT) && if (sizeof(IntT) == sizeof(ExtT) &&
std::numeric_limits<IntT>::is_integer == std::numeric_limits<IntT>::is_integer ==
std::numeric_limits<ExtT>::is_integer) std::numeric_limits<ExtT>::is_integer)
{ {
// Data is compatible (aside from the issue of endian-ness). // Data is compatible (aside from the issue of endian-ness).
str.read(reinterpret_cast<char *>(array), num * sizeof(ExtT)); str.read(reinterpret_cast<char*>(array), num * sizeof(ExtT));
if (!str.good()) if (!str.good())
throw GeographicErr("Failure reading data"); throw GeographicErr("Failure reading data");
if (bigendp != Math::bigendian) { // endian mismatch -> swap byte s if (bigendp != Math::bigendian) { // endian mismatch -> swap byte s
for (size_t i = num; i--;) for (size_t i = num; i--;)
array[i] = Math::swab<IntT>(array[i]); array[i] = Math::swab<IntT>(array[i]);
} }
} }
else else
#endif #endif
{ {
const int bufsize = 1024; // read this many values at a time const int bufsize = 1024; // read this many values at a time
ExtT buffer[bufsize]; // temporary buffer ExtT buffer[bufsize]; // temporary buffer
int k = int(num); // data values left to read int k = int(num); // data values left to read
int i = 0; // index into output array int i = 0; // index into output array
while (k) { while (k) {
int n = (std::min)(k, bufsize); int n = (std::min)(k, bufsize);
str.read(reinterpret_cast<char *>(buffer), n * sizeof(ExtT)); str.read(reinterpret_cast<char*>(buffer), n * sizeof(ExtT));
if (!str.good()) if (!str.good())
throw GeographicErr("Failure reading data"); throw GeographicErr("Failure reading data");
for (int j = 0; j < n; ++j) for (int j = 0; j < n; ++j)
// fix endian-ness and cast to IntT // fix endian-ness and cast to IntT
array[i++] = IntT(bigendp == Math::bigendian ? buffer[j] : array[i++] = IntT(bigendp == Math::bigendian ? buffer[j] :
Math::swab<ExtT>(buffer[j])); Math::swab<ExtT>(buffer[j]));
k -= n; k -= n;
} }
} }
return; return;
skipping to change at line 491 skipping to change at line 504
template<typename ExtT, typename IntT, bool bigendp> template<typename ExtT, typename IntT, bool bigendp>
static inline void writearray(std::ostream& str, static inline void writearray(std::ostream& str,
const IntT array[], size_t num) { const IntT array[], size_t num) {
#if GEOGRAPHICLIB_PRECISION < 4 #if GEOGRAPHICLIB_PRECISION < 4
if (sizeof(IntT) == sizeof(ExtT) && if (sizeof(IntT) == sizeof(ExtT) &&
std::numeric_limits<IntT>::is_integer == std::numeric_limits<IntT>::is_integer ==
std::numeric_limits<ExtT>::is_integer && std::numeric_limits<ExtT>::is_integer &&
bigendp == Math::bigendian) bigendp == Math::bigendian)
{ {
// Data is compatible (including endian-ness). // Data is compatible (including endian-ness).
str.write(reinterpret_cast<const char *>(array), num * sizeof(Ext T)); str.write(reinterpret_cast<const char*>(array), num * sizeof(ExtT ));
if (!str.good()) if (!str.good())
throw GeographicErr("Failure writing data"); throw GeographicErr("Failure writing data");
} }
else else
#endif #endif
{ {
const int bufsize = 1024; // write this many values at a time const int bufsize = 1024; // write this many values at a time
ExtT buffer[bufsize]; // temporary buffer ExtT buffer[bufsize]; // temporary buffer
int k = int(num); // data values left to write int k = int(num); // data values left to write
int i = 0; // index into output array int i = 0; // index into output array
while (k) { while (k) {
int n = (std::min)(k, bufsize); int n = (std::min)(k, bufsize);
for (int j = 0; j < n; ++j) for (int j = 0; j < n; ++j)
// cast to ExtT and fix endian-ness // cast to ExtT and fix endian-ness
buffer[j] = bigendp == Math::bigendian ? ExtT(array[i++]) : buffer[j] = bigendp == Math::bigendian ? ExtT(array[i++]) :
Math::swab<ExtT>(ExtT(array[i++])); Math::swab<ExtT>(ExtT(array[i++]));
str.write(reinterpret_cast<const char *>(buffer), n * sizeof(Ex tT)); str.write(reinterpret_cast<const char*>(buffer), n * sizeof(Ext T));
if (!str.good()) if (!str.good())
throw GeographicErr("Failure writing data"); throw GeographicErr("Failure writing data");
k -= n; k -= n;
} }
} }
return; return;
} }
/** /**
* Write data in an array of type IntT as type ExtT to a binary stream. * Write data in an array of type IntT as type ExtT to a binary stream.
 End of changes. 5 change blocks. 
4 lines changed or deleted 17 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/