Accumulator.hpp   Accumulator.hpp 
/** /**
* \file Accumulator.hpp * \file Accumulator.hpp
* \brief Header for GeographicLib::Accumulator class * \brief Header for GeographicLib::Accumulator class
* *
* Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2010-2011) <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_ACCUMULATOR_HPP) #if !defined(GEOGRAPHICLIB_ACCUMULATOR_HPP)
#define GEOGRAPHICLIB_ACCUMULATOR_HPP \ #define GEOGRAPHICLIB_ACCUMULATOR_HPP 1
"$Id: 7a95b0ebcc20534577ea6fcbd3d145e498dd5049 $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief An accumulator for sums * \brief An accumulator for sums
* *
* This allow many numbers of floating point type \e T to be added togeth er * This allow many numbers of floating point type \e T to be added togeth er
* with twice the normal precision. Thus if \e T is double, the effectiv e * with twice the normal precision. Thus if \e T is double, the effectiv e
* precision of the sum is 106 bits or about 32 decimal places. The core * precision of the sum is 106 bits or about 32 decimal places. The core
* idea is the error free transformation of a sum, D. E. Knuth, TAOCP, Vo l 2, * idea is the error free transformation of a sum, D. E. Knuth, TAOCP, Vo l 2,
* 4.2.2, Theorem B. * 4.2.2, Theorem B.
* *
* The implementation follows J. R. Shewchuk, * The implementation follows J. R. Shewchuk,
* <a href="http://dx.doi.org/10.1007/PL00009321"> Adaptive Precision * <a href="http://dx.doi.org/10.1007/PL00009321"> Adaptive Precision
* Floating-Point Arithmetic and Fast Robust Geometric Predicates</a>, * Floating-Point Arithmetic and Fast Robust Geometric Predicates</a>,
* Discrete & Computational Geometry 18(3) 305-363 (1997). * Discrete & Computational Geometry 18(3) 305&ndash;363 (1997).
* *
* Approximate timings (summing a vector<double>) * Approximate timings (summing a vector<double>)
* - double: 2ns * - double: 2ns
* - Accumulator<double>: 23ns * - Accumulator<double>: 23ns
* *
* In the documentation of the member functions, \e sum stands for the va lue * In the documentation of the member functions, \e sum stands for the va lue
* currently held in the accumulator. * currently held in the accumulator.
* *
* Example of use: * Example of use:
* \include example-Accumulator.cpp * \include example-Accumulator.cpp
skipping to change at line 153 skipping to change at line 152
********************************************************************** / ********************************************************************** /
Accumulator& operator+=(T y) throw() { Add(y); return *this; } Accumulator& operator+=(T y) throw() { 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) throw() { 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 * \e T is exactly representable as a \e T (i * integers such that \e n &times; \e T is exactly representable as a \
.e., e T
* +/- powers of two). Use \e n = -1 to negate \e sum. * (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) throw() { _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 throw() { return _s == y; }
/** /**
* Test inequality of an Accumulator with a number. * Test inequality of an Accumulator with a number.
 End of changes. 4 change blocks. 
7 lines changed or deleted 7 lines changed or added


 AlbersEqualArea.hpp   AlbersEqualArea.hpp 
/** /**
* \file AlbersEqualArea.hpp * \file AlbersEqualArea.hpp
* \brief Header for GeographicLib::AlbersEqualArea class * \brief Header for GeographicLib::AlbersEqualArea class
* *
* Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2010-2012) <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_ALBERSEQUALAREA_HPP) #if !defined(GEOGRAPHICLIB_ALBERSEQUALAREA_HPP)
#define GEOGRAPHICLIB_ALBERSEQUALAREA_HPP \ #define GEOGRAPHICLIB_ALBERSEQUALAREA_HPP 1
"$Id: ac57b23974e41848724eba72e55887112d67c85a $"
#include <algorithm> #include <algorithm>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Albers equal area conic projection * \brief Albers equal area conic projection
* *
* Implementation taken from the report, * Implementation taken from the report,
skipping to change at line 47 skipping to change at line 46
* two standard parallels is converted into a single standard parallel, t he * two standard parallels is converted into a single standard parallel, t he
* latitude of minimum azimuthal scale, with an azimuthal scale specified on * latitude of minimum azimuthal scale, with an azimuthal scale specified on
* this parallel. This latitude is also used as the latitude of origin w hich * this parallel. This latitude is also used as the latitude of origin w hich
* is returned by AlbersEqualArea::OriginLatitude. The azimuthal scale o n * is returned by AlbersEqualArea::OriginLatitude. The azimuthal scale o n
* the latitude of origin is given by AlbersEqualArea::CentralScale. The * the latitude of origin is given by AlbersEqualArea::CentralScale. The
* case with two standard parallels at opposite poles is singular and is * case with two standard parallels at opposite poles is singular and is
* disallowed. The central meridian (which is a trivial shift of the * disallowed. The central meridian (which is a trivial shift of the
* longitude) is specified as the \e lon0 argument of the * longitude) is specified as the \e lon0 argument of the
* AlbersEqualArea::Forward and AlbersEqualArea::Reverse functions. * AlbersEqualArea::Forward and AlbersEqualArea::Reverse functions.
* AlbersEqualArea::Forward and AlbersEqualArea::Reverse also return the * AlbersEqualArea::Forward and AlbersEqualArea::Reverse also return the
* meridian convergence, \e gamma, and azimuthal scale, \e k. A small sq uare * meridian convergence, &gamma;, and azimuthal scale, \e k. A small squ are
* aligned with the cardinal directions is projected to a rectangle with * aligned with the cardinal directions is projected to a rectangle with
* dimensions \e k (in the E-W direction) and 1/\e k (in the N-S directio n). * dimensions \e k (in the E-W direction) and 1/\e k (in the N-S directio n).
* The E-W sides of the rectangle are oriented \e gamma degrees * The E-W sides of the rectangle are oriented &gamma; degrees
* counter-clockwise from the \e x axis. There is no provision in this c lass * counter-clockwise from the \e x axis. There is no provision in this c lass
* for specifying a false easting or false northing or a different latitu de * for specifying a false easting or false northing or a different latitu de
* of origin. * of origin.
* *
* Example of use: * Example of use:
* \include example-AlbersEqualArea.cpp * \include example-AlbersEqualArea.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.
skipping to change at line 134 skipping to change at line 133
/** /**
* 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.
* @param[in] k0 azimuthal scale on the standard parallel. * @param[in] k0 azimuthal scale on the standard parallel.
* * @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k0 i
* An exception is thrown if \e a or \e k0 is not positive or if \e std s
lat * not positive.
* is not in the range [-90, 90]. * @exception GeographicErr if \e stdlat is not in [&minus;90&deg;,
* 90&deg;].
********************************************************************** / ********************************************************************** /
AlbersEqualArea(real a, real f, real stdlat, real k0); AlbersEqualArea(real a, real f, real stdlat, real k0);
/** /**
* Constructor with two standard parallels. * Constructor with two standard parallels.
* *
* @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] stdlat1 first standard parallel (degrees). * @param[in] stdlat1 first standard parallel (degrees).
* @param[in] stdlat2 second standard parallel (degrees). * @param[in] stdlat2 second standard parallel (degrees).
* @param[in] k1 azimuthal scale on the standard parallels. * @param[in] k1 azimuthal scale on the standard parallels.
* * @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k1 i
* An exception is thrown if \e a or \e k0 is not positive or if \e std s
lat1 * not positive.
* or \e stdlat2 is not in the range [-90, 90]. In addition, an except * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
ion * [&minus;90&deg;, 90&deg;], or if \e stdlat1 and \e stdlat2 are
* is thrown if \e stdlat1 and \e stdlat2 are opposite poles. * opposite poles.
********************************************************************** / ********************************************************************** /
AlbersEqualArea(real a, real f, real stdlat1, real stdlat2, real k1); AlbersEqualArea(real a, real f, real stdlat1, real stdlat2, real k1);
/** /**
* Constructor with two standard parallels specified by sines and cosin es. * Constructor with two standard parallels specified by sines and cosin es.
* *
* @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] sinlat1 sine of first standard parallel. * @param[in] sinlat1 sine of first standard parallel.
* @param[in] coslat1 cosine of first standard parallel. * @param[in] coslat1 cosine of first standard parallel.
* @param[in] sinlat2 sine of second standard parallel. * @param[in] sinlat2 sine of second standard parallel.
* @param[in] coslat2 cosine of second standard parallel. * @param[in] coslat2 cosine of second standard parallel.
* @param[in] k1 azimuthal scale on the standard parallels. * @param[in] k1 azimuthal scale on the standard parallels.
* @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k1 i
s
* not positive.
* @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
* [&minus;90&deg;, 90&deg;], or if \e stdlat1 and \e stdlat2 are
* opposite poles.
* *
* This allows parallels close to the poles to be specified accurately. * This allows parallels close to the poles to be specified accurately.
* This routine computes the latitude of origin and the azimuthal scale at * This routine computes the latitude of origin and the azimuthal scale at
* this latitude. If \e dlat = abs(\e lat2 - \e lat1) <= 160<sup>o</su * this latitude. If \e dlat = abs(\e lat2 &minus; \e lat1) &le; 160&d
p>, eg;,
* then the error in the latitude of origin is less than * then the error in the latitude of origin is less than 4.5 &times;
* 4.5e-14<sup>o</sup>. * 10<sup>&minus;14</sup>d;.
********************************************************************** / ********************************************************************** /
AlbersEqualArea(real a, real f, AlbersEqualArea(real a, real f,
real sinlat1, real coslat1, real sinlat1, real coslat1,
real sinlat2, real coslat2, real sinlat2, real coslat2,
real k1); real k1);
/** /**
* Set the azimuthal scale for the projection. * Set the azimuthal scale for the projection.
* *
* @param[in] lat (degrees). * @param[in] lat (degrees).
* @param[in] k azimuthal scale at latitude \e lat (default 1). * @param[in] k azimuthal scale at latitude \e lat (default 1).
* @exception GeographicLib \e k is not positive.
* @exception GeographicErr if \e lat is not in (&minus;90&deg;,
* 90&deg;).
* *
* This allows a "latitude of conformality" to be specified. An except * This allows a "latitude of conformality" to be specified.
ion
* is thrown if \e k is not positive or if \e lat is not in the range (
-90,
* 90).
********************************************************************** / ********************************************************************** /
void SetScale(real lat, real k = real(1)); void SetScale(real lat, real k = real(1));
/** /**
* Forward projection, from geographic to Lambert conformal conic. * Forward projection, from geographic to Lambert conformal conic.
* *
* @param[in] lon0 central meridian longitude (degrees). * @param[in] lon0 central meridian longitude (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).
* @param[out] gamma meridian convergence at point (degrees). * @param[out] gamma meridian convergence at point (degrees).
* @param[out] k azimuthal scale of projection at point; the radial * @param[out] k azimuthal scale of projection at point; the radial
* 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
* [-90, 90]; \e lon and \e lon0 should be in the range [-180, 360]. T * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
he * range [&minus;540&deg;, 540&deg;). The values of \e x and \e y
* values of \e x and \e y returned for points which project to infinit * returned for points which project to infinity (i.e., one or both of
y the
* (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 throw();
/** /**
* 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).
* @param[out] k azimuthal scale of projection at point; the radial * @param[out] k azimuthal scale of projection at point; the radial
* 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. \e lon0 should be in the range * false easting or northing is added. \e lon0 should be in the range
* [-180, 360]. The value of \e lon returned is in the range [-180, 18 * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
0). * the range [&minus;180&deg;, 180&deg;). The value of \e lat
* The value of \e lat returned is in the range [-90,90]. If the input * returned is in the range [&minus;90&deg;, 90&deg;]. If the
* point is outside the legal projected space the nearest pole is retur * input point is outside the legal projected space the nearest pole is
ned. * 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 throw();
/** /**
* 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 throw() {
skipping to change at line 303 skipping to change at line 313
/** /**
* 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;
/** /**
* A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e
* stdlat = 90<sup>o</sup>;, and \e k0 = 1. This degenerates to the * stdlat = 90°;, and \e k0 = 1. This degenerates to the
* Lambert azimuthal equal area projection. * Lambert azimuthal equal area projection.
********************************************************************** / ********************************************************************** /
static const AlbersEqualArea AzimuthalEqualAreaNorth; static const AlbersEqualArea AzimuthalEqualAreaNorth;
/** /**
* A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e * A global instantiation of AlbersEqualArea with the WGS84 ellipsoid, \e
* stdlat = -90<sup>o</sup>;, and \e k0 = 1. This degenerates to the * stdlat = &minus;90&deg;, and \e k0 = 1. This degenerates to the
* Lambert azimuthal equal area projection. * Lambert azimuthal equal area projection.
********************************************************************** / ********************************************************************** /
static const AlbersEqualArea AzimuthalEqualAreaSouth; static const AlbersEqualArea AzimuthalEqualAreaSouth;
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_ALBERSEQUALAREA_HPP #endif // GEOGRAPHICLIB_ALBERSEQUALAREA_HPP
 End of changes. 14 change blocks. 
36 lines changed or deleted 41 lines changed or added


 AzimuthalEquidistant.hpp   AzimuthalEquidistant.hpp 
/** /**
* \file AzimuthalEquidistant.hpp * \file AzimuthalEquidistant.hpp
* \brief Header for GeographicLib::AzimuthalEquidistant class * \brief Header for GeographicLib::AzimuthalEquidistant class
* *
* Copyright (c) Charles Karney (2009-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2011) <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_AZIMUTHALEQUIDISTANT_HPP) #if !defined(GEOGRAPHICLIB_AZIMUTHALEQUIDISTANT_HPP)
#define GEOGRAPHICLIB_AZIMUTHALEQUIDISTANT_HPP \ #define GEOGRAPHICLIB_AZIMUTHALEQUIDISTANT_HPP 1
"$Id: 585a3b7b28ec2cb070d8ba5a472fea83c9a21f7f $"
#include <GeographicLib/Geodesic.hpp> #include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Azimuthal equidistant projection * \brief Azimuthal equidistant projection
* *
* Azimuthal equidistant projection centered at an arbitrary position on the * Azimuthal equidistant projection centered at an arbitrary position on the
skipping to change at line 71 skipping to change at line 70
* *
* @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).
* @param[out] azi azimuth of geodesic at point (degrees). * @param[out] azi azimuth of geodesic at point (degrees).
* @param[out] rk reciprocal of azimuthal scale at point. * @param[out] rk reciprocal of azimuthal scale at point.
* *
* \e lat0 and \e lat should be in the range [-90, 90] and \e lon0 and * \e lat0 and \e lat should be in the range [&minus;90&deg;,
\e * 90&deg;] and \e lon0 and \e lon should be in the range
* lon should be in the range [-180, 360]. The scale of the projection * [&minus;540&deg;, 540&deg;). The scale of the projection is 1
is * in the "radial" direction, \e azi clockwise from true north, and is
* 1 in the "radial" direction, \e azi clockwise from true north, and i 1/\e
s * rk in the direction perpendicular to this. A call to Forward follow
* 1/\e rk in the direction perpendicular to this. A call to Forward ed
* followed by a call to Reverse will return the original (\e lat, \e l * by a call to Reverse will return the original (\e lat, \e lon) (to
on) * within roundoff).
* (to 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 throw();
/** /**
* 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).
* @param[out] azi azimuth of geodesic at point (degrees). * @param[out] azi azimuth of geodesic at point (degrees).
* @param[out] rk reciprocal of azimuthal scale at point. * @param[out] rk reciprocal of azimuthal scale at point.
* *
* \e lat0 should be in the range [-90, 90] and \e lon0 should be in th * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
e * lon0 should be in the range [&minus;540&deg;, 540&deg;). \e lat
* range [-180, 360]. \e lat will be in the range [-90, 90] and \e lon * will be in the range [&minus;90&deg;, 90&deg;] and \e lon will
* will be in the range [-180, 180). The scale of the projection is 1 * be in the range [&minus;180&deg;, 180&deg;). The scale of the
in * projection is 1 in the "radial" direction, \e azi clockwise from tru
* the "radial" direction, \e azi clockwise from true north, and is 1/\ e
e rk * north, and is 1/\e rk in the direction perpendicular to this. A cal
* in the direction perpendicular to this. A call to Reverse followed l to
by a * Reverse followed by a call to Forward will return the original (\e x
* call to Forward will return the original (\e x, \e y) (to roundoff) , \e
only * y) (to roundoff) only if the geodesic to (\e x, \e y) is a shortest
* 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 throw();
/** /**
* 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 throw() {
real azi, rk; real azi, rk;
 End of changes. 3 change blocks. 
24 lines changed or deleted 22 lines changed or added


 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-2011) <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 \ #define GEOGRAPHICLIB_CASSINISOLDNER_HPP 1
"$Id: 0faa2e3045fa02878e47c4c76da781062a0bdf54 $"
#include <GeographicLib/Geodesic.hpp> #include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicLine.hpp> #include <GeographicLib/GeodesicLine.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Cassini-Soldner projection * \brief Cassini-Soldner projection
* *
* Cassini-Soldner projection centered at an arbitrary position, \e lat0, \e * Cassini-Soldner projection centered at an arbitrary position, \e lat0, \e
* lon0, on the ellipsoid. This projection is a transverse cylindrical * lon0, on the ellipsoid. This projection is a transverse cylindrical
* equidistant projection. The projection from (\e lat, \e lon) to easti ng * equidistant projection. The projection from (\e lat, \e lon) to easti ng
* and northing (\e x, \e y) is defined by geodesics as follows. Go nort h * and northing (\e x, \e y) is defined by geodesics as follows. Go nort h
* along a geodesic a distance \e y from the central point; then turn * along a geodesic a distance \e y from the central point; then turn
* clockwise 90<sup>o</sup>; and go a distance \e x along a geodesic. * clockwise 90°; and go a distance \e x along a geodesic.
* (Although the initial heading is north, this changes to south if the p ole * (Although the initial heading is north, this changes to south if the p ole
* is crossed.) This procedure uniquely defines the reverse projection. The * is crossed.) This procedure uniquely defines the reverse projection. The
* forward projection is constructed as follows. Find the point (\e lat1 , \e * forward projection is constructed as follows. Find the point (\e lat1 , \e
* lon1) on the meridian closest to (\e lat, \e lon). Here we consider t he * lon1) on the meridian closest to (\e lat, \e lon). Here we consider t he
* full meridian so that \e lon1 may be either \e lon0 or \e lon0 + * full meridian so that \e lon1 may be either \e lon0 or \e lon0 +
* 180<sup>o</sup>. \e x is the geodesic distance from (\e lat1, \e lon1 ) to * 180°. \e x is the geodesic distance from (\e lat1, \e lon1) to
* (\e lat, \e lon), appropriately signed according to which side of the * (\e lat, \e lon), appropriately signed according to which side of the
* central meridian (\e lat, \e lon) lies. \e y is the shortest distance * central meridian (\e lat, \e lon) lies. \e y is the shortest distance
* along the meridian from (\e lat0, \e lon0) to (\e lat1, \e lon1), agai n, * along the meridian from (\e lat0, \e lon0) to (\e lat1, \e lon1), agai n,
* appropriately signed according to the initial heading. [Note that, in the * appropriately signed according to the initial heading. [Note that, in the
* case of prolate ellipsoids, the shortest meridional path from (\e lat0 , \e * case of prolate ellipsoids, the shortest meridional path from (\e lat0 , \e
* lon0) to (\e lat1, \e lon1) may not be the shortest path.] This proce dure * lon0) to (\e lat1, \e lon1) may not be the shortest path.] This proce dure
* uniquely defines the forward projection except for a small class of po ints * uniquely defines the forward projection except for a small class of po ints
* for which there may be two equally short routes for either leg of the * for which there may be two equally short routes for either leg of the
* path. * path.
* *
skipping to change at line 81 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 AngNormalize(real x) throw() {
// Place angle in [-180, 180). Assumes x is in [-540, 540).
return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x);
}
static inline real AngRound(real x) throw() { static inline real AngRound(real x) throw() {
// 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 = real(0.0625); // 1/16 const real z = real(0.0625); // 1/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;
skipping to change at line 124 skipping to change at line 119
: _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 [-90, 90] and \e lon0 should be in th * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
e * lon0 should be in the range [&minus;540&deg;, 540&deg;).
* range [-180, 360].
********************************************************************** / ********************************************************************** /
CassiniSoldner(real lat0, real lon0, CassiniSoldner(real lat0, real lon0,
const Geodesic& earth = Geodesic::WGS84) throw() const Geodesic& earth = Geodesic::WGS84) throw()
: _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 [-90, 90] and \e lon0 should be in th * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
e * lon0 should be in the range [&minus;540&deg;, 540&deg;).
* range [-180, 360].
********************************************************************** / ********************************************************************** /
void Reset(real lat0, real lon0) throw(); void Reset(real lat0, real lon0) throw();
/** /**
* 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 [-90, 90] and \e lon should be in the * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
* range [-180, 360]. A call to Forward followed by a call to Reverse * lon should be in the range [&minus;540&deg;, 540&deg;). A call
will * to Forward followed by a call to Reverse will return the original (\
* return the original (\e lat, \e lon) (to within roundoff). The rout e
ine * lat, \e lon) (to within roundoff). The routine does nothing if the
* 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 throw();
/** /**
* 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).
 End of changes. 7 change blocks. 
20 lines changed or deleted 13 lines changed or added


 CircularEngine.hpp   CircularEngine.hpp 
/** /**
* \file CircularEngine.hpp * \file CircularEngine.hpp
* \brief Header for GeographicLib::CircularEngine class * \brief Header for GeographicLib::CircularEngine class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_CIRCULARENGINE_HPP) #if !defined(GEOGRAPHICLIB_CIRCULARENGINE_HPP)
#define GEOGRAPHICLIB_CIRCULARENGINE_HPP \ #define GEOGRAPHICLIB_CIRCULARENGINE_HPP 1
"$Id: 1e012847f5ecd4d38f3cfdae7ef3badebb433da5 $"
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/SphericalEngine.hpp> #include <GeographicLib/SphericalEngine.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs vector // Squelch warnings about dll vs vector
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Spherical harmonic sums for a circle * \brief Spherical harmonic sums for a circle
* *
* The class is a companion to SphericalEngine. If the results of a * The class is a companion to SphericalEngine. If the results of a
* spherical harmonic sum are needed for several points on a circle of * spherical harmonic sum are needed for several points on a circle of
* constant latitude \e lat and height \e h, then SphericalEngine::Circle can * constant latitude \e lat and height \e h, then SphericalEngine::Circle can
skipping to change at line 47 skipping to change at line 46
* maximum degree). * maximum degree).
* *
* CircularEngine is tightly linked to the internals of SphericalEngine. For * CircularEngine is tightly linked to the internals of SphericalEngine. For
* that reason, the constructor for this class is private. Use * that reason, the constructor for this class is private. Use
* SphericalHarmonic::Circle, SphericalHarmonic1::Circle, and * SphericalHarmonic::Circle, SphericalHarmonic1::Circle, and
* SphericalHarmonic2::Circle to create instances of this class. * SphericalHarmonic2::Circle to create instances of this class.
* *
* CircularEngine stores the coefficients needed to allow the summation o ver * CircularEngine stores the coefficients needed to allow the summation o ver
* order to be performed in 2 or 6 vectors of length \e M + 1 (depending on * order to be performed in 2 or 6 vectors of length \e M + 1 (depending on
* whether gradients are to be calculated). For this reason the construc tor * whether gradients are to be calculated). For this reason the construc tor
* may throw a bad_alloc exception. * may throw a std::bad_alloc exception.
* *
* Example of use: * Example of use:
* \include example-CircularEngine.cpp * \include example-CircularEngine.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHIC_EXPORT CircularEngine { class GEOGRAPHIC_EXPORT CircularEngine {
private: private:
typedef Math::real real; typedef Math::real real;
enum normalization { enum normalization {
FULL = SphericalEngine::FULL, FULL = SphericalEngine::FULL,
skipping to change at line 202 skipping to change at line 201
real& gradx, real& grady, real& gradz) const thro w() { real& gradx, real& grady, real& gradz) const thro w() {
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)
#endif #endif
#endif // GEOGRAPHICLIB_CIRCULARENGINE_HPP #endif // GEOGRAPHICLIB_CIRCULARENGINE_HPP
 End of changes. 4 change blocks. 
6 lines changed or deleted 5 lines changed or added


 Config.h   Config.h 
#define HAVE_LONG_DOUBLE 1 #define HAVE_LONG_DOUBLE 1
#define GEOGRAPHICLIB_VERSION_STRING "1.22" #define GEOGRAPHICLIB_VERSION_STRING "1.23"
/* # undef WORDS_BIGENDIAN */ /* # undef WORDS_BIGENDIAN */
 End of changes. 1 change blocks. 
1 lines changed or deleted 1 lines changed or added


 Constants.hpp   Constants.hpp 
/** /**
* \file Constants.hpp * \file Constants.hpp
* \brief Header for GeographicLib::Constants class * \brief Header for GeographicLib::Constants class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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_CONSTANTS_HPP) #if !defined(GEOGRAPHICLIB_CONSTANTS_HPP)
#define GEOGRAPHICLIB_CONSTANTS_HPP \ #define GEOGRAPHICLIB_CONSTANTS_HPP 1
"$Id: 9d779f7a1f6939407128e2dcb925b1dc96f74f69 $"
#include <GeographicLib/Config.h> #include <GeographicLib/Config.h>
/** /**
* A compile-time assert. Use C++11 static_assert, if available. * A compile-time assert. Use C++11 static_assert, if available.
**********************************************************************/ **********************************************************************/
#if !defined(STATIC_ASSERT) #if !defined(STATIC_ASSERT)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) # if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define STATIC_ASSERT static_assert # define STATIC_ASSERT static_assert
# elif defined(_MSC_VER) && _MSC_VER >= 1600 # elif defined(_MSC_VER) && _MSC_VER >= 1600
# define STATIC_ASSERT static_assert # define STATIC_ASSERT static_assert
# else # else
# define STATIC_ASSERT(cond,reason) \ # define STATIC_ASSERT(cond,reason) \
{ enum{ STATIC_ASSERT_ENUM = 1/int(cond) }; } { enum{ STATIC_ASSERT_ENUM = 1/int(cond) }; }
# endif # endif
#endif #endif
#if defined(__GNUC__)
// Suppress "defined but not used" warnings
# define RCSID_DECL(x) namespace \
{ char VAR_ ## x [] __attribute__((used)) = x; }
#else
/**
* Insertion of RCS Id strings into the object file.
**********************************************************************/
# define RCSID_DECL(x) namespace { char VAR_ ## x [] = x; }
#endif
#if defined(_WIN32) && defined(GEOGRAPHIC_SHARED_LIB) && GEOGRAPHIC_SHARED_ LIB #if defined(_WIN32) && defined(GEOGRAPHIC_SHARED_LIB) && GEOGRAPHIC_SHARED_ LIB
# if defined(Geographic_EXPORTS) # if defined(Geographic_EXPORTS)
# define GEOGRAPHIC_EXPORT __declspec(dllexport) # define GEOGRAPHIC_EXPORT __declspec(dllexport)
# else # else
# define GEOGRAPHIC_EXPORT __declspec(dllimport) # define GEOGRAPHIC_EXPORT __declspec(dllimport)
# endif # endif
#else #else
# define GEOGRAPHIC_EXPORT # define GEOGRAPHIC_EXPORT
#endif #endif
skipping to change at line 119 skipping to change at line 107
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_f() throw() template<typename T> static inline T WGS84_f() throw()
{ 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() throw() { 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>-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() throw()
{ 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 the WGS84 ellipsoid, \e omega, i * @return the angular velocity of the WGS84 ellipsoid, &omega;, in rad
n * s<sup>&minus;1</sup>.
* rad s<sup>-1</sup>.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T WGS84_omega() throw() template<typename T> static inline T WGS84_omega() throw()
{ 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() throw()
{ return 1/WGS84_f<T>(); } { return 1/WGS84_f<T>(); }
skipping to change at line 152 skipping to change at line 140
static inline Math::real WGS84_r() throw() { return WGS84_r<real>(); } static inline Math::real WGS84_r() throw() { return WGS84_r<real>(); }
/** /**
* @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() throw()
{ 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>-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() throw()
{ 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 the GRS80 ellipsoid, \e omega, i * @return the angular velocity of the GRS80 ellipsoid, &omega;, in rad
n * s<sup>&minus;1</sup>.
* rad s<sup>-1</sup>.
* *
* This is about 2*pi*366.25 / (365.25*24*3600) rad s<sup>-1</sup>. 36 * This is about 2 &pi; 366.25 / (365.25 &times; 24 &times; 3600) rad
5.25 * s<sup>&minus;1</sup>. 365.25 is the number of days in a Julian year
* is the number of days in a Julian year and 365.35/366.25 converts fr and
om * 365.35/366.25 converts from solar days to sidereal days. Using the
* solar days to sidereal days. Using the number of days in a Gregoria * number of days in a Gregorian year (365.2425) results in a worse
n * approximation (because the Gregorian year includes the precession of
* year (365.2425) results in a worse approximation (because the Gregor the
ian * earth's axis).
* year includes the precession of the earth's axis).
********************************************************************** / ********************************************************************** /
template<typename T> static inline T GRS80_omega() throw() template<typename T> static inline T GRS80_omega() throw()
{ 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() throw()
{ return T(108263) / T(100000000); } { return T(108263) / T(100000000); }
 End of changes. 7 change blocks. 
30 lines changed or deleted 15 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-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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 "$Id: b785083c68342befaed31fa99990bc7d26dbce3 9 $" #define GEOGRAPHICLIB_DMS_HPP 1
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/Utility.hpp> #include <GeographicLib/Utility.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs string // Squelch warnings about dll vs string
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \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.
skipping to change at line 119 skipping to change at line 119
******************************************************************** **/ ******************************************************************** **/
SECOND = 2, SECOND = 2,
}; };
/** /**
* 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).
* @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, '
* (single quote), &quot; (double quote), and these components may only be * (single quote), &quot; (double quote), and these components may only be
* given in this order. Any (but not all) components may be omitted an d * given in this order. Any (but not all) components may be omitted an d
* other symbols (e.g., the <sup>o</sup> symbol for degrees and the uni code * other symbols (e.g., the ° symbol for degrees and the unicode
* prime and double prime symbols for minutes and seconds) may be * prime and double prime symbols for minutes and seconds) may be
* substituted. The last component indicator may be omitted and is ass umed * substituted. The last component indicator may be omitted and is ass umed
* to be the next smallest unit (thus 33d10 is interpreted as 33d10'). The * to be the next smallest unit (thus 33d10 is interpreted as 33d10'). The
* final component may be a decimal fraction but the non-final componen ts * final component may be a decimal fraction but the non-final componen ts
* must be integers. Instead of using d, ', and &quot; to indicate * must be integers. Instead of using d, ', and &quot; to indicate
* degrees, minutes, and seconds, : (colon) may be used to <i>separate< /i> * degrees, minutes, and seconds, : (colon) may be used to <i>separate< /i>
* these components (numbers must appear before and after each colon); thus * these components (numbers must appear before and after each colon); thus
* 50d30'10.3&quot; may be written as 50:30:10.3, 5.5' may be written * 50d30'10.3&quot; may be 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 * 0:5.5, and so on. The integer parts of the minutes and seconds
* components must be less than 60. A single leading sign is permitted . A * components must be less than 60. A single leading sign is permitted . A
skipping to change at line 162 skipping to change at line 163
* 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="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoding. (T he * <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoding. (T he
* 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:
* - degrees: * - degrees:
* - d, D lower and upper case letters * - d, D lower and upper case letters
* - U+00b0 degree symbol * - 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
* - minutes: * - minutes:
* - ' apostrophe * - ' apostrophe
* - U+2032 prime * - U+2032 prime (&prime;)
* - U+00b4 acute accent * - U+00b4 acute accent
* - U+2019 right single quote (&rsquo;)
* - seconds: * - seconds:
* - &quot; quotation mark * - &quot; quotation mark
* - U+2033 double prime * - U+2033 double prime (&Prime;)
* - U+201d right double quote (&rdquo;)
* - '&nbsp;' any two consecutive symbols for minutes * - '&nbsp;' any two consecutive symbols for minutes
* . * .
* 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.
* *
skipping to change at line 200 skipping to change at line 204
********************************************************************** / ********************************************************************** /
static Math::real Decode(real d, real m = 0, real s = 0) throw() static Math::real Decode(real d, real m = 0, real s = 0) throw()
{ return d + (m + s/real(60))/real(60); } { return d + (m + s/real(60))/real(60); }
/// \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.
* @return decoded number. * @return decoded number.
********************************************************************** / ********************************************************************** /
static Math::real Decode(const std::string& str) static Math::real Decode(const std::string& str)
{ return Utility::num<real>(str); } { return Utility::num<real>(str); }
/** /**
* <b>DEPRECATED</b> (use Utility::fract, instead). * <b>DEPRECATED</b> (use Utility::fract, instead).
* Convert a string to a real number treating the case where the string is * Convert a string to a real number treating the case where the string is
* a simple fraction. * a simple fraction.
* *
* @param[in] str string input. * @param[in] str string input.
* @exception GeographicErr if \e str is malformed.
* @return decoded number. * @return decoded number.
********************************************************************** / ********************************************************************** /
static Math::real DecodeFraction(const std::string& str) static Math::real DecodeFraction(const std::string& str)
{ return Utility::fract<real>(str); } { return Utility::fract<real>(str); }
/// \endcond /// \endcond
/** /**
* Convert a pair of strings to latitude and longitude. * Convert a pair of strings to latitude and longitude.
* *
* @param[in] dmsa first string. * @param[in] dmsa first string.
* @param[in] dmsb second string. * @param[in] dmsb second string.
* @param[out] lat latitude. * @param[out] lat latitude.
* @param[out] lon longitude. * @param[out] lon longitude reduced to the range [&minus;180&deg;,
* 180&deg;).
* @param[in] swaplatlong if true assume longitude is given before lati tude * @param[in] swaplatlong if true assume longitude is given before lati tude
* in the absence of hemisphere designators (default false). * in the absence of hemisphere designators (default false).
* @exception GeographicErr if \e dmsa or \e dmsb is malformed.
* @exception GeographicErr if \e dmsa and \e dmsb are both interpreted
as
* latitudes.
* @exception GeographicErr if \e dmsa and \e dmsb are both interpreted
as
* longitudes.
* @exception GeographicErr if decoded latitude is not in [&minus;90&de
g;,
* 90&deg;].
* @exception GeographicErr if decoded longitude is not in
* [&minus;540&deg;, 540&deg;).
* *
* By default, the \e lat (resp., \e lon) is assigned to the results of * By default, the \e lat (resp., \e lon) is assigned to the results of
* decoding \e dmsa (resp., \e dmsb). However this is overridden if ei ther * decoding \e dmsa (resp., \e dmsb). However this is overridden if ei ther
* \e dmsa or \e dmsb contain a latitude or longitude hemisphere design ator * \e dmsa or \e dmsb contain a latitude or longitude hemisphere design ator
* (N, S, E, W). Throws an error if the decoded numbers are out of the * (N, S, E, W). If an exception is thrown, \e lat and \e lon are
* ranges [-90<sup>o</sup>, 90<sup>o</sup>] for latitude and * unchanged.
* [-180<sup>o</sup>, 360<sup>o</sup>] for longitude and, in which case
\e
* lat and \e lon are unchanged. Finally the longitude is reduced to t
he
* range [-180<sup>o</sup>, 180<sup>o</sup>).
********************************************************************** / ********************************************************************** /
static void DecodeLatLon(const std::string& dmsa, const std::string& dm sb, static void DecodeLatLon(const std::string& dmsa, const std::string& dm sb,
real& lat, real& lon, bool swaplatlong = false ); real& lat, real& lon, bool swaplatlong = false );
/** /**
* Convert a string to an angle in degrees. * Convert a string to an angle in degrees.
* *
* @param[in] angstr input string. * @param[in] angstr input string.
* @exception GeographicErr if \e angstr is malformed.
* @exception GeographicErr if \e angstr includes a hemisphere designat
or.
* @return angle (degrees) * @return angle (degrees)
* *
* No hemisphere designator is allowed and no check is done on the rang e of * No hemisphere designator is allowed and no check is done on the rang e of
* the result. * the result.
********************************************************************** / ********************************************************************** /
static Math::real DecodeAngle(const std::string& angstr); static Math::real DecodeAngle(const std::string& angstr);
/** /**
* Convert a string to an azimuth in degrees. * Convert a string to an azimuth in degrees.
* *
* @param[in] azistr input string. * @param[in] azistr input string.
* @return azimuth (degrees) * @exception GeographicErr if \e azistr is malformed.
* @exception GeographicErr if \e azistr includes a N/S designator.
* @exception GeographicErr if decoded azimuth is not in
* [&minus;540&deg;, 540&deg;).
* @return azimuth (degrees) reduced to the range [&minus;180&deg;,
* 180&deg;).
* *
* A hemisphere designator E/W can be used; the result is multiplied by * A hemisphere designator E/W can be used; the result is multiplied by
-1 * &minus;1 if W is present.
* if W is present. Throws an error if the result is out of the range
* [-180<sup>o</sup>, 360<sup>o</sup>]. Finally the azimuth is reduced
to
* the range [-180<sup>o</sup>, 180<sup>o</sup>).
********************************************************************** / ********************************************************************** /
static Math::real DecodeAzimuth(const std::string& azistr); static Math::real DecodeAzimuth(const std::string& azistr);
/** /**
* Convert angle (in degrees) into a DMS string (using d, ', and &quot; ). * Convert angle (in degrees) into a DMS string (using d, ', and &quot; ).
* *
* @param[in] angle input angle (degrees) * @param[in] angle input angle (degrees)
* @param[in] trailing DMS::component value indicating the trailing uni ts * @param[in] trailing DMS::component value indicating the trailing uni ts
* on the string and this is given as a decimal number if necessary. * on the string and this is given as a decimal number if necessary.
* @param[in] prec the number of digits after the decimal point for the * @param[in] prec the number of digits after the decimal point for the
* trailing component. * trailing component.
* @param[in] ind DMS::flag value indicated additional formatting. * @param[in] ind DMS::flag value indicated additional formatting.
* @param[in] dmssep if non-null, use as the DMS separator character * @param[in] dmssep if non-null, use as the DMS separator character
* (instead of d, ', &quot; delimiters). * (instead of d, ', &quot; delimiters).
* @exception std::bad_alloc if memory for the string can't be allocate d.
* @return formatted string * @return formatted string
* *
* The interpretation of \e ind is as follows: * The interpretation of \e ind is as follows:
* - ind == DMS::NONE, signed result no leading zeros on degrees except in * - ind == DMS::NONE, signed result no leading zeros on degrees except in
* the units place, e.g., -8d03'. * the units place, e.g., -8d03'.
* - ind == DMS::LATITUDE, trailing N or S hemisphere designator, no si gn, * - ind == DMS::LATITUDE, trailing N or S hemisphere designator, no si gn,
* pad degrees to 2 digits, e.g., 08d03'S. * pad degrees to 2 digits, e.g., 08d03'S.
* - ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no * - ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no
* sign, pad degrees to 3 digits, e.g., 008d03'W. * sign, pad degrees to 3 digits, e.g., 008d03'W.
* - ind == DMS::AZIMUTH, convert to the range [0, 360<sup>o</sup>;), no * - ind == DMS::AZIMUTH, convert to the range [0, 360°;), no
* sign, pad degrees to 3 digits, , e.g., 351d57'. * sign, pad degrees to 3 digits, , e.g., 351d57'.
* . * .
* The integer parts of the minutes and seconds components are always g iven * The integer parts of the minutes and seconds components are always g iven
* with 2 digits. * with 2 digits.
********************************************************************** / ********************************************************************** /
static std::string Encode(real angle, component trailing, unsigned prec , static std::string Encode(real angle, component trailing, unsigned prec ,
flag ind, char dmssep); flag ind, char dmssep);
/** /**
* Convert angle (in degrees) into a DMS string (using d, ', and &quot; ). * Convert angle (in degrees) into a DMS string (using d, ', and &quot; ).
skipping to change at line 324 skipping to change at line 343
/** /**
* Convert angle into a DMS string (using d, ', and &quot;) selecting t he * Convert angle into a DMS string (using d, ', and &quot;) selecting t he
* trailing component based on the precision. * trailing component based on the precision.
* *
* @param[in] angle input angle (degrees) * @param[in] angle input angle (degrees)
* @param[in] prec the precision relative to 1 degree. * @param[in] prec the precision relative to 1 degree.
* @param[in] ind DMS::flag value indicated additional formatting. * @param[in] ind DMS::flag value indicated additional formatting.
* @param[in] dmssep if non-null, use as the DMS separator character * @param[in] dmssep if non-null, use as the DMS separator character
* (instead of d, ', &quot; delimiters). * (instead of d, ', &quot; delimiters).
* @exception std::bad_alloc if memory for the string can't be allocate d.
* @return formatted string * @return formatted string
* *
* \e prec indicates the precision relative to 1 degree, e.g., \e prec = 3 * \e prec indicates the precision relative to 1 degree, e.g., \e prec = 3
* gives a result accurate to 0.1' and \e prec = 4 gives a result accur ate * gives a result accurate to 0.1' and \e prec = 4 gives a result accur ate
* to 1&quot;. \e ind is interpreted as in DMS::Encode with the additi onal * to 1&quot;. \e ind is interpreted as in DMS::Encode with the additi onal
* facility that DMS::NUMBER represents \e angle as a number in fixed * facility that DMS::NUMBER represents \e angle as a number in fixed
* format with precision \e prec. * format with precision \e prec.
********************************************************************** / ********************************************************************** /
static std::string Encode(real angle, unsigned prec, flag ind = NONE, static std::string Encode(real angle, unsigned prec, flag ind = NONE,
char dmssep = char(0)) { char dmssep = char(0)) {
skipping to change at line 370 skipping to change at line 390
static void Encode(real ang, real& d, real& m, real& s) throw() { static void Encode(real ang, real& d, real& m, real& s) throw() {
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)
#endif #endif
#endif // GEOGRAPHICLIB_DMS_HPP #endif // GEOGRAPHICLIB_DMS_HPP
 End of changes. 21 change blocks. 
24 lines changed or deleted 44 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) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * 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 \ #define GEOGRAPHICLIB_ELLIPSOID_HPP 1
"$Id: 56f44ba756b6289d4e328ae3e953768a909325f7 $"
#include <string> #include <string>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/TransverseMercator.hpp> #include <GeographicLib/TransverseMercator.hpp>
#include <GeographicLib/EllipticFunction.hpp> #include <GeographicLib/EllipticFunction.hpp>
#include <GeographicLib/AlbersEqualArea.hpp> #include <GeographicLib/AlbersEqualArea.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
skipping to change at line 35 skipping to change at line 34
* This class returns various properties of the ellipsoid and converts * This class returns various properties of the ellipsoid and converts
* between various types of latitudes. The latitude conversions are also * between various types of latitudes. The latitude conversions are also
* possible using the various projections supported by %GeographicLib; bu t * possible using the various projections supported by %GeographicLib; bu t
* Ellipsoid provides more direct access (sometimes using private functio ns * Ellipsoid provides more direct access (sometimes using private functio ns
* of the projection classes). Ellipsoid::RectifyingLatitude, * of the projection classes). Ellipsoid::RectifyingLatitude,
* Ellipsoid::InverseRectifyingLatitude, and Ellipsoid::MeridianDistance * Ellipsoid::InverseRectifyingLatitude, and Ellipsoid::MeridianDistance
* provide functionality which can be provided by the Geodesic class. * provide functionality which can be provided by the Geodesic class.
* However Geodesic uses a series approximation (valid for abs \e f < 1/1 50), * However Geodesic uses a series approximation (valid for abs \e f < 1/1 50),
* whereas Ellipsoid computes these quantities using EllipticFunction whi ch * whereas Ellipsoid computes these quantities using EllipticFunction whi ch
* provides accurate results even when \e f is large. Use of this class * provides accurate results even when \e f is large. Use of this class
* should be limited to -3 < \e f < 3/4 (i.e., 1/4 < b/a < 4). * should be limited to &minus;3 < \e f < 3/4 (i.e., 1/4 < b/a < 4).
* *
* Example of use: * Example of use:
* \include example-Ellipsoid.cpp * \include example-Ellipsoid.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHIC_EXPORT Ellipsoid { class GEOGRAPHIC_EXPORT Ellipsoid {
private: private:
typedef Math::real real; typedef Math::real real;
static const int numit_ = 10; static const int numit_ = 10;
real _a, _f, _f1, _f12, _e2, _e12, _n, _b, _stol; real _a, _f, _f1, _f12, _e2, _e12, _n, _b, _stol;
skipping to change at line 72 skipping to change at line 71
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* 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.
* * @exception GeographicErr if \e a or (1 &minus; \e f ) \e a is not
* An exception is thrown if either of the axes of the ellipsoid is * positive.
* non-positive.
********************************************************************** / ********************************************************************** /
Ellipsoid(real a, real f); Ellipsoid(real a, real f);
///@} ///@}
/** \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
skipping to change at line 96 skipping to change at line 94
********************************************************************** / ********************************************************************** /
Math::real MajorRadius() const throw() { return _a; } Math::real MajorRadius() const throw() { 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 throw() { 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 = (\e pi / 2) \e a. The rad * meridian (meters). For a sphere \e L = (&pi;/2) \e a. The radius
ius * of a sphere with the same meridian length is \e L / (&pi;/2).
* of a sphere with the same meridian length is \e L / (\e pi / 2).
********************************************************************** / ********************************************************************** /
Math::real QuarterMeridian() const throw(); Math::real QuarterMeridian() const throw();
/** /**
* @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\e pi <i>a</i><sup>2</sup>. The radius of a sphe * a sphere \e A = 4&pi; <i>a</i><sup>2</sup>. The radius of a spher
re e
* with the same area is sqrt(\e A / (4 \e pi)). * with the same area is sqrt(\e A / (4&pi;)).
********************************************************************** / ********************************************************************** /
Math::real Area() const throw(); Math::real Area() const throw();
/** /**
* @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\e pi / 3) <i>a</i><sup>3</sup>. The radius * For a sphere \e V = (4&pi; / 3) <i>a</i><sup>3</sup>. The radius
of of
* a sphere with the same volume is cbrt(\e V / (4 \e pi / 3)). * a sphere with the same volume is cbrt(\e V / (4&pi;/3)).
********************************************************************** / ********************************************************************** /
Math::real Volume() const throw() Math::real Volume() const throw()
{ 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 - \e b) / \e a, the flattening of the ellipsoid * @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
* This is the value used in the constructor. This is zero, positive ro,
, or * positive, or negative for a sphere, oblate ellipsoid, or prolate
* negative for a sphere, oblate ellipsoid, or prolate ellipsoid. * ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real Flattening() { return _f; } Math::real Flattening() { return _f; }
/** /**
* @return \e f ' = (\e a - \e b) / \e b, the second flattening of the * @return \e f ' = (\e a &minus; \e b) / \e b, the second flattening o
* ellipsoid. This is zero, positive, or negative for a sphere, obla f
te * the ellipsoid. This is zero, positive, or negative for a sphere,
* ellipsoid, or prolate ellipsoid. * oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real SecondFlattening() { return _f / (1 - _f); } Math::real SecondFlattening() { return _f / (1 - _f); }
/** /**
* @return \e n = (\e a - \e b) / (\e a + \e b), the third flattening o * @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third flatte
f ning
* the ellipsoid. This is zero, positive, or negative for a sphere, * 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() { return _n; } Math::real ThirdFlattening() { return _n; }
/** /**
* @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> - * @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 the ellipsoid. This is zero, positive, or negative for a * of the ellipsoid. This is zero, positive, or negative for a spher
* sphere, oblate ellipsoid, or prolate ellipsoid. e,
* oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real EccentricitySq() { return _e2; } Math::real EccentricitySq() { return _e2; }
/** /**
* @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> - * @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 the ellipsoid. This is zero, positive, or negative * squared of the ellipsoid. This is zero, positive, or negative for
for a
* a sphere, oblate ellipsoid, or prolate ellipsoid. * sphere, oblate ellipsoid, or prolate ellipsoid.
********************************************************************** / ********************************************************************** /
Math::real SecondEccentricitySq() { return _e12; } Math::real SecondEccentricitySq() { return _e12; }
/** /**
* @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> - * @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 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() { return _e2 / (2 - _e2); } Math::real ThirdEccentricitySq() { 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 \e beta the parametric latitude (degrees). * @return &beta; the parametric latitude (degrees).
* *
* The geographic latitude, \e phi, is the angle beween the equatorial * The geographic latitude, &phi;, is the angle beween the equatorial
* plane and a vector normal to the surface of the ellipsoid. * plane and a vector normal to the surface of the ellipsoid.
* *
* The parametric latitude (also called the reduced latitude), \e beta, * The parametric latitude (also called the reduced latitude), &beta;,
* allows the cartesian coordinated of a meridian to be expressed * allows the cartesian coordinated of a meridian to be expressed
* conveniently in parametric form as * conveniently in parametric form as
* - \e R = \e a cos \e beta * - \e R = \e a cos &beta;
* - \e Z = \e b sin \e 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 \e beta = \e phi. * For a sphere &beta; = &phi;.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e beta lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &beta; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real ParametricLatitude(real phi) const throw(); Math::real ParametricLatitude(real phi) const throw();
/** /**
* @param[in] beta the parametric latitude (degrees). * @param[in] beta the parametric latitude (degrees).
* @return \e phi the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* \e beta must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e phi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseParametricLatitude(real beta) const throw(); Math::real InverseParametricLatitude(real beta) const throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e theta the geocentric latitude (degrees). * @return &theta; the geocentric latitude (degrees).
* *
* The geocentric latitude, \e theta, is the angle beween the equatoria l * 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 \e theta = \e phi. * ellipsoid. For a sphere &theta; = &phi;.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e theta lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &theta; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real GeocentricLatitude(real phi) const throw(); Math::real GeocentricLatitude(real phi) const throw();
/** /**
* @param[in] theta the geocentric latitude (degrees). * @param[in] theta the geocentric latitude (degrees).
* @return \e phi the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* \e theta must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>]; th e * &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
* \e phi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseGeocentricLatitude(real theta) const throw(); Math::real InverseGeocentricLatitude(real theta) const throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e mu the rectifying latitude (degrees). * @return &mu; the rectifying latitude (degrees).
* *
* The rectifying latitude, \e mu, has the property that the distance a long * 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
* <i>mu</i><sub>1</sub> and <i>mu</i><sub>2</sub> is equal to * &mu;<sub>1</sub> and &mu;<sub>2</sub> is equal to
* (<i>mu</i><sub>2</sub> - <i>mu</i><sub>1</sub>) \e L / 90<sup>o</sup * (&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 \e mu = \e phi.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e mu lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &mu; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real RectifyingLatitude(real phi) const throw(); Math::real RectifyingLatitude(real phi) const throw();
/** /**
* @param[in] mu the rectifying latitude (degrees). * @param[in] mu the rectifying latitude (degrees).
* @return \e phi the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* \e mu must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e phi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseRectifyingLatitude(real mu) const throw(); Math::real InverseRectifyingLatitude(real mu) const throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e xi the authalic latitude (degrees). * @return &xi; the authalic latitude (degrees).
* *
* The authalic latitude, \e 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
* <i>xi</i><sub>1</sub> and <i>xi</i><sub>2</sub> is equal to (sin * &xi;<sub>1</sub> and &xi;<sub>2</sub> is equal to (sin
* <i>xi</i><sub>2</sub> - sin <i>xi</i><sub>1</sub>) \e A / 2, where \ * &xi;<sub>2</sub> - sin &xi;<sub>1</sub>) \e A / 2, where \e A
e A * = Area(). For a sphere &xi; = &phi;.
* = Area(). For a sphere \e xi = \e phi.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e xi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &xi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real AuthalicLatitude(real phi) const throw(); Math::real AuthalicLatitude(real phi) const throw();
/** /**
* @param[in] xi the authalic latitude (degrees). * @param[in] xi the authalic latitude (degrees).
* @return \e phi the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* \e xi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e phi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseAuthalicLatitude(real xi) const throw(); Math::real InverseAuthalicLatitude(real xi) const throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e chi the conformal latitude (degrees). * @return &chi; the conformal latitude (degrees).
* *
* The conformal latitude, \e chi, gives the mapping of the ellipsoid t o 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 \e chi = \e phi. * sphere &chi; = &phi;.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e chi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &chi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real ConformalLatitude(real phi) const throw(); Math::real ConformalLatitude(real phi) const throw();
/** /**
* @param[in] chi the conformal latitude (degrees). * @param[in] chi the conformal latitude (degrees).
* @return \e phi the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* \e chi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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
* \e phi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseConformalLatitude(real chi) const throw(); Math::real InverseConformalLatitude(real chi) const throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e 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 \e psi = * defines the Mercator projection. For a sphere &psi; =
* sinh<sup>-1</sup> tan \e phi. * sinh<sup>&minus;1</sup> tan &phi;.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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 throw();
/** /**
* @param[in] psi the isometric latitude (degrees). * @param[in] psi the isometric latitude (degrees).
* @return \e phi the geographic latitude (degrees). * @return &phi; the geographic latitude (degrees).
* *
* The returned value \e phi lies in [-90<sup>o</sup>, 90<sup>o</sup>;]. * The returned value &phi; lies in [&minus;90&deg;, 90&deg;].
********************************************************************** / ********************************************************************** /
Math::real InverseIsometricLatitude(real psi) const throw(); Math::real InverseIsometricLatitude(real psi) const throw();
///@} ///@}
/** \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 \e beta the radius of a circle of latitude \ * @return \e R = \e a cos &beta; the radius of a circle of latitude
e * &phi; (meters). \e R (&pi;/180&deg;) gives meters per degree
* phi (meters). \e R (\e pi / 180<sup>o</sup>) gives meters per deg
ree
* longitude measured along a circle of latitude. * longitude measured along a circle of latitude.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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 throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e Z = \e b sin \e beta the distance of a circle of latitude * @return \e Z = \e b sin &beta; the distance of a circle of latitude
\e * &phi; from the equator measured parallel to the ellipsoid axis
* phi from the equator measured parallel to the ellipsoid axis (mete * (meters).
rs).
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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 throw();
/** /**
* @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 \e phi (meters). \e s * between the equator and a point of latitude &phi; (meters). \e s
is is
* given by \e s = \e mu \e L / 90<sup>o</sup>, where \e L = * given by \e s = &mu; \e L / 90&deg;, where \e L =
* QuarterMeridian()). * QuarterMeridian()).
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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 throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e rho the meridional radius of curvature of the ellipsoid a * @return &rho; the meridional radius of curvature of the ellipsoid at
t * latitude &phi; (meters); this is the curvature of the meridian. \
* latitude \e phi (meters); this is the curvature of the meridian. e
\e * rho is given by &rho; = (180&deg;/&pi;) d\e s / d&phi;,
* rho is given by \e rho = (180<sup>o</sup> / \e pi) d\e s / d\e phi * where \e s = MeridianDistance(); thus &rho; (&pi;/180&deg;)
,
* where \e s = MeridianDistance(); thus \e rho (\e pi / 180<sup>o</s
up>)
* gives meters per degree latitude measured along a meridian. * gives meters per degree latitude measured along a meridian.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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 throw();
/** /**
* @param[in] phi the geographic latitude (degrees). * @param[in] phi the geographic latitude (degrees).
* @return \e nu the transverse radius of curvature of the ellipsoid at * @return &nu; the transverse radius of curvature of the ellipsoid at
* latitude \e 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. \e nu is related to \e R = CircleRadius() by * and to the meridian. &nu; is related to \e R = CircleRadius() by
\e \e
* R = \e nu cos \e phi. * R = &nu; cos &phi;.
* *
* \e phi must lie in the range [-90<sup>o</sup>, 90<sup>o</sup>;]; 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 throw();
/**
* @param[in] phi the geographic latitude (degrees).
* @param[in] azi the angle between the meridian and the normal section
* (degrees).
* @return the radius of curvature of the ellipsoid in the normal
* section at latitude &phi; inclined at an angle \e azi to the
* meridian (meters).
*
* &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
* result is undefined if either of conditions does not hold.
**********************************************************************
/
Math::real NormalCurvatureRadius(real phi, real azi) const throw();
///@} ///@}
/** \name Eccentricity conversions. /** \name Eccentricity conversions.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* @param[in] fp = \e f ' = (\e a - \e b) / \e b, the second flattening * @param[in] fp = \e f ' = (\e a &minus; \e b) / \e b, the second
. * flattening.
* @return \e f = (\e a - \e b) / \e a, the flattening. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* \e f ' should lie in (-1, inf). * \e f ' should lie in (&minus;1, &infin;).
* The returned value \e f lies in (-inf, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real SecondFlatteningToFlattening(real fp) throw() static Math::real SecondFlatteningToFlattening(real fp) throw()
{ return fp / (1 + fp); } { return fp / (1 + fp); }
/** /**
* @param[in] f = (\e a - \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return \e f ' = (\e a - \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 (-inf, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value \e f ' lies in (-1, inf). * The returned value \e f ' lies in (&minus;1, &infin;).
********************************************************************** / ********************************************************************** /
static Math::real FlatteningToSecondFlattening(real f) throw() static Math::real FlatteningToSecondFlattening(real f) throw()
{ return f / (1 - f); } { return f / (1 - f); }
/** /**
* @param[in] n = (\e a - \e b) / (\e a + \e b), the third flattening. * @param[in] n = (\e a &minus; \e b) / (\e a + \e b), the third
* @return \e f = (\e a - \e b) / \e a, the flattening. * flattening.
* @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* *
* \e n should lie in (-1, 1). * \e n should lie in (&minus;1, 1).
* The returned value \e f lies in (-inf, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real ThirdFlatteningToFlattening(real n) throw() static Math::real ThirdFlatteningToFlattening(real n) throw()
{ return 2 * n / (1 + n); } { return 2 * n / (1 + n); }
/** /**
* @param[in] f = (\e a - \e b) / \e a, the flattening. * @param[in] f = (\e a &minus; \e b) / \e a, the flattening.
* @return \e n = (\e a - \e b) / (\e a + \e b), the third flattening. * @return \e n = (\e a &minus; \e b) / (\e a + \e b), the third
* flattening.
* *
* \e f should lie in (-inf, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value \e n lies in (-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) throw()
{ return f / (2 - f); } { return f / (2 - f); }
/** /**
* @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> - * @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 - \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 (-inf, 1). * <i>e</i><sup>2</sup> should lie in (&minus;&infin;, 1).
* The returned value \e f lies in (-inf, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real EccentricitySqToFlattening(real e2) throw() static Math::real EccentricitySqToFlattening(real e2) throw()
{ return e2 / (std::sqrt(1 - e2) + 1); } { return e2 / (std::sqrt(1 - e2) + 1); }
/** /**
* @param[in] f = (\e a - \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> - * @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 (-inf, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value <i>e</i><sup>2</sup> lies in (-inf, 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) throw()
{ return f * (2 - f); } { return f * (2 - f); }
/** /**
* @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> - * @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 - \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 (-1, inf). * <i>e'</i> <sup>2</sup> should lie in (&minus;1, &infin;).
* The returned value \e f lies in (-inf, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real SecondEccentricitySqToFlattening(real ep2) throw() static Math::real SecondEccentricitySqToFlattening(real ep2) throw()
{ return ep2 / (std::sqrt(1 + ep2) + 1 + ep2); } { return ep2 / (std::sqrt(1 + ep2) + 1 + ep2); }
/** /**
* @param[in] f = (\e a - \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> - * @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 (-inf, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value <i>e'</i> <sup>2</sup> lies in (-1, inf). * 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) throw()
{ 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>
* <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</su * &minus; <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> +
p>), * <i>b</i><sup>2</sup>), the third eccentricity squared.
* the third eccentricity squared. * @return \e f = (\e a &minus; \e b) / \e a, the flattening.
* @return \e f = (\e a - \e b) / \e a, the flattening.
* *
* <i>e''</i> <sup>2</sup> should lie in (-1, 1). * <i>e''</i> <sup>2</sup> should lie in (&minus;1, 1).
* The returned value \e f lies in (-inf, 1). * The returned value \e f lies in (&minus;&infin;, 1).
********************************************************************** / ********************************************************************** /
static Math::real ThirdEccentricitySqToFlattening(real epp2) throw() static Math::real ThirdEccentricitySqToFlattening(real epp2) throw()
{ 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 - \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> - * @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 (-inf, 1). * \e f should lie in (&minus;&infin;, 1).
* The returned value <i>e''</i> <sup>2</sup> lies in (-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) throw()
{ 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.
********************************************************************** / ********************************************************************** /
 End of changes. 96 change blocks. 
164 lines changed or deleted 172 lines changed or added


 EllipticFunction.hpp   EllipticFunction.hpp 
/** /**
* \file EllipticFunction.hpp * \file EllipticFunction.hpp
* \brief Header for GeographicLib::EllipticFunction class * \brief Header for GeographicLib::EllipticFunction class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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_ELLIPTICFUNCTION_HPP) #if !defined(GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP)
#define GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP \ #define GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP 1
"$Id: fdcfd14ffa66adbc9ac813b93b62e302eada1d7c $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Elliptic functions needed for TransverseMercatorExact * \brief Elliptic functions needed for TransverseMercatorExact
* *
* This provides the subset of elliptic functions needed for * This provides the subset of elliptic functions needed for
* TransverseMercatorExact. For a given ellipsoid, only parameters * TransverseMercatorExact. For a given ellipsoid, only parameters
* <i>e</i><sup>2</sup> and 1 - <i>e</i><sup>2</sup> are needed. This cl * <i>e</i><sup>2</sup> and 1 &minus; <i>e</i><sup>2</sup> are needed. T
ass his
* taken the parameter as a constructor parameters and caches the values * class taken the parameter as a constructor parameters and caches the
of * values of the required complete integrals. A method is provided for
* the required complete integrals. A method is provided for Jacobi elli * Jacobi elliptic functions and for the incomplete elliptic integral of
ptic the
* functions and for the incomplete elliptic integral of the second kind * second kind in terms of the amplitude.
in
* terms of the amplitude.
* *
* The computation of the elliptic integrals uses the algorithms given in * The computation of the elliptic integrals uses the algorithms given in
* - B. C. Carlson, * - B. C. Carlson,
* <a href="http://dx.doi.org/10.1007/BF02198293"> Computation of ellip tic * <a href="http://dx.doi.org/10.1007/BF02198293"> Computation of ellip tic
* integrals</a>, Numerical Algorithms 10, 13&ndash;26 (1995). * integrals</a>, Numerical Algorithms 10, 13&ndash;26 (1995).
* . * .
* The computation of the Jacobi elliptic functions uses the algorithm gi ven * The computation of the Jacobi elliptic functions uses the algorithm gi ven
* in * in
* - R. Bulirsch, * - R. Bulirsch,
* <a href="http://dx.doi.org/10.1007/BF01397975"> Numerical Calculatio n of * <a href="http://dx.doi.org/10.1007/BF01397975"> Numerical Calculatio n of
skipping to change at line 79 skipping to change at line 78
* is done.) * is done.)
********************************************************************** / ********************************************************************** /
explicit EllipticFunction(real m) throw(); explicit EllipticFunction(real m) throw();
/** /**
* @return the parameter \e m. * @return the parameter \e m.
********************************************************************** / ********************************************************************** /
Math::real m() const throw() { return _m; } Math::real m() const throw() { return _m; }
/** /**
* @return the complementary parameter \e m' = (1 - \e m). * @return the complementary parameter \e m' = (1 &minus; \e m).
********************************************************************** / ********************************************************************** /
Math::real m1() const throw() { return _m1; } Math::real m1() const throw() { return _m1; }
/** /**
* @return the complete integral of first kind, \e K(\e m). * @return the complete integral of first kind, \e K(\e m).
********************************************************************** / ********************************************************************** /
Math::real K() const throw() { _init || Init(); return _kc; } Math::real K() const throw() { _init || Init(); return _kc; }
/** /**
* @return the complete integral of second kind, \e E(\e m). * @return the complete integral of second kind, \e E(\e m).
skipping to change at line 115 skipping to change at line 114
* @param[out] sn sn(<i>x</i>|<i>m</i>). * @param[out] sn sn(<i>x</i>|<i>m</i>).
* @param[out] cn cn(<i>x</i>|<i>m</i>). * @param[out] cn cn(<i>x</i>|<i>m</i>).
* @param[out] dn dn(<i>x</i>|<i>m</i>). * @param[out] dn dn(<i>x</i>|<i>m</i>).
********************************************************************** / ********************************************************************** /
void sncndn(real x, real& sn, real& cn, real& dn) const throw(); void sncndn(real x, real& sn, real& cn, real& dn) const throw();
/** /**
* The incomplete integral of the second kind. * The incomplete integral of the second kind.
* *
* @param[in] phi * @param[in] phi
* @return int sqrt(1 - \e m sin<sup>2</sup>(\e phi)) \e dphi. * @return &int; sqrt(1 &minus; \e m sin<sup>2</sup>&phi;) d&phi;.
********************************************************************** / ********************************************************************** /
Math::real E(real phi) const throw(); Math::real E(real phi) const throw();
/** /**
* The incomplete integral of the second kind. * The incomplete integral of the second kind with the argument given i
n
* degrees.
* *
* @param[in] ang in <i>degrees</i>. * @param[in] ang in <i>degrees</i>.
* @return int sqrt(1 - \e m sin<sup>2</sup>(\e phi)) \e dphi. * @return &int; sqrt(1 &minus; \e m sin<sup>2</sup>&phi;) d&phi;.
* *
* \e ang must lie in [-90, 90]. This function returns the correct res * \e ang must lie in [&minus;90&deg;, 90&deg;]. This function
ult * returns the correct result even when \e m is negative.
* even when \e m is negative.
********************************************************************** / ********************************************************************** /
Math::real Ed(real ang) const throw(); Math::real Ed(real ang) const throw();
/** /**
* 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 * @param[in] sn
* @param[in] cn * @param[in] cn
* @param[in] dn * @param[in] dn
* @return int dn(\e w)<sup>2</sup> \e dw (A+S 17.2.10). * @return &int; dn(\e w)<sup>2</sup> \e dw (A+S 17.2.10).
* *
* Instead of specifying the amplitude \e phi, we provide \e sn = sin(\ * Instead of specifying the amplitude &phi;, we provide \e sn = sin&ph
e i;,
* phi), \e cn = cos(\e phi), \e dn = sqrt(1 - \e m sin<sup>2</sup>(\e * \e cn = cos&phi;, \e dn = sqrt(1 &minus; \e m sin<sup>2</sup>&phi;).
* phi)).
********************************************************************** / ********************************************************************** /
Math::real E(real sn, real cn, real dn) const throw(); Math::real E(real sn, real cn, real dn) const throw();
}; };
} // namespace GeographicLib } // namespace GeographicLib
#endif // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP #endif // GEOGRAPHICLIB_ELLIPTICFUNCTION_HPP
 End of changes. 9 change blocks. 
23 lines changed or deleted 20 lines changed or added


 GeoCoords.hpp   GeoCoords.hpp 
/** /**
* \file GeoCoords.hpp * \file GeoCoords.hpp
* \brief Header for GeographicLib::GeoCoords class * \brief Header for GeographicLib::GeoCoords class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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/
**********************************************************************/ **********************************************************************/
#ifndef GEOGRAPHICLIB_GEOCOORDS_HPP #if !defined(GEOGRAPHICLIB_GEOCOORDS_HPP)
#define GEOGRAPHICLIB_GEOCOORDS_HPP \ #define GEOGRAPHICLIB_GEOCOORDS_HPP 1
"$Id: e706d3a35c3be0e2beaf39041cac29beb468a5aa $"
#include <GeographicLib/UTMUPS.hpp> #include <GeographicLib/UTMUPS.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Conversion between geographic coordinates * \brief Conversion between geographic coordinates
* *
* This class stores a geographic position which may be set via the * This class stores a geographic position which may be set via the
skipping to change at line 75 skipping to change at line 74
} }
void UTMUPSString(int zone, real easting, real northing, void UTMUPSString(int zone, real easting, real northing,
int prec, std::string& utm) const; int prec, std::string& utm) const;
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<sup>o</sup * The default constructor is equivalent to \e latitude = 90&deg;,
>, * \e longitude = 0&deg;.
* \e longitude = 0<sup>o</sup>.
********************************************************************** / ********************************************************************** /
GeoCoords() throw() GeoCoords() throw()
// 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(); }
/** /**
* Construct from a string. * Construct from a string.
* *
* @param[in] s 1-element, 2-element, or 3-element string representatio n of * @param[in] s 1-element, 2-element, or 3-element string representatio n of
* the position. * the position.
* @param[in] centerp governs the interpretation of MGRS coordinates (s ee * @param[in] centerp governs the interpretation of MGRS coordinates (s ee
* below). * below).
* @param[in] swaplatlong governs the interpretation of geographic * @param[in] swaplatlong governs the interpretation of geographic
* coordinates (see below). * coordinates (see below).
* @exception GeographicErr if the \e s is malformed (see below).
* *
* Parse as a string and interpret it as a geographic position. The in put * Parse as a string and interpret it as a geographic position. The in put
* string is broken into space (or comma) separated pieces and Basic * string is broken into space (or comma) separated pieces and Basic
* decision on which format is based on number of components * decision on which format is based on number of components
* -# MGRS * -# MGRS
* -# "Lat Long" or "Long Lat" * -# "Lat Long" or "Long Lat"
* -# "Zone Easting Northing" or "Easting Northing Zone" * -# "Zone Easting Northing" or "Easting Northing Zone"
* *
* The following inputs are approximately the same (Ar Ramadi Bridge, I raq) * The following inputs are approximately the same (Ar Ramadi Bridge, I raq)
* - Latitude and Longitude * - Latitude and Longitude
skipping to change at line 145 skipping to change at line 145
* components. Thus * components. Thus
* - 40d30'30&quot; * - 40d30'30&quot;
* - 40d30'30 * - 40d30'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
* . * .
* 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 [-90, * so -1d30 is -(1+30/60) = -1.5. Latitudes must be in the range
90] * [&minus;90&deg;, 90&deg;] and longitudes in the range
* and longitudes in the range [-180, 360]. Internally longitudes are * [&minus;540&deg;, 540&deg;). Internally longitudes are reduced
* reduced to the range [-180, 180). * to the range [&minus;180&deg;, 180&deg;).
* *
* UTM/UPS parsing. For UTM zones (-80 <= Lat <= 84), the zone designa * UTM/UPS parsing. For UTM zones (&minus;80&deg; &le; Lat < 84&deg;),
tor the
* is made up of a zone number (for 1 to 60) and a hemisphere letter (N * zone designator is made up of a zone number (for 1 to 60) and a
or * hemisphere letter (N or S), e.g., 38N. The latitude zone designer
* S), e.g., 38N. The latitude zone designer ([C&ndash;M] in the south * ([C&ndash;M] in the southern hemisphere and [N&ndash;X] in the north
ern ern)
* hemisphere and [N&ndash;X] in the northern) should NOT be used. (Th * should NOT be used. (This is part of the MGRS coordinate.) The zon
is e
* is part of the MGRS coordinate.) The zone designator for the poles * designator for the poles (where UPS is employed) is a hemisphere let
* (where UPS is employed) is a hemisphere letter by itself, i.e., N or ter
S. * by itself, i.e., N or S.
* *
* MGRS parsing interprets the grid references as square area at the * MGRS parsing 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.,
skipping to change at line 180 skipping to change at line 182
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).
* @param[in] zone if specified, force the UTM/UPS representation to us e a * @param[in] zone if specified, force the UTM/UPS representation to us e a
* specified zone using the rules given in UTMUPS::zonespec. * specified zone using the rules given in UTMUPS::zonespec.
* @exception GeographicErr if \e latitude is not in [&minus;90&deg;,
* 90&deg;].
* @exception GeographicErr if \e longitude is not in [&minus;540&deg;,
* 540&deg;).
* @exception GeographicErr if \e zone cannot be used for this location
.
********************************************************************** / ********************************************************************** /
GeoCoords(real latitude, real longitude, int zone = UTMUPS::STANDARD) { GeoCoords(real latitude, real longitude, int zone = UTMUPS::STANDARD) {
Reset(latitude, longitude, zone); Reset(latitude, longitude, zone);
} }
/** /**
* Construct from UTM/UPS coordinates. * Construct from UTM/UPS coordinates.
* *
* @param[in] zone UTM zone (zero means UPS). * @param[in] zone 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] easting (meters). * @param[in] easting (meters).
* @param[in] northing (meters). * @param[in] northing (meters).
* @exception GeographicErr if \e zone, \e easting, or \e northing is
* outside its allowed range.
********************************************************************** / ********************************************************************** /
GeoCoords(int zone, bool northp, real easting, real northing) { GeoCoords(int zone, bool northp, real easting, real northing) {
Reset(zone, northp, easting, northing); Reset(zone, northp, easting, northing);
} }
/** /**
* Reset the location from a string. See * Reset the location from a string. See
* GeoCoords(const std::string& s, bool centerp, bool swaplatlong). * GeoCoords(const std::string& s, bool centerp, bool swaplatlong).
*
* @param[in] s 1-element, 2-element, or 3-element string representatio
n of
* the position.
* @param[in] centerp governs the interpretation of MGRS coordinates.
* @param[in] swaplatlong governs the interpretation of geographic
* coordinates.
* @exception GeographicErr if the \e s is malformed.
********************************************************************** / ********************************************************************** /
void Reset(const std::string& s, void Reset(const std::string& s,
bool centerp = true, bool swaplatlong = false); bool centerp = true, bool swaplatlong = false);
/** /**
* Reset the location in terms of geographic coordinates. See * Reset the location in terms of geographic coordinates. See
* GeoCoords(real latitude, real longitude, int zone). * GeoCoords(real latitude, real longitude, int zone).
*
* @param[in] latitude (degrees).
* @param[in] longitude (degrees).
* @param[in] zone if specified, force the UTM/UPS representation to us
e a
* specified zone using the rules given in UTMUPS::zonespec.
* @exception GeographicErr if \e latitude is not in [&minus;90&deg;,
* 90&deg;].
* @exception GeographicErr if \e longitude is not in [&minus;540&deg;,
* 540&deg;).
* @exception GeographicErr if \e zone cannot be used for this location
.
********************************************************************** / ********************************************************************** /
void Reset(real latitude, real longitude, int zone = UTMUPS::STANDARD) { void Reset(real latitude, real longitude, int zone = UTMUPS::STANDARD) {
UTMUPS::Forward(latitude, longitude, UTMUPS::Forward(latitude, longitude,
_zone, _northp, _easting, _northing, _gamma, _k, _zone, _northp, _easting, _northing, _gamma, _k,
zone); zone);
_lat = latitude; _lat = latitude;
_long = longitude; _long = longitude;
if (_long >= 180) if (_long >= 180) _long -= 360;
_long -= 360; else if (_long < -180) _long += 360;
CopyToAlt(); CopyToAlt();
} }
/** /**
* Reset the location in terms of UPS/UPS coordinates. See * Reset the location in terms of UPS/UPS coordinates. See
* GeoCoords(int zone, bool northp, real easting, real northing). * GeoCoords(int zone, bool northp, real easting, real northing).
*
* @param[in] zone UTM zone (zero means UPS).
* @param[in] northp hemisphere (true means north, false means south).
* @param[in] easting (meters).
* @param[in] northing (meters).
* @exception GeographicErr if \e zone, \e easting, or \e northing is
* outside its allowed range.
********************************************************************** / ********************************************************************** /
void Reset(int zone, bool northp, real easting, real northing) { void Reset(int zone, bool northp, real easting, real northing) {
UTMUPS::Reverse(zone, northp, easting, northing, UTMUPS::Reverse(zone, northp, easting, northing,
_lat, _long, _gamma, _k); _lat, _long, _gamma, _k);
_zone = zone; _zone = zone;
_northp = northp; _northp = northp;
_easting = easting; _easting = easting;
_northing = northing; _northing = northing;
FixHemisphere(); FixHemisphere();
CopyToAlt(); CopyToAlt();
skipping to change at line 292 skipping to change at line 325
///@} ///@}
/** \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.
* @exception GeographicErr if \e zone cannot be used for this location .
* *
* See UTMUPS::zonespec for more information on the interpretation of \ e * See UTMUPS::zonespec for more information on the interpretation of \ e
* zone. Note that \e zone == UTMUPS::STANDARD (the default) use the * zone. Note that \e zone == UTMUPS::STANDARD (the default) use the
* standard UPS or UTM zone, UTMUPS::MATCH does nothing retaining the * standard UPS or UTM zone, UTMUPS::MATCH does nothing retaining the
* existing alternate representation. Before this is called the altern ate * existing alternate representation. Before this is called the altern ate
* zone is the input zone. * zone is the input zone.
********************************************************************** / ********************************************************************** /
void SetAltZone(int zone = UTMUPS::STANDARD) const { void SetAltZone(int zone = UTMUPS::STANDARD) const {
if (zone == UTMUPS::MATCH) if (zone == UTMUPS::MATCH)
return; return;
skipping to change at line 349 skipping to change at line 383
/** \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).
* @param[in] swaplatlong if true give longitude first (default = false ) * @param[in] swaplatlong if true give longitude first (default = false )
* @exception std::bad_alloc if memory for the string can't be allocate d.
* @return decimal latitude/longitude string representation. * @return decimal latitude/longitude string representation.
* *
* Precision specifies accuracy of representation as follows: * Precision specifies accuracy of representation as follows:
* - prec = -5 (min), 1d * - prec = &minus;5 (min), 1&deg;
* - prec = 0, 10<sup>-5</sup>d (about 1m) * - prec = 0, 10<sup>&minus;5</sup>&deg; (about 1m)
* - prec = 3, 10<sup>-8</sup>d * - prec = 3, 10<sup>&minus;8</sup>&deg;
* - prec = 9 (max), 10<sup>-14</sup>d * - prec = 9 (max), 10<sup>&minus;14</sup>&deg;
********************************************************************** / ********************************************************************** /
std::string GeoRepresentation(int prec = 0, bool swaplatlong = false) c onst; std::string GeoRepresentation(int prec = 0, bool swaplatlong = false) c onst;
/** /**
* String representation with latitude and longitude as degrees, minute s, * String representation with latitude and longitude as degrees, minute s,
* seconds, and hemisphere. * seconds, and hemisphere.
* *
* @param[in] prec precision (relative to about 1m) * @param[in] prec precision (relative to about 1m)
* @param[in] swaplatlong if true give longitude first (default = false ) * @param[in] swaplatlong if true give longitude first (default = false )
* @param[in] dmssep if non-null, use as the DMS separator character * @param[in] dmssep if non-null, use as the DMS separator character
* (instead of d, ', &quot; delimiters). * (instead of d, ', &quot; delimiters).
* @exception std::bad_alloc if memory for the string can't be allocate d.
* @return DMS latitude/longitude string representation. * @return DMS latitude/longitude string representation.
* *
* Precision specifies accuracy of representation as follows: * Precision specifies accuracy of representation as follows:
* - prec = -5 (min), 1d * - prec = &minus;5 (min), 1&deg;
* - prec = -4, 0.1d * - prec = &minus;4, 0.1&deg;
* - prec = -3, 1' * - prec = &minus;3, 1'
* - prec = -2, 0.1' * - prec = &minus;2, 0.1'
* - prec = -1, 1&quot; * - prec = &minus;1, 1&quot;
* - prec = 0, 0.1&quot; (about 3m) * - prec = 0, 0.1&quot; (about 3m)
* - prec = 1, 0.01&quot; * - prec = 1, 0.01&quot;
* - prec = 10 (max), 10<sup>-11</sup>&quot; * - prec = 10 (max), 10<sup>&minus;11</sup>&quot;
********************************************************************** / ********************************************************************** /
std::string DMSRepresentation(int prec, bool swaplatlong, char dmssep) std::string DMSRepresentation(int prec, bool swaplatlong, char dmssep)
const; const;
/** /**
* String representation with latitude and longitude as degrees, minute s, * String representation with latitude and longitude as degrees, minute s,
* seconds, and hemisphere. * seconds, and hemisphere.
* *
* @param[in] prec precision (relative to about 1m) * @param[in] prec precision (relative to about 1m)
* @param[in] swaplatlong if true give longitude first (default = false ) * @param[in] swaplatlong if true give longitude first (default = false )
* @exception std::bad_alloc if memory for the string can't be allocate d.
* @return DMS latitude/longitude string representation. * @return DMS latitude/longitude string representation.
* *
* <b>COMPATIBILITY NOTE:</b> This function calls * <b>COMPATIBILITY NOTE:</b> This function calls
* DMSRepresentation(int, bool, char) const with a 3rd argument of * DMSRepresentation(int, bool, char) const with a 3rd argument of
* char(0). At some point, DMSRepresentation(int, bool) const and * char(0). At some point, DMSRepresentation(int, bool) const and
* will be withdrawn and the interface to * will be withdrawn and the interface to
* DMSRepresentation(int, bool, char) const changed so that its * DMSRepresentation(int, bool, char) const changed so that its
* arguments have default values. This will preserve source-level * arguments have default values. This will preserve source-level
* compatibility. * compatibility.
********************************************************************** / ********************************************************************** /
std::string DMSRepresentation(int prec = 0, bool swaplatlong = false) c onst; std::string DMSRepresentation(int prec = 0, bool swaplatlong = false) c onst;
/** /**
* 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.
* @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 -2 (100m) is 38SMB441847 and not 38SMB442848 * coordinate at precision &minus;2 (100m) is 38SMB441847 and not
. * 38SMB442848. \e prec specifies the precision of the MGRS string as
* \e prec specifies the precision of the MGRS string as follows: * follows:
* - prec = -5 (min), 100km * - prec = &minus;5 (min), 100km
* - prec = -4, 10km * - prec = &minus;4, 10km
* - prec = -3, 1km * - prec = &minus;3, 1km
* - prec = -2, 100m * - prec = &minus;2, 100m
* - prec = -1, 10m * - prec = &minus;1, 10m
* - prec = 0, 1m * - prec = 0, 1m
* - prec = 1, 0.1m * - prec = 1, 0.1m
* - prec = 6 (max), 1um * - 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)
* @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 = -5 (min), 100km * - prec = &minus;5 (min), 100km
* - prec = -3, 1km * - prec = &minus;3, 1km
* - prec = 0, 1m * - prec = 0, 1m
* - prec = 3, 1mm * - prec = 3, 1mm
* - prec = 6, 1um * - 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) 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).
* @exception std::bad_alloc if memory for the string can't be allocate
d.
* @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)
* @exception std::bad_alloc if memory for the string can't be allocate
d.
* @return UTM/UPS string representation: zone designator, easting, and
* northing.
********************************************************************** / ********************************************************************** /
std::string AltUTMUPSRepresentation(int prec = 0) const; std::string AltUTMUPSRepresentation(int prec = 0) 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).
* *
 End of changes. 25 change blocks. 
46 lines changed or deleted 97 lines changed or added


 Geocentric.hpp   Geocentric.hpp 
/** /**
* \file Geocentric.hpp * \file Geocentric.hpp
* \brief Header for GeographicLib::Geocentric class * \brief Header for GeographicLib::Geocentric class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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_GEOCENTRIC_HPP) #if !defined(GEOGRAPHICLIB_GEOCENTRIC_HPP)
#define GEOGRAPHICLIB_GEOCENTRIC_HPP \ #define GEOGRAPHICLIB_GEOCENTRIC_HPP 1
"$Id: e9f709c85e61f60509c492429061cba04350eea8 $"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief %Geocentric coordinates * \brief %Geocentric coordinates
* *
* Convert between geodetic coordinates latitude = \e lat, longitude = \e * Convert between geodetic coordinates latitude = \e lat, longitude = \e
* lon, height = \e h (measured vertically from the surface of the ellips oid) * lon, height = \e h (measured vertically from the surface of the ellips oid)
* to geocentric coordinates (\e X, \e Y, \e Z). The origin of geocentri c * to geocentric coordinates (\e X, \e Y, \e Z). The origin of geocentri c
* coordinates is at the center of the earth. The \e Z axis goes thru th e * coordinates is at the center of the earth. The \e Z axis goes thru th e
* north pole, \e lat = 90<sup>o</sup>. The \e X axis goes thru \e lat = 0, * north pole, \e lat = 90°. The \e X axis goes thru \e lat = 0,
* \e lon = 0. %Geocentric coordinates are also known as earth centered, * \e lon = 0. %Geocentric coordinates are also known as earth centered,
* earth fixed (ECEF) coordinates. * earth fixed (ECEF) coordinates.
* *
* The conversion from geographic to geocentric coordinates is * The conversion from geographic to geocentric coordinates is
* straightforward. For the reverse transformation we use * straightforward. For the reverse transformation we use
* - H. Vermeille, * - H. Vermeille,
* <a href="http://dx.doi.org/10.1007/s00190-002-0273-6"> Direct * <a href="http://dx.doi.org/10.1007/s00190-002-0273-6"> Direct
* transformation from geocentric coordinates to geodetic coordinates</ a>, * transformation from geocentric coordinates to geodetic coordinates</ a>,
* J. Geodesy 76, 451&ndash;454 (2002). * J. Geodesy 76, 451&ndash;454 (2002).
* . * .
skipping to change at line 110 skipping to change at line 109
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.
* * @exception GeographicLib if \e a or (1 &minus; \e f ) \e a is not
* An exception is thrown if either of the axes of the ellipsoid is * positive.
* non-positive.
********************************************************************** / ********************************************************************** /
Geocentric(real a, real f); Geocentric(real a, real f);
/** /**
* A default constructor (for use by NormalGravity). * A default constructor (for use by NormalGravity).
********************************************************************** / ********************************************************************** /
Geocentric() : _a(-1) {} Geocentric() : _a(-1) {}
/** /**
* Convert from geodetic to geocentric coordinates. * Convert from geodetic to geocentric 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 geocentric coordinate (meters). * @param[out] X geocentric coordinate (meters).
* @param[out] Y geocentric coordinate (meters). * @param[out] Y geocentric coordinate (meters).
* @param[out] Z geocentric coordinate (meters). * @param[out] Z geocentric coordinate (meters).
* *
* \e lat should be in the range [-90, 90]; \e lon and \e lon0 should b * \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
e in * should be in the range [&minus;540&deg;, 540&deg;).
* the range [-180, 360].
********************************************************************** / ********************************************************************** /
void Forward(real lat, real lon, real h, real& X, real& Y, real& Z) void Forward(real lat, real lon, real h, real& X, real& Y, real& Z)
const throw() { const throw() {
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.
skipping to change at line 161 skipping to change at line 159
* matrix in row-major order. * matrix in row-major order.
* *
* Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
* express \e v as \e column vectors in one of two ways * express \e v as \e column vectors in one of two ways
* - 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 . \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 throw() {
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()); copy(t, t + dim2_, M.begin());
skipping to change at line 191 skipping to change at line 189
* @param[in] Z geocentric coordinate (meters). * @param[in] Z geocentric coordinate (meters).
* @param[out] lat latitude of point (degrees). * @param[out] lat latitude of point (degrees).
* @param[out] lon longitude of point (degrees). * @param[out] lon longitude of point (degrees).
* @param[out] h height of point above the ellipsoid (meters). * @param[out] h height of point above the ellipsoid (meters).
* *
* In general there are multiple solutions and the result which maximiz es * In general there are multiple solutions and the result which maximiz es
* \e h is returned. If there are still multiple solutions with differ ent * \e h is returned. If there are still multiple solutions with differ ent
* 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 >= - \e a (1 - * returned. The value of \e h returned satisfies \e h &ge; &minus; \e
* <i>e</i><sup>2</sup>) / sqrt(1 - <i>e</i><sup>2</sup> sin<sup>2</sup a
>\e * (1 &minus; <i>e</i><sup>2</sup>) / sqrt(1 &minus; <i>e</i><sup>2</su
* lat). The value of \e lon returned is in the range [-180, 180). p>
* sin<sup>2</sup>\e lat). The value of \e lon returned is in the rang
e
* [&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 throw() {
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.
* *
skipping to change at line 221 skipping to change at line 220
* matrix in row-major order. * matrix in row-major order.
* *
* Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
* express \e v as \e column vectors in one of two ways * express \e v as \e column vectors in one of two ways
* - 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 v1 = \e M^T . \e v0, where \e M^T is the transpose o * Then we have \e v1 = \e M<sup>T</sup> &sdot; \e v0, where \e
f \e * M<sup>T</sup> is the transpose of \e M.
* 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 throw() {
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()); copy(t, t + dim2_, M.begin());
 End of changes. 7 change blocks. 
17 lines changed or deleted 16 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-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2011) <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 \ #define GEOGRAPHICLIB_GEODESIC_HPP 1
"$Id: df63b56b6cca3c80859b8d0448745800b40106fc $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if !defined(GEOD_ORD) #if !defined(GEOD_ORD)
/** /**
* The order of the expansions used by Geodesic. * The order of the expansions used by Geodesic.
**********************************************************************/ **********************************************************************/
#define GEOD_ORD \ # define GEOD_ORD \
(GEOGRAPHICLIB_PREC == 1 ? 6 : (GEOGRAPHICLIB_PREC == 0 ? 3 : 7)) (GEOGRAPHICLIB_PREC == 1 ? 6 : (GEOGRAPHICLIB_PREC == 0 ? 3 : 7))
#endif #endif
namespace GeographicLib { namespace GeographicLib {
class GeodesicLine; class GeodesicLine;
/** /**
* \brief %Geodesic calculations * \brief %Geodesic calculations
* *
skipping to change at line 54 skipping to change at line 53
* *
* Given \e lat1, \e lon1, \e lat2, and \e lon2, we can determine \e azi1 , \e * Given \e lat1, \e lon1, \e lat2, and \e lon2, we can determine \e azi1 , \e
* azi2, and \e s12. This is the \e inverse geodesic problem, whose solu tion * azi2, and \e s12. This is the \e inverse geodesic problem, whose solu tion
* is given by Geodesic::Inverse. Usually, the solution to the inverse * is given by Geodesic::Inverse. Usually, the solution to the inverse
* problem is unique. In cases where there are multiple solutions (all w ith * problem is unique. In cases where there are multiple solutions (all w ith
* the same \e s12, of course), all the solutions can be easily generated * the same \e s12, of course), all the solutions can be easily generated
* once a particular solution is provided. * once a particular solution is provided.
* *
* The standard way of specifying the direct problem is the specify the * The standard way of specifying the direct problem is the specify the
* distance \e s12 to the second point. However it is sometimes useful * distance \e s12 to the second point. However it is sometimes useful
* instead to specify the the arc length \e a12 (in degrees) on the auxil iary * instead to specify the arc length \e a12 (in degrees) on the auxiliary
* sphere. This is a mathematical construct used in solving the geodesic * sphere. This is a mathematical construct used in solving the geodesic
* problems. The solution of the direct problem in this form is provide by * problems. The solution of the direct problem in this form is provide by
* Geodesic::ArcDirect. An arc length in excess of 180<sup>o</sup> indic ates * Geodesic::ArcDirect. An arc length in excess of 180° indicates
* that the geodesic is not a shortest path. In addition, the arc length * that the geodesic is not a shortest path. In addition, the arc length
* between an equatorial crossing and the next extremum of latitude for a * between an equatorial crossing and the next extremum of latitude for a
* geodesic is 90<sup>o</sup>;. * geodesic is 90°;.
* *
* This class can also calculate several other quantities related to * This class can also calculate several other quantities related to
* geodesics. These are: * geodesics. These are:
* - <i>reduced length</i>. If we fix the first point and increase \e az i1 * - <i>reduced length</i>. If we fix the first point and increase \e az i1
* by \e dazi1 (radians), the the second point is displaced \e m12 \e d * by \e dazi1 (radians), the second point is displaced \e m12 \e dazi1
azi1 in
* in the direction \e azi2 + 90<sup>o</sup>. The quantity \e m12 is * the direction \e azi2 + 90&deg;. The quantity \e m12 is called
* called the "reduced length" and is symmetric under interchange of th * the "reduced length" and is symmetric under interchange of the two
e * points. On a curved surface the reduced length obeys a symmetry
* two points. On a curved surface the reduced length obeys a symmetry
* relation, \e m12 + \e m21 = 0. On a flat surface, we have \e m12 = \e * relation, \e m12 + \e m21 = 0. On a flat surface, we have \e m12 = \e
* s12. The ratio <i>s12</i>/\e m12 gives the azimuthal scale for an * s12. The ratio <i>s12</i>/\e m12 gives the azimuthal scale for an
* azimuthal equidistant projection. * azimuthal equidistant projection.
* - <i>geodesic scale</i>. Consider a reference geodesic and a second * - <i>geodesic scale</i>. Consider a reference geodesic and a second
* geodesic parallel to this one at point 1 and separated by a small * geodesic parallel to this one at point 1 and separated by a small
* distance \e dt. The separation of the two geodesics at point 2 is \ e * distance \e dt. The separation of the two geodesics at point 2 is \ e
* M12 \e dt where \e M12 is called the "geodesic scale". \e M21 is * M12 \e dt where \e M12 is called the "geodesic scale". \e M21 is
* defined similarly (with the geodesics being parallel at point 2). O n a * defined similarly (with the geodesics being parallel at point 2). O n a
* flat surface, we have \e M12 = \e M21 = 1. The quantity 1/\e M12 gi ves * flat surface, we have \e M12 = \e M21 = 1. The quantity 1/\e M12 gi ves
* the scale of the Cassini-Soldner projection. * the scale of the Cassini-Soldner projection.
skipping to change at line 95 skipping to change at line 94
* polygon. * polygon.
* *
* Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and
* Geodesic::Inverse allow these quantities to be returned. In addition * Geodesic::Inverse allow these quantities to be returned. In addition
* there are general functions Geodesic::GenDirect, and Geodesic::GenInve rse * there are general functions Geodesic::GenDirect, and Geodesic::GenInve rse
* which allow an arbitrary set of results to be computed. The quantitie s \e * which allow an arbitrary set of results to be computed. The quantitie s \e
* m12, \e M12, \e M21 which all specify the behavior of nearby geodesics * m12, \e M12, \e M21 which all specify the behavior of nearby geodesics
* obey addition rules. Let points 1, 2, and 3 all lie on a single geode sic, * obey addition rules. Let points 1, 2, and 3 all lie on a single geode sic,
* then * then
* - \e m13 = \e m12 \e M23 + \e m23 \e M21 * - \e m13 = \e m12 \e M23 + \e m23 \e M21
* - \e M13 = \e M12 \e M23 - (1 - \e M12 \e M21) \e m23 / \e m12 * - \e M13 = \e M12 \e M23 &minus; (1 &minus; \e M12 \e M21) \e m23 / \e
* - \e M31 = \e M32 \e M21 - (1 - \e M23 \e M32) \e m12 / \e m23 m12
* - \e M31 = \e M32 \e M21 &minus; (1 &minus; \e M23 \e M32) \e m12 / \e
m23
* *
* Additional functionality is provided by the GeodesicLine class, which * Additional functionality is provided by the GeodesicLine class, which
* allows a sequence of points along a geodesic to be computed. * allows a sequence of points along a geodesic to be computed.
* *
* The calculations are accurate to better than 15 nm (15 nanometers). S ee * The calculations are accurate to better than 15 nm (15 nanometers). S ee
* Sec. 9 of * Sec. 9 of
* <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a>
* for details. * for details.
* *
* The algorithms are described in * The algorithms are described in
* - C. F. F. Karney, * - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1102.1215v1">Geodesics * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* on an ellipsoid of revolution</a>, * Algorithms for geodesics</a>,
* Feb. 2011; * J. Geodesy, 2012;
* preprint * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a>. * 10.1007/s00190-012-0578-z</a>.
* - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1109.4448">Algorithms for geodesics</a
>,
* Sept. 2011;
* preprint
* <a href="http://arxiv.org/abs/1109.4448">arxiv:1109.4448</a>.
* . * .
* For more information on geodesics see \ref geodesic. * For more information on geodesics see \ref geodesic.
* *
* Example of use: * Example of use:
* \include example-Geodesic.cpp * \include example-Geodesic.cpp
* *
* <a href="Geod.1.html">Geod</a> is a command-line utility providing acc ess * <a href="Geod.1.html">Geod</a> is a command-line utility providing acc ess
* to the functionality of Geodesic and GeodesicLine. * to the functionality of Geodesic and GeodesicLine.
**********************************************************************/ **********************************************************************/
skipping to change at line 165 skipping to change at line 159
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(); throw();
static inline real AngNormalize(real x) throw() {
// Place angle in [-180, 180). Assumes x is in [-540, 540).
return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x);
}
static inline real AngRound(real x) throw() { static inline real AngRound(real x) throw() {
// 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 = real(0.0625); // 1/16 const real z = real(0.0625); // 1/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;
skipping to change at line 302 skipping to change at line 292
/** \name Constructor /** \name Constructor
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* 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.
* * @exception GeographicLib if \e a or (1 &minus; \e f ) \e a is not
* An exception is thrown if either of the axes of the ellipsoid is * positive.
* non-positive.
********************************************************************** / ********************************************************************** /
Geodesic(real a, real f); Geodesic(real a, real f);
///@} ///@}
/** \name Direct geodesic problem specified in terms of distance. /** \name Direct geodesic problem specified in terms of distance.
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Perform the direct geodesic calculation where the length of the geod esic * Perform the direct geodesic calculation where the length of the geod esic
* is specify in terms of distance. * is specify in terms of distance.
skipping to change at line 332 skipping to change at line 321
* @param[out] lon2 longitude of point 2 (degrees). * @param[out] lon2 longitude of point 2 (degrees).
* @param[out] azi2 (forward) azimuth at point 2 (degrees). * @param[out] azi2 (forward) azimuth at point 2 (degrees).
* @param[out] m12 reduced length of geodesic (meters). * @param[out] m12 reduced length of geodesic (meters).
* @param[out] M12 geodesic scale of point 2 relative to point 1 * @param[out] M12 geodesic scale of point 2 relative to point 1
* (dimensionless). * (dimensionless).
* @param[out] M21 geodesic scale of point 1 relative to point 2 * @param[out] M21 geodesic scale of point 1 relative to point 2
* (dimensionless). * (dimensionless).
* @param[out] S12 area under the geodesic (meters<sup>2</sup>). * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
* @return \e a12 arc length of between point 1 and point 2 (degrees). * @return \e a12 arc length of between point 1 and point 2 (degrees).
* *
* \e lat1 should be in the range [-90, 90]; \e lon1 and \e azi1 should * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 an
be d \e
* in the range [-180, 360]. The values of \e lon2 and \e azi2 returne * azi1 should be in the range [&minus;540&deg;, 540&deg;). The values
d of
* are in the range [-180, 180). * \e lon2 and \e azi2 returned are in the range [&minus;180&deg;,
* 180&deg;).
* *
* 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 and writing \e lat = 90 - \e eps or -90 + \e eps and * longitude fixed and writing \e lat = 90&deg; &minus; &epsilon; or
* taking the limit \e eps -> 0 from above. An arc length greater that * &minus;90&deg; + &epsilon; and taking the limit &epsilon; &rarr; 0 f
180 rom
* degrees signifies a geodesic which is not a shortest path. (For a * above. An arc length greater that 180&deg; signifies a geodesic whi
* prolate ellipsoid, an additional condition is necessary for a shorte ch
st * is not a shortest path. (For a prolate ellipsoid, an additional
* path: the longitudinal extent must not exceed of 180 degrees.) * condition is necessary for a shortest 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 throw() {
real t; real t;
skipping to change at line 445 skipping to change at line 436
* @param[out] lon2 longitude of point 2 (degrees). * @param[out] lon2 longitude of point 2 (degrees).
* @param[out] azi2 (forward) azimuth at point 2 (degrees). * @param[out] azi2 (forward) azimuth at point 2 (degrees).
* @param[out] s12 distance between point 1 and point 2 (meters). * @param[out] s12 distance between point 1 and point 2 (meters).
* @param[out] m12 reduced length of geodesic (meters). * @param[out] m12 reduced length of geodesic (meters).
* @param[out] M12 geodesic scale of point 2 relative to point 1 * @param[out] M12 geodesic scale of point 2 relative to point 1
* (dimensionless). * (dimensionless).
* @param[out] M21 geodesic scale of point 1 relative to point 2 * @param[out] M21 geodesic scale of point 1 relative to point 2
* (dimensionless). * (dimensionless).
* @param[out] S12 area under the geodesic (meters<sup>2</sup>). * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
* *
* \e lat1 should be in the range [-90, 90]; \e lon1 and \e azi1 should * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 an
be d \e
* in the range [-180, 360]. The values of \e lon2 and \e azi2 returne * azi1 should be in the range [&minus;540&deg;, 540&deg;). The values
d of
* are in the range [-180, 180). * \e lon2 and \e azi2 returned are in the range [&minus;180&deg;,
* 180&deg;).
* *
* 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 and writing \e lat = 90 - \e eps or -90 + \e eps and * longitude fixed and writing \e lat = 90&deg; &minus; &epsilon; or
* taking the limit \e eps -> 0 from above. An arc length greater that * &minus;90&deg; + &epsilon; and taking the limit &epsilon; &rarr; 0 f
180 rom
* degrees signifies a geodesic which is not a shortest path. (For a * above. An arc length greater that 180&deg; signifies a geodesic whi
* prolate ellipsoid, an additional condition is necessary for a shorte ch
st * is not a shortest path. (For a prolate ellipsoid, an additional
* path: the longitudinal extent must not exceed of 180 degrees.) * condition is necessary for a shortest 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 throw() {
GenDirect(lat1, lon1, azi1, true, a12, GenDirect(lat1, lon1, azi1, true, a12,
LATITUDE | LONGITUDE | AZIMUTH | DISTANCE | LATITUDE | LONGITUDE | AZIMUTH | DISTANCE |
skipping to change at line 618 skipping to change at line 611
* @param[out] azi1 azimuth at point 1 (degrees). * @param[out] azi1 azimuth at point 1 (degrees).
* @param[out] azi2 (forward) azimuth at point 2 (degrees). * @param[out] azi2 (forward) azimuth at point 2 (degrees).
* @param[out] m12 reduced length of geodesic (meters). * @param[out] m12 reduced length of geodesic (meters).
* @param[out] M12 geodesic scale of point 2 relative to point 1 * @param[out] M12 geodesic scale of point 2 relative to point 1
* (dimensionless). * (dimensionless).
* @param[out] M21 geodesic scale of point 1 relative to point 2 * @param[out] M21 geodesic scale of point 1 relative to point 2
* (dimensionless). * (dimensionless).
* @param[out] S12 area under the geodesic (meters<sup>2</sup>). * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
* @return \e a12 arc length of between point 1 and point 2 (degrees). * @return \e a12 arc length of between point 1 and point 2 (degrees).
* *
* \e lat1 and \e lat2 should be in the range [-90, 90]; \e lon1 and \e * \e lat1 and \e lat2 should be in the range [&minus;90&deg;, 90&deg;]
* lon2 should be in the range [-180, 360]. The values of \e azi1 and ; \e
\e * lon1 and \e lon2 should be in the range [&minus;540&deg;, 540&deg;).
* azi2 returned are in the range [-180, 180). * The values of \e azi1 and \e azi2 returned are in the range
* [&minus;180&deg;, 180&deg;).
* *
* 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 and writing \e lat = 90 - \e eps or -90 + \e eps and * longitude fixed and writing \e lat = 90&deg; &minus; &epsilon; or
* taking the limit \e eps -> 0 from above. If the routine fails to * &minus;90&deg; + &epsilon; and taking the limit &epsilon; &rarr; 0 f
* converge, then all the requested outputs are set to Math::NaN(). (T rom
est * above. If the routine fails to converge, then all the requested out
* for such results with Math::isnan.) This is not expected to happen puts
with * are set to Math::NaN(). (Test for such results with Math::isnan.)
* ellipsoidal models of the earth; please report all cases where this This
* occurs. * is not expected to happen with ellipsoidal models of the earth; plea
se
* report all cases where this occurs.
* *
* 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 throw() {
return GenInverse(lat1, lon1, lat2, lon2, return GenInverse(lat1, lon1, lat2, lon2,
DISTANCE | AZIMUTH | DISTANCE | AZIMUTH |
skipping to change at line 772 skipping to change at line 766
* Set up to compute several points on a singe geodesic. * Set up to compute several points on a singe geodesic.
* *
* @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).
* @param[in] azi1 azimuth at point 1 (degrees). * @param[in] azi1 azimuth at point 1 (degrees).
* @param[in] caps bitor'ed combination of Geodesic::mask values * @param[in] caps bitor'ed combination of Geodesic::mask values
* specifying the capabilities the GeodesicLine object should possess , * specifying the capabilities the GeodesicLine object should possess ,
* i.e., which quantities can be returned in calls to * i.e., which quantities can be returned in calls to
* GeodesicLib::Position. * GeodesicLib::Position.
* *
* \e lat1 should be in the range [-90, 90]; \e lon1 and \e azi1 should * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 an
be d \e
* in the range [-180, 360]. * azi1 should be in the range [&minus;540&deg;, 540&deg;).
* *
* The Geodesic::mask values are * The Geodesic::mask values are
* - \e caps |= Geodesic::LATITUDE for the latitude \e lat2; this is * - \e caps |= Geodesic::LATITUDE for the latitude \e lat2; this is
* added automatically * added automatically
* - \e caps |= Geodesic::LONGITUDE for the latitude \e lon2 * - \e caps |= Geodesic::LONGITUDE for the latitude \e lon2
* - \e caps |= Geodesic::AZIMUTH for the latitude \e azi2; this is * - \e caps |= Geodesic::AZIMUTH for the latitude \e azi2; this is
* added automatically * added automatically
* - \e caps |= Geodesic::DISTANCE for the distance \e s12 * - \e caps |= Geodesic::DISTANCE for the distance \e s12
* - \e caps |= Geodesic::REDUCEDLENGTH for the reduced length \e m12 * - \e caps |= Geodesic::REDUCEDLENGTH for the reduced length \e m12
* - \e caps |= Geodesic::GEODESICSCALE for the geodesic scales \e M12 * - \e caps |= Geodesic::GEODESICSCALE for the geodesic scales \e M12
* and \e M21 * and \e M21
* - \e caps |= Geodesic::AREA for the area \e S12 * - \e caps |= Geodesic::AREA for the area \e S12
* - \e caps |= Geodesic::DISTANCE_IN permits the length of the * - \e caps |= Geodesic::DISTANCE_IN permits the length of the
* geodesic to be given in terms of \e s12; without this capability t he * geodesic to be given in terms of \e s12; without this capability t he
* length can only be specified in terms of arc length. * length can only be specified in terms of arc length.
* . * .
* The default value of \e caps is Geodesic::ALL which turns on all the * The default value of \e caps is Geodesic::ALL which turns on all the
* capabilities. * capabilities.
* *
* If the point is at a pole, the azimuth is defined by keeping the \e lon1 * If the point is at a pole, the azimuth is defined by keeping the \e lon1
* fixed and writing \e lat1 = 90 - \e eps or -90 + \e eps and taking t * fixed and writing \e lat1 = 90 &minus; &epsilon; or &minus;90 +
he * &epsilon; and taking the limit &epsilon; &rarr; 0 from above.
* limit \e eps -> 0 from above.
********************************************************************** / ********************************************************************** /
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 throw();
///@} ///@}
/** \name Inspector functions. /** \name Inspector functions.
********************************************************************** / ********************************************************************** /
///@{ ///@{
 End of changes. 18 change blocks. 
74 lines changed or deleted 71 lines changed or added


 GeodesicLine.hpp   GeodesicLine.hpp 
/** /**
* \file GeodesicLine.hpp * \file GeodesicLine.hpp
* \brief Header for GeographicLib::GeodesicLine class * \brief Header for GeographicLib::GeodesicLine class
* *
* Copyright (c) Charles Karney (2009-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2011) <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_GEODESICLINE_HPP) #if !defined(GEOGRAPHICLIB_GEODESICLINE_HPP)
#define GEOGRAPHICLIB_GEODESICLINE_HPP \ #define GEOGRAPHICLIB_GEODESICLINE_HPP 1
"$Id: 6d8b4f427813cac9195c1a3a9b785256b34d4e96 $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/Geodesic.hpp> #include <GeographicLib/Geodesic.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief A geodesic line * \brief A geodesic line
* *
* GeodesicLine facilitates the determination of a series of points on a * GeodesicLine facilitates the determination of a series of points on a
skipping to change at line 39 skipping to change at line 38
* The default copy constructor and assignment operators work with this * The default copy constructor and assignment operators work with this
* class. Similarly, a vector can be used to hold GeodesicLine objects. * class. Similarly, a vector can be used to hold GeodesicLine objects.
* *
* The calculations are accurate to better than 15 nm (15 nanometers). S ee * The calculations are accurate to better than 15 nm (15 nanometers). S ee
* Sec. 9 of * Sec. 9 of
* <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for * <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for
* details. * details.
* *
* The algorithms are described in * The algorithms are described in
* - C. F. F. Karney, * - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1102.1215v1">Geodesics * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* on an ellipsoid of revolution</a>, * Algorithms for geodesics</a>,
* Feb. 2011; * J. Geodesy, 2012;
* preprint * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* <a href="http://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a>. * 10.1007/s00190-012-0578-z</a>.
* - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1109.4448">Algorithms for geodesics</a
>,
* Sept. 2011;
* preprint
* <a href="http://arxiv.org/abs/1109.4448">arxiv:1109.4448</a>.
* . * .
* For more information on geodesics see \ref geodesic. * For more information on geodesics see \ref geodesic.
* *
* Example of use: * Example of use:
* \include example-GeodesicLine.cpp * \include example-GeodesicLine.cpp
* *
* <a href="Geod.1.html">Geod</a> is a command-line utility providing acc ess * <a href="Geod.1.html">Geod</a> is a command-line utility providing acc ess
* to the functionality of Geodesic and GeodesicLine. * to the functionality of Geodesic and GeodesicLine.
**********************************************************************/ **********************************************************************/
skipping to change at line 172 skipping to change at line 166
* about the GeodesicLine. * about the GeodesicLine.
* *
* @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).
* @param[in] azi1 azimuth at point 1 (degrees). * @param[in] azi1 azimuth at point 1 (degrees).
* @param[in] caps bitor'ed combination of GeodesicLine::mask values * @param[in] caps bitor'ed combination of GeodesicLine::mask values
* specifying the capabilities the GeodesicLine object should possess , * specifying the capabilities the GeodesicLine object should possess ,
* i.e., which quantities can be returned in calls to * i.e., which quantities can be returned in calls to
* GeodesicLib::Position. * GeodesicLib::Position.
* *
* \e lat1 should be in the range [-90, 90]; \e lon1 and \e azi1 should * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]; \e lon1 an
be d \e
* in the range [-180, 360]. * azi1 should be in the range [&minus;540&deg;, 540&deg;).
* *
* The GeodesicLine::mask values are * The GeodesicLine::mask values are
* - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this i s * - \e caps |= GeodesicLine::LATITUDE for the latitude \e lat2; this i s
* added automatically * added automatically
* - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2 * - \e caps |= GeodesicLine::LONGITUDE for the latitude \e lon2
* - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is * - \e caps |= GeodesicLine::AZIMUTH for the latitude \e azi2; this is
* added automatically * added automatically
* - \e caps |= GeodesicLine::DISTANCE for the distance \e s12 * - \e caps |= GeodesicLine::DISTANCE for the distance \e s12
* - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m 12 * - \e caps |= GeodesicLine::REDUCEDLENGTH for the reduced length \e m 12
* - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12 * - \e caps |= GeodesicLine::GEODESICSCALE for the geodesic scales \e M12
* and \e M21 * and \e M21
* - \e caps |= GeodesicLine::AREA for the area \e S12 * - \e caps |= GeodesicLine::AREA for the area \e S12
* - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the * - \e caps |= GeodesicLine::DISTANCE_IN permits the length of the
* geodesic to be given in terms of \e s12; without this capability t he * geodesic to be given in terms of \e s12; without this capability t he
* length can only be specified in terms of arc length. * length can only be specified in terms of arc length.
* . * .
* The default value of \e caps is GeodesicLine::ALL which turns on all the * The default value of \e caps is GeodesicLine::ALL which turns on all the
* capabilities. * capabilities.
* *
* If the point is at a pole, the azimuth is defined by keeping the \e lon1 * If the point is at a pole, the azimuth is defined by keeping the \e lon1
* fixed and writing \e lat1 = 90 - \e eps or -90 + \e eps and taking t * fixed and writing \e lat1 = 90&deg; &minus; &epsilon; or
he * &minus;90&deg; + &epsilon; and taking the limit &epsilon; &rarr; 0 f
* limit \e eps -> 0 from above. rom
* above.
********************************************************************** / ********************************************************************** /
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(); 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.
skipping to change at line 239 skipping to change at line 234
* (dimensionless); requires that the GeodesicLine object was constru cted * (dimensionless); requires that the GeodesicLine object was constru cted
* with \e caps |= GeodesicLine::GEODESICSCALE. * with \e caps |= GeodesicLine::GEODESICSCALE.
* @param[out] M21 geodesic scale of point 1 relative to point 2 * @param[out] M21 geodesic scale of point 1 relative to point 2
* (dimensionless); requires that the GeodesicLine object was constru cted * (dimensionless); requires that the GeodesicLine object was constru cted
* with \e caps |= GeodesicLine::GEODESICSCALE. * with \e caps |= GeodesicLine::GEODESICSCALE.
* @param[out] S12 area under the geodesic (meters<sup>2</sup>); requir es * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requir es
* that the GeodesicLine object was constructed with \e caps |= * that the GeodesicLine object was constructed with \e caps |=
* GeodesicLine::AREA. * GeodesicLine::AREA.
* @return \e a12 arc length of between point 1 and point 2 (degrees). * @return \e a12 arc length of between point 1 and point 2 (degrees).
* *
* The values of \e lon2 and \e azi2 returned are in the range [-180, 1 * The values of \e lon2 and \e azi2 returned are in the range
80). * [&minus;180&deg;, 180&deg;).
* *
* The GeodesicLine object \e must have been constructed with \e caps | = * The GeodesicLine object \e must have been constructed with \e caps | =
* GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no * GeodesicLine::DISTANCE_IN; otherwise Math::NaN() is returned and no
* parameters are set. Requesting a value which the GeodesicLine objec t is * parameters are set. Requesting a value which the GeodesicLine objec t is
* not capable of computing is not an error; the corresponding argument * not capable of computing is not an error; the corresponding argument
* 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
skipping to change at line 356 skipping to change at line 352
* @param[out] M12 geodesic scale of point 2 relative to point 1 * @param[out] M12 geodesic scale of point 2 relative to point 1
* (dimensionless); requires that the GeodesicLine object was constru cted * (dimensionless); requires that the GeodesicLine object was constru cted
* with \e caps |= GeodesicLine::GEODESICSCALE. * with \e caps |= GeodesicLine::GEODESICSCALE.
* @param[out] M21 geodesic scale of point 1 relative to point 2 * @param[out] M21 geodesic scale of point 1 relative to point 2
* (dimensionless); requires that the GeodesicLine object was constru cted * (dimensionless); requires that the GeodesicLine object was constru cted
* with \e caps |= GeodesicLine::GEODESICSCALE. * with \e caps |= GeodesicLine::GEODESICSCALE.
* @param[out] S12 area under the geodesic (meters<sup>2</sup>); requir es * @param[out] S12 area under the geodesic (meters<sup>2</sup>); requir es
* that the GeodesicLine object was constructed with \e caps |= * that the GeodesicLine object was constructed with \e caps |=
* GeodesicLine::AREA. * GeodesicLine::AREA.
* *
* The values of \e lon2 and \e azi2 returned are in the range [-180, 1 * The values of \e lon2 and \e azi2 returned are in the range
80). * [&minus;180&deg;, 180&deg;).
* *
* 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,
 End of changes. 6 change blocks. 
23 lines changed or deleted 17 lines changed or added


 Geohash.hpp   Geohash.hpp 
/** /**
* \file Geohash.hpp * \file Geohash.hpp
* \brief Header for GeographicLib::Geohash class * \brief Header for GeographicLib::Geohash class
* *
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_GEOHASH_HPP) #if !defined(GEOGRAPHICLIB_GEOHASH_HPP)
#define GEOGRAPHICLIB_GEOHASH_HPP \ #define GEOGRAPHICLIB_GEOHASH_HPP 1
"$Id: dbfced4af65871c0040168e0fe72bb1aeefd8248 $"
#include <string> #include <string>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs string // Squelch warnings about dll vs string
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Conversions for geohashes * \brief Conversions for geohashes
* *
* Geohashes are described in * Geohashes are described in
* - http://en.wikipedia.org/wiki/Geohash * - http://en.wikipedia.org/wiki/Geohash
* - http://geohash.org/ * - http://geohash.org/
skipping to change at line 63 skipping to change at line 62
public: public:
/** /**
* Convert from geographic coordinates to a geohash. * Convert from geographic coordinates to a geohash.
* *
* @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] len the length of the resulting geohash. * @param[in] len the length of the resulting geohash.
* @param[out] geohash the geohash. * @param[out] geohash the geohash.
* @exception GeographicErr if \e la is not in [&minus;90&deg;,
* 90&deg;].
* @exception GeographicErr if \e lon is not in [&minus;540&deg;,
* 540&deg;).
* @exception std::bad_alloc if memory for \e geohash can't be allocate
d.
* *
* \e lat should be in the range [-90, 90]; \e lon and \e lon0 should b * Internally, \e len is first put in the range [0, 18].
e in *
* the range [-180, 360]. Internally, \e len is first put in the range * If \e lat or \e lon is NaN, the returned geohash is "nan".
* [0, 18].
********************************************************************** / ********************************************************************** /
static void Forward(real lat, real lon, int len, std::string& geohash); static void Forward(real lat, real lon, int len, std::string& geohash);
/** /**
* Convert from a geohash to geographic coordinates. * Convert from a geohash to geographic coordinates.
* *
* @param[in] geohash the geohash. * @param[in] geohash the geohash.
* @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] len the length of the geohash. * @param[out] len the length of the geohash.
* @param[in] centerp if true (the default) return the center of the * @param[in] centerp if true (the default) return the center of the
* geohash location, otherwise return the south-west corner. * geohash location, otherwise return the south-west corner.
* @exception GeographicErr if \e geohash contains illegal characters.
* *
* Only the first 18 characters for \e geohash are considered. The cas e of * Only the first 18 characters for \e geohash are considered. The cas e of
* the letters in \e geohash is ignored. * the letters in \e geohash is ignored.
*
* If the first three characters in \e geohash are "nan", then \e lat a
nd
* \e lon are set to NaN.
********************************************************************** / ********************************************************************** /
static void Reverse(const std::string& geohash, real& lat, real& lon, static void Reverse(const std::string& geohash, real& lat, real& lon,
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).
* *
skipping to change at line 157 skipping to change at line 165
/** /**
* 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 [-2, 12]. * decimal precision is in the range [&minus;2, 12].
********************************************************************** / ********************************************************************** /
static int DecimalPrecision(int len) throw() { static int DecimalPrecision(int len) throw() {
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)
#endif #endif
#endif // GEOGRAPHICLIB_GEOHASH_HPP #endif // GEOGRAPHICLIB_GEOHASH_HPP
 End of changes. 8 change blocks. 
10 lines changed or deleted 19 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-2012) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2009-2012) <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 \ #define GEOGRAPHICLIB_GEOID_HPP 1
"$Id: 4e4eb5941d16ad00416798703d246a6f7ef5fe46 $"
#include <string> #include <string>
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs vector // Squelch warnings about dll vs vector
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
#if !defined(PGM_PIXEL_WIDTH) #if !defined(PGM_PIXEL_WIDTH)
/** /**
* The size of the pixel data in the pgm data files for the geoids. 2 * The size of the pixel data in the pgm data files for the geoids. 2 is t
* is the standard size corresponding to a maxval 2^16-1. Setting it he
* to 4 uses a maxval of 2^32-1 and changes the extension for the data * standard size corresponding to a maxval 2<sup>16</sup>&minus;1. Setting
* files from .pgm to .pgm4. Note that the format of these pgm4 files it
* to 4 uses a maxval of 2<sup>32</sup>&minus;1 and changes the extension f
or
* the data files from .pgm to .pgm4. Note that the format of these pgm4 f
iles
* is a non-standard extension of the pgm format. * is a non-standard extension of the pgm format.
**********************************************************************/ **********************************************************************/
#define PGM_PIXEL_WIDTH 2 # define PGM_PIXEL_WIDTH 2
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Looking up the height of the geoid * \brief Looking up the height of the geoid
* *
* This class evaluated the height of one of the standard geoids, EGM84, * This class evaluated the height of one of the standard geoids, EGM84,
* EGM96, or EGM2008 by bilinear or cubic interpolation into a rectangula r * EGM96, or EGM2008 by bilinear or cubic interpolation into a rectangula r
* grid of data. These geoid models are documented in * grid of data. These geoid models are documented in
skipping to change at line 214 skipping to change at line 213
///@{ ///@{
/** /**
* Construct a geoid. * Construct a geoid.
* *
* @param[in] name the name of the geoid. * @param[in] name the name of the geoid.
* @param[in] path (optional) directory for data file. * @param[in] path (optional) directory for data file.
* @param[in] cubic (optional) interpolation method; false means biline ar, * @param[in] cubic (optional) interpolation method; false means biline ar,
* true (the default) means cubic. * true (the default) means cubic.
* @param[in] threadsafe (optional), if true, construct a thread safe * @param[in] threadsafe (optional), if true, construct a thread safe
* object. The default is false * object. The default is false
* @exception GeographicErr if the data file cannot be found, is
* unreadable, or is corrupt.
* @exception GeographicErr if \e threadsafe is true but the memory
* necessary for caching the data can't be allocated.
* *
* The data file is formed by appending ".pgm" to the name. If \e path is * The data file is formed by appending ".pgm" to the name. If \e path is
* specified (and is non-empty), then the file is loaded from directory , \e * specified (and is non-empty), then the file is loaded from directory , \e
* path. Otherwise the path is given by DefaultGeoidPath(). This may * path. Otherwise the path is given by DefaultGeoidPath(). If the \e
* throw an exception because the file does not exist, is unreadable, o * threadsafe parameter is true, the data set is read into memory, the
r is data
* corrupt. If the \e threadsafe parameter is true, the data set is re * file is closed, and single-cell caching is turned off; this results
ad in a
* into memory (which this may also cause an exception to be thrown), t * Geoid object which \e is thread safe.
he
* data file is closed, and single-cell caching is turned off; this res
ults
* in a Geoid object which \e is thread safe.
********************************************************************** / ********************************************************************** /
explicit Geoid(const std::string& name, const std::string& path = "", explicit Geoid(const std::string& name, const std::string& path = "",
bool cubic = true, bool threadsafe = false); bool cubic = true, bool threadsafe = false);
/** /**
* Set up a cache. * Set up a cache.
* *
* @param[in] south latitude (degrees) of the south edge of the cached area. * @param[in] south latitude (degrees) of the south edge of the cached area.
* @param[in] west longitude (degrees) of the west edge of the cached a rea. * @param[in] west longitude (degrees) of the west edge of the cached a rea.
* @param[in] north latitude (degrees) of the north edge of the cached area. * @param[in] north latitude (degrees) of the north edge of the cached area.
* @param[in] east longitude (degrees) of the east edge of the cached a rea. * @param[in] east longitude (degrees) of the east edge of the cached a rea.
* @exception GeographicErr if the memory necessary for caching the dat
a
* can't be allocated (in this case, you will have no cache and can t
ry
* again with a smaller area).
* @exception GeographicErr if there's a problem reading the data.
* @exception GeographicErr if this is called on a threadsafe Geoid.
* *
* Cache the data for the specified "rectangular" area bounded by the * Cache the data for the specified "rectangular" area bounded by the
* parallels \e south and \e north and the meridians \e west and \e eas t. * parallels \e south and \e north and the meridians \e west and \e eas t.
* \e east is always interpreted as being east of \e west, if necessary by * \e east is always interpreted as being east of \e west, if necessary by
* adding 360<sup>o</sup> to its value. This may throw an error becaus * adding 360&deg; to its value. \e south and \e north should be in
e of * the range [&minus;90&deg;, 90&deg;]; \e west and \e east should
* insufficient memory or because of an error reading the data from the * be in the range [&minus;540&deg;, 540&deg;).
* file. In this case, you can catch the error and either do nothing (
you
* will have no cache in this case) or try again with a smaller area.
\e
* south and \e north should be in the range [-90, 90]; \e west and \e
east
* should be in the range [-180, 360]. An exception is thrown if this
* routine is called on a thread safe Geoid.
********************************************************************** / ********************************************************************** /
void CacheArea(real south, real west, real north, real east) const; void CacheArea(real south, real west, real north, real east) const;
/** /**
* Cache all the data. On most computers, this is fast for data sets w * Cache all the data.
ith *
* grid resolution of 5' or coarser. For a 1' grid, the required RAM i * @exception GeographicErr if the memory necessary for caching the dat
s a
* 450MB; a 2.5' grid needs 72MB; and a 5' grid needs 18MB. This may t * can't be allocated (in this case, you will have no cache and can t
hrow ry
* an error because of insufficient memory or because of an error readi * again with a smaller area).
ng * @exception GeographicErr if there's a problem reading the data.
* the data from the file. In this case, you can catch the error and * @exception GeographicErr if this is called on a threadsafe Geoid.
* either do nothing (you will have no cache in this case) or try using *
* Geoid::CacheArea on a specific area. An exception is thrown if this * On most computers, this is fast for data sets with grid resolution o
* routine is called on a thread safe Geoid. f 5'
* or coarser. For a 1' grid, the required RAM is 450MB; a 2.5' grid n
eeds
* 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 throw();
///@} ///@}
/** \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).
* @param[in] lon longitude of the point (degrees). * @param[in] lon longitude of the point (degrees).
* @exception GeographicErr if there's a problem reading the data; this
* 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 [-90, 90] and longitude should be in * The latitude should be in [&minus;90&deg;, 90&deg;] and
* [-180,360]. This may throw an error because of an error reading dat * longitude should be in [&minus;540&deg;, 540&deg;).
a
* from disk. However, it will not throw if (\e lat, \e lon) is within
a
* successfully cached area.
********************************************************************** / ********************************************************************** /
Math::real operator()(real lat, real lon) const { Math::real operator()(real lat, real lon) const {
real gradn, grade; real gradn, grade;
return height(lat, lon, false, gradn, grade); return height(lat, lon, false, gradn, grade);
} }
/** /**
* 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
* 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 [-90, 90] and longitude should be in [-180 * The latitude should be in [&minus;90&deg;, 90&deg;] and
, * longitude should be in [&minus;540&deg;, 540&deg;). As a result
* 360]. This may throw an error because of an error reading data from * of the way that the geoid data is stored, the calculation of gradien
* disk. However, it will not throw if (\e lat, \e lon) is within a ts
* successfully cached area. As a result of the way that the geoid dat * can result in large quantization errors. This is particularly acute
a is for
* stored, the calculation of gradients can result in large quantizatio * fine grids, at high latitudes, and for the easterly gradient. If yo
n u
* errors. This is particularly acute for fine grids, at high latitude * need to compute the direction of the acceleration due to gravity
s, * accurately, you should use GravityModel::Gravity.
* and for the easterly gradient. If you need to 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).
* @param[in] lon longitude of the point (degrees). * @param[in] lon longitude of the point (degrees).
* @param[in] h height of the point (degrees). * @param[in] h height of the point (degrees).
* @param[in] d a Geoid::convertflag specifying the direction of the * @param[in] d a Geoid::convertflag specifying the direction of the
* conversion; Geoid::GEOIDTOELLIPSOID means convert a height above t he * conversion; Geoid::GEOIDTOELLIPSOID means convert a height above t he
* geoid to a height above the ellipsoid; Geoid::ELLIPSOIDTOGEOID mea ns * geoid to a height above the ellipsoid; Geoid::ELLIPSOIDTOGEOID mea ns
* convert a height above the ellipsoid to a height above the geoid. * convert a height above the ellipsoid to a height above the geoid.
* @exception GeographicErr if there's a problem reading the data; this
* never happens if (\e lat, \e lon) is within a successfully cached
area.
* @return converted height (meters). * @return converted height (meters).
********************************************************************** / ********************************************************************** /
Math::real ConvertHeight(real lat, real lon, real h, Math::real ConvertHeight(real lat, real lon, real h,
convertflag d) const { convertflag d) const {
real gradn, grade; real gradn, grade;
return h + real(d) * height(lat, lon, true, gradn, grade); return h + real(d) * height(lat, lon, true, gradn, grade);
} }
///@} ///@}
skipping to change at line 374 skipping to change at line 381
* @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 -1. * absent, return &minus;1.
********************************************************************** / ********************************************************************** /
Math::real MaxError() const throw() { return _maxerror; } Math::real MaxError() const throw() { 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 -1. * absent, return &minus;1.
********************************************************************** / ********************************************************************** /
Math::real RMSError() const throw() { return _rmserror; } Math::real RMSError() const throw() { 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 throw() { return _offset; }
skipping to change at line 501 skipping to change at line 508
* it is just provided as a convenience for a calling program when * it is just provided as a convenience for a calling program when
* constructing a Geoid object. * constructing a Geoid object.
********************************************************************** / ********************************************************************** /
static std::string DefaultGeoidName(); static std::string DefaultGeoidName();
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning (pop) # pragma warning (pop)
#endif #endif
#endif // GEOGRAPHICLIB_GEOID_HPP #endif // GEOGRAPHICLIB_GEOID_HPP
 End of changes. 17 change blocks. 
65 lines changed or deleted 71 lines changed or added


 Gnomonic.hpp   Gnomonic.hpp 
/** /**
* \file Gnomonic.hpp * \file Gnomonic.hpp
* \brief Header for GeographicLib::Gnomonic class * \brief Header for GeographicLib::Gnomonic class
* *
* Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2010-2011) <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_GNOMONIC_HPP) #if !defined(GEOGRAPHICLIB_GNOMONIC_HPP)
#define GEOGRAPHICLIB_GNOMONIC_HPP \ #define GEOGRAPHICLIB_GNOMONIC_HPP 1
"$Id: 8b845d9465a032fdd4b5991d9a02c65599d79deb $"
#include <GeographicLib/Geodesic.hpp> #include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/GeodesicLine.hpp> #include <GeographicLib/GeodesicLine.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief %Gnomonic projection * \brief %Gnomonic projection
* *
* %Gnomonic projection centered at an arbitrary position \e C on the * %Gnomonic projection centered at an arbitrary position \e C on the
* ellipsoid. This projection is derived in Section 13 of * ellipsoid. This projection is derived in Section 8 of
* - C. F. F. Karney, * - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1102.1215v1">Geodesics * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* on an ellipsoid of revolution</a>, * Algorithms for geodesics</a>,
* Feb. 2011; * J. Geodesy, 2012;
* preprint * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* <a href="http://arxiv.org/abs/1102.1215v1">arxiv:1102.1215v1</a>. * 10.1007/s00190-012-0578-z</a>.
* . * .
* See also Section 8 of * The projection of \e P is defined as follows: compute the geodesic lin
* - C. F. F. Karney, e
* <a href="http://arxiv.org/abs/1109.4448">Algorithms for geodesics</a * from \e C to \e P; compute the reduced length \e m12, geodesic scale \
>, e
* Sept. 2011; * M12, and &rho; = <i>m12</i>/\e M12; finally \e x = &rho; sin \e azi1;
* preprint \e
* <a href="http://arxiv.org/abs/1109.4448">arxiv:1109.4448</a>. * y = &rho; cos \e azi1, where \e azi1 is the azimuth of the geodesic at
* . \e
* The projection of \e P is defined as follows: compute the * C. The Gnomonic::Forward and Gnomonic::Reverse methods also return th
* geodesic line from \e C to \e P; compute the reduced length \e m12, e
* geodesic scale \e M12, and \e rho = <i>m12</i>/\e M12; finally \e x = * azimuth \e azi of the geodesic at \e P and reciprocal scale \e rk in t
\e he
* rho sin \e azi1; \e y = \e rho cos \e azi1, where \e azi1 is the azimu * azimuthal direction. The scale in the radial direction if
th * 1/<i>rk</i><sup>2</sup>.
* of the geodesic at \e C. The Gnomonic::Forward and Gnomonic::Reverse
* methods also return the azimuth \e azi of the geodesic at \e P and
* reciprocal scale \e rk in the azimuthal direction. The scale in the
* radial direction if 1/<i>rk</i><sup>2</sup>.
* *
* For a sphere, \e rho is reduces to \e a tan(<i>s12</i>/<i>a</i>), wher e \e * For a sphere, &rho; is reduces to \e a tan(<i>s12</i>/<i>a</i>), where \e
* s12 is the length of the geodesic from \e C to \e P, and the gnomonic * s12 is the length of the geodesic from \e C to \e P, and the gnomonic
* projection has the property that all geodesics appear as straight line s. * projection has the property that all geodesics appear as straight line s.
* For an ellipsoid, this property holds only for geodesics interesting t he * For an ellipsoid, this property holds only for geodesics interesting t he
* centers. However geodesic segments close to the center are approximat ely * centers. However geodesic segments close to the center are approximat ely
* straight. * straight.
* *
* Consider a geodesic segment of length \e l. Let \e T be the point on the * Consider a geodesic segment of length \e l. Let \e T be the point on the
* geodesic (extended if necessary) closest to \e C the center of the * geodesic (extended if necessary) closest to \e C the center of the
* projection and \e t be the distance \e CT. To lowest order, the maxim um * projection and \e t be the distance \e CT. To lowest order, the maxim um
* deviation (as a true distance) of the corresponding gnomonic line segm ent * deviation (as a true distance) of the corresponding gnomonic line segm ent
* (i.e., with the same end points) from the geodesic is<br> * (i.e., with the same end points) from the geodesic is<br>
* <br> * <br>
* (<i>K</i>(<i>T</i>) - <i>K</i>(<i>C</i>)) * (<i>K</i>(<i>T</i>) - <i>K</i>(<i>C</i>))
* <i>l</i><sup>2</sup> \e t / 32.<br> * <i>l</i><sup>2</sup> \e t / 32.<br>
* <br> * <br>
* where \e K is the Gaussian curvature. * where \e K is the Gaussian curvature.
* *
* This result applies for any surface. For an ellipsoid of revolution, * This result applies for any surface. For an ellipsoid of revolution,
* consider all geodesics whose end points are within a distance \e r of \e * consider all geodesics whose end points are within a distance \e r of \e
* C. For a given \e r, the deviation is maximum when the latitude of \e C * C. For a given \e r, the deviation is maximum when the latitude of \e C
* is 45<sup>o</sup>, when endpoints are a distance \e r away, and when t * is 45&deg;, when endpoints are a distance \e r away, and when their
heir * azimuths from the center are &plusmn; 45&deg; or &plusmn; 135&deg;.
* azimuths from the center are +/- 45<sup>o</sup> or +/- 135<sup>o</sup>
.
* To lowest order in \e r and the flattening \e f, the deviation is \e f * To lowest order in \e r and the flattening \e f, the deviation is \e f
* (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r. * (<i>r</i>/2<i>a</i>)<sup>3</sup> \e r.
* *
* The conversions all take place using a Geodesic object (by default * The conversions all take place using a Geodesic object (by default
* Geodesic::WGS84). For more information on geodesics see \ref geodesic . * Geodesic::WGS84). For more information on geodesics see \ref geodesic .
* *
* <b>CAUTION:</b> The definition of this projection for a sphere is * <b>CAUTION:</b> The definition of this projection for a sphere is
* standard. However, there is no standard for how it should be extended to * standard. However, there is no standard for how it should be extended to
* an ellipsoid. The choices are: * an ellipsoid. The choices are:
* - Declare that the projection is undefined for an ellipsoid. * - Declare that the projection is undefined for an ellipsoid.
skipping to change at line 94 skipping to change at line 86
* This was proposed by independently by Bowring and Williams in 1997. * This was proposed by independently by Bowring and Williams in 1997.
* - Project to the conformal sphere with the constant of integration cho sen * - Project to the conformal sphere with the constant of integration cho sen
* so that the values of the latitude match for the center point and * so that the values of the latitude match for the center point and
* perform a central projection onto the plane tangent to the conformal * perform a central projection onto the plane tangent to the conformal
* sphere at the center point. This causes normal sections through the * sphere at the center point. This causes normal sections through the
* center point to appear as straight lines in the projection; i.e., it * center point to appear as straight lines in the projection; i.e., it
* generalizes the spherical great circle to a normal section. This wa s * generalizes the spherical great circle to a normal section. This wa s
* proposed by I. G. Letoval'tsev, Generalization of the %Gnomonic * proposed by I. G. Letoval'tsev, Generalization of the %Gnomonic
* Projection for a Spheroid and the Principal Geodetic Problems Involv ed * Projection for a Spheroid and the Principal Geodetic Problems Involv ed
* in the Alignment of Surface Routes, Geodesy and Aerophotography (5), * in the Alignment of Surface Routes, Geodesy and Aerophotography (5),
* 271-274 (1963). * 271&ndash;274 (1963).
* - The projection given here. This causes geodesics close to the cente r * - The projection given here. This causes geodesics close to the cente r
* point to appear as straight lines in the projection; i.e., it * point to appear as straight lines in the projection; i.e., it
* generalizes the spherical great circle to a geodesic. * generalizes the spherical great circle to a geodesic.
* *
* Example of use: * Example of use:
* \include example-Gnomonic.cpp * \include example-Gnomonic.cpp
* *
* <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utili ty * <a href="GeodesicProj.1.html">GeodesicProj</a> is a command-line utili ty
* providing access to the functionality of AzimuthalEquidistant, Gnomoni c, * providing access to the functionality of AzimuthalEquidistant, Gnomoni c,
* and CassiniSoldner. * and CassiniSoldner.
skipping to change at line 142 skipping to change at line 134
* *
* @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).
* @param[out] azi azimuth of geodesic at point (degrees). * @param[out] azi azimuth of geodesic at point (degrees).
* @param[out] rk reciprocal of azimuthal scale at point. * @param[out] rk reciprocal of azimuthal scale at point.
* *
* \e lat0 and \e lat should be in the range [-90, 90] and \e lon0 and * \e lat0 and \e lat should be in the range [&minus;90&deg;, 90&deg;]
\e and
* lon should be in the range [-180, 360]. The scale of the projection * \e lon0 and \e lon should be in the range [&minus;540&deg;, 540&deg;
is ).
* 1/<i>rk</i><sup>2</sup> in the "radial" direction, \e azi clockwise * The scale of the projection is 1/<i>rk</i><sup>2</sup> in the "radia
from l"
* true north, and is 1/\e rk in the direction perpendicular to this. * direction, \e azi clockwise from true north, and is 1/\e rk in the
If * direction perpendicular to this. If the point lies "over the horizo
* the point lies "over the horizon", i.e., if \e rk <= 0, then NaNs ar n",
e * i.e., if \e rk &le; 0, then NaNs are returned for \e x and \e y (the
* returned for \e x and \e y (the correct values are returned for \e a * correct values are returned for \e azi and \e rk). A call to Forwar
zi d
* and \e rk). A call to Forward followed by a call to Reverse will re * followed by a call to Reverse will return the original (\e lat, \e l
turn on)
* the original (\e lat, \e lon) (to within roundoff) provided the poin * (to within roundoff) provided the point in not over the horizon.
t 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 throw();
/** /**
* 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).
* @param[out] azi azimuth of geodesic at point (degrees). * @param[out] azi azimuth of geodesic at point (degrees).
* @param[out] rk reciprocal of azimuthal scale at point. * @param[out] rk reciprocal of azimuthal scale at point.
* *
* \e lat0 should be in the range [-90, 90] and \e lon0 should be in th * \e lat0 should be in the range [&minus;90&deg;, 90&deg;] and \e
e * lon0 should be in the range [&minus;540&deg;, 540&deg;). \e lat
* range [-180, 360]. \e lat will be in the range [-90, 90] and \e lon * will be in the range [&minus;90&deg;, 90&deg;] and \e lon will
* will be in the range [-180, 180). The scale of the projection is 1/ * be in the range [&minus;180&deg;, 180&deg;). The scale of the
\e * projection is 1/\e rk<sup>2</sup> in the "radial" direction, \e azi
* rk<sup>2</sup> in the "radial" direction, \e azi clockwise from true * clockwise from true north, and is 1/\e rk in the direction perpendic
* north, and is 1/\e rk in the direction perpendicular to this. Even ular
* though all inputs should return a valid \e lat and \e lon, it's poss * to this. Even though all inputs should return a valid \e lat and \e
ible * lon, it's possible that the procedure fails to converge for very lar
* that the procedure fails to converge for very large \e x or \e y; in ge
* this case NaNs are returned for all the output arguments. A call to * \e x or \e y; in this case NaNs are returned for all the output
* Reverse followed by a call to Forward will return the original (\e x * arguments. A call to Reverse followed by a call to Forward will ret
, \e urn
* 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 throw();
/** /**
* 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 throw() {
real azi, rk; real azi, rk;
 End of changes. 10 change blocks. 
64 lines changed or deleted 55 lines changed or added


 GravityCircle.hpp   GravityCircle.hpp 
/** /**
* \file GravityCircle.hpp * \file GravityCircle.hpp
* \brief Header for GeographicLib::GravityCircle class * \brief Header for GeographicLib::GravityCircle class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_GRAVITYCIRCLE_HPP) #if !defined(GEOGRAPHICLIB_GRAVITYCIRCLE_HPP)
#define GEOGRAPHICLIB_GRAVITYCIRCLE_HPP \ #define GEOGRAPHICLIB_GRAVITYCIRCLE_HPP 1
"$Id: 6ae0869411185a48c9f55016e6d1fb14e69aaac1 $"
#include <string> #include <string>
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/CircularEngine.hpp> #include <GeographicLib/CircularEngine.hpp>
#include <GeographicLib/GravityModel.hpp> #include <GeographicLib/GravityModel.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Gravity on a circle of latitude * \brief Gravity on a circle of latitude
* *
* Evaluate the earth's gravity field on a circle of constant height and * Evaluate the earth's gravity field on a circle of constant height and
* latitude. This uses a CircleEngine to pre-evaluate the inner sum of t he * latitude. This uses a CircularEngine to pre-evaluate the inner sum of the
* spherical harmonic sum, allowing the values of the field at several * spherical harmonic sum, allowing the values of the field at several
* different longitudes to be evaluated rapidly. * different longitudes to be evaluated rapidly.
* *
* Use GravityModel::Circle to create a GravityCircle object. (The * Use GravityModel::Circle to create a GravityCircle object. (The
* constructor for this class is private.) * constructor for this class is private.)
* *
* See \ref gravityparallel for an example of using GravityCircle (togeth er * See \ref gravityparallel for an example of using GravityCircle (togeth er
* with OpenMP) to speed up the computation of geoid heights. * with OpenMP) to speed up the computation of geoid heights.
* *
* Example of use: * Example of use:
skipping to change at line 117 skipping to change at line 116
GravityCircle() : _a(-1) {} GravityCircle() : _a(-1) {}
/** \name Compute the gravitational field /** \name Compute the gravitational field
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Evaluate the gravity. * Evaluate the gravity.
* *
* @param[in] lon the geographic longitude (degrees). * @param[in] lon the geographic longitude (degrees).
* @param[out] gx the easterly component of the acceleration * @param[out] gx the easterly component of the acceleration
* (m s<sup>-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>-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>-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 throw( );
/** /**
* 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>-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>-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>-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 throw();
/** /**
* 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
skipping to change at line 161 skipping to change at line 160
* 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 throw();
/** /**
* 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>-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 throw();
/** /**
* 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>-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>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e W = \e V + \e 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>-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 throw() {
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>-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>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e V = \e W - \e Phi the gravitational potential * @return \e V = \e W - &Phi; the gravitational potential
* (m<sup>2</sup> s<sup>-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 throw() {
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>-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>-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>-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>-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 throw() {
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>-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 throw() {
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
 End of changes. 20 change blocks. 
25 lines changed or deleted 24 lines changed or added


 GravityModel.hpp   GravityModel.hpp 
/** /**
* \file GravityModel.hpp * \file GravityModel.hpp
* \brief Header for GeographicLib::GravityModel class * \brief Header for GeographicLib::GravityModel class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_GRAVITYMODEL_HPP) #if !defined(GEOGRAPHICLIB_GRAVITYMODEL_HPP)
#define GEOGRAPHICLIB_GRAVITYMODEL_HPP \ #define GEOGRAPHICLIB_GRAVITYMODEL_HPP 1
"$Id: e1a573fb0148fa5bc408b2dbdb096d4cd3091bac $"
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/NormalGravity.hpp> #include <GeographicLib/NormalGravity.hpp>
#include <GeographicLib/SphericalHarmonic.hpp> #include <GeographicLib/SphericalHarmonic.hpp>
#include <GeographicLib/SphericalHarmonic1.hpp> #include <GeographicLib/SphericalHarmonic1.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs vector // Squelch warnings about dll vs vector
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
class GravityCircle; class GravityCircle;
/** /**
* \brief Model of the earth's gravity field * \brief Model of the earth's gravity field
* *
* Evaluate the earth's gravity field according to a model. The supporte d * Evaluate the earth's gravity field according to a model. The supporte d
* models treat only the gravitational field exterior to the mass of the * models treat only the gravitational field exterior to the mass of the
* earth. When computing the field at points near (but above) the surfac e of * earth. When computing the field at points near (but above) the surfac e of
* the earth a small correction can be applied to account for the mass of the * the earth a small correction can be applied to account for the mass of the
* atomsphere above the point in question; see \ref gravityatmos. * atomsphere above the point in question; see \ref gravityatmos.
* Determining the geoid height entails correcting for the mass of the ea rth * Determining the geoid height entails correcting for the mass of the ea rth
* above the geoid. The egm96 and egm2008 include separate correction te rms * above the geoid. The egm96 and egm2008 include separate correction te rms
* to account for this mass. * to account for this mass.
* *
* Definitions and terminology (from Heiskanen and Moritz, Sec 2-13): * Definitions and terminology (from Heiskanen and Moritz, Sec 2-13):
* - \e V = gravitational potential; * - \e V = gravitational potential;
* - \e Phi = rotational potential; * - &Phi; = rotational potential;
* - \e W = \e V + \e Phi = \e T + \e U = total potential; * - \e W = \e V + &Phi; = \e T + \e U = total potential;
* - <i>V</i><sub>0</sub> = normal gravitation potential; * - <i>V</i><sub>0</sub> = normal gravitation potential;
* - \e U = <i>V</i><sub>0</sub> + \e Phi = total normal potential; * - \e U = <i>V</i><sub>0</sub> + &Phi; = total normal potential;
* - \e T = \e W - \e U = \e V - <i>V</i><sub>0</sub> = anomalous or * - \e T = \e W &minus; \e U = \e V &minus; <i>V</i><sub>0</sub> = anoma
* disturbing potential; lous
* - <b>g</b> = <b>grad</b> \e W = <b>gamma</b> + <b>delta</b>; * or disturbing potential;
* - <b>f</b> = <b>grad</b> \e Phi; * - <b>g</b> = &nabla;\e W = <b>&gamma;</b> + <b>&delta;</b>;
* - <b>Gamma</b> = <b>grad</b> <i>V</i><sub>0</sub>; * - <b>f</b> = &nabla;&Phi;;
* - <b>gamma</b> = <b>grad</b> \e U; * - <b>&Gamma;</b> = &nabla;<i>V</i><sub>0</sub>;
* - <b>delta</b> = <b>grad</b> \e T = gravity disturbance vector * - <b>&gamma;</b> = &nabla;\e U;
* = <b>g</b><sub><i>P</i></sub> - <b>gamma</b><sub><i>P</i></sub>; * - <b>&delta;</b> = &nabla;\e T = gravity disturbance vector
* - delta \e g = gravity disturbance = \e g<sub><i>P</i></sub> - \e * = <b>g</b><sub><i>P</i></sub> &minus; <b>&gamma;</b><sub><i>P</i></s
* gamma<sub><i>P</i></sub>; ub>;
* - Delta <b>g</b> = gravity anomaly vector = * - &delta;\e g = gravity disturbance = \e g<sub><i>P</i></sub> &minus;
* <b>g</b><sub><i>P</i></sub> - <b>gamma</b><sub><i>Q</i></sub>; here * &gamma;<sub><i>P</i></sub>;
the * - &Delta;<b>g</b> = gravity anomaly vector = <b>g</b><sub><i>P</i></su
* line \e PQ is perpendicular to ellipsoid and the potential at \e P b>
* equals the normal potential at \e Q; * &minus; <b>&gamma;</b><sub><i>Q</i></sub>; here the line \e PQ is
* - Delta \e g = gravity anomaly = \e g<sub><i>P</i></sub> - \e * perpendicular to ellipsoid and the potential at \e P equals the norm
* gamma<sub><i>Q</i></sub>; al
* - (\e xi, \e eta) deflection of the vertical, the difference in * potential at \e Q;
* - &Delta;\e g = gravity anomaly = \e g<sub><i>P</i></sub> &minus;
* &gamma;<sub><i>Q</i></sub>;
* - (&xi;, &eta;) deflection of the vertical, the difference in
* directions of <b>g</b><sub><i>P</i></sub> and * directions of <b>g</b><sub><i>P</i></sub> and
* <b>gamma</b><sub><i>Q</i></sub>, \e xi = NS, \e eta = EW. * <b>&gamma;</b><sub><i>Q</i></sub>, &xi; = NS, &eta; = EW.
* - \e X, \e Y, \e Z, geocentric coordinates; * - \e X, \e Y, \e Z, geocentric coordinates;
* - \e x, \e y, \e z, local cartesian coordinates used to denote the eas t, * - \e x, \e y, \e z, local cartesian coordinates used to denote the eas t,
* north and up directions. * north and up directions.
* *
* See \ref gravity for details of how to install the gravity model and t he * See \ref gravity for details of how to install the gravity model and t he
* data format. * data format.
* *
* References: * References:
* - W. A. Heiskanen and H. Moritz, Physical Geodesy (Freeman, San * - W. A. Heiskanen and H. Moritz, Physical Geodesy (Freeman, San
* Francisco, 1967). * Francisco, 1967).
skipping to change at line 169 skipping to change at line 168
ALL = CAP_ALL, ALL = CAP_ALL,
}; };
/** \name Setting up the gravity model /** \name Setting up the gravity model
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Construct a gravity model. * Construct a gravity model.
* *
* @param[in] name the name of the model. * @param[in] name the name of the model.
* @param[in] path (optional) directory for data file. * @param[in] path (optional) directory for data file.
* @exception GeographicErr if the data file cannot be found, is
* unreadable, or is corrupt.
* @exception std::bad_alloc if the memory necessary for storing the mo
del
* can't be allocated.
* *
* A filename is formed by appending ".egm" (World Gravity Model) to th e * A filename is formed by appending ".egm" (World Gravity Model) to th e
* name. If \e path is specified (and is non-empty), then the file is * name. If \e path is specified (and is non-empty), then the file is
* loaded from directory, \e path. Otherwise the path is given by * loaded from directory, \e path. Otherwise the path is given by
* DefaultGravityPath(). This may throw an exception because the file * DefaultGravityPath().
does
* not exist, is unreadable, or is corrupt.
* *
* This file contains the metadata which specifies the properties of th e * This file contains the metadata which specifies the properties of th e
* model. The coefficients for the spherical harmonic sums are obtaine d * model. The coefficients for the spherical harmonic sums are obtaine d
* from a file obtained by appending ".cof" to metadata file (so the * from a file obtained by appending ".cof" to metadata file (so the
* filename ends in ".egm.cof"). * filename ends in ".egm.cof").
********************************************************************** / ********************************************************************** /
explicit GravityModel(const std::string& name, explicit GravityModel(const std::string& name,
const std::string& path = ""); const std::string& path = "");
///@} ///@}
skipping to change at line 196 skipping to change at line 198
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* 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] 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] gx the easterly component of the acceleration * @param[out] gx the easterly component of the acceleration
* (m s<sup>-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>-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>-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 throw();
/** /**
* 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>-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>-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>-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 throw();
/** /**
* Evaluate the geoid height. * Evaluate the geoid height.
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
skipping to change at line 249 skipping to change at line 251
********************************************************************** / ********************************************************************** /
Math::real GeoidHeight(real lat, real lon) const throw(); Math::real GeoidHeight(real lat, real lon) const throw();
/** /**
* 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>-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,
skipping to change at line 274 skipping to change at line 276
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* 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] gX the \e X component of the acceleration * @param[out] gX the \e X component of the acceleration
* (m s<sup>-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>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e W = \e V + \e 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>-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 throw();
/** /**
* 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>-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>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e V = \e W - \e Phi the gravitational potential * @return \e V = \e W - &Phi; the gravitational potential
* (m<sup>2</sup> s<sup>-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 throw();
/** /**
* 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>-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>-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>-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>-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 throw()
{ 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>-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 throw() {
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 * Evaluate the components of the acceleration due to normal gravity an
d the d
* 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).
* @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 normal acceleration * @param[out] gammaX the \e X component of the normal acceleration
* (m s<sup>-2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gammaY the \e Y component of the normal acceleration * @param[out] gammaY the \e Y component of the normal acceleration
* (m s<sup>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e U = <i>V</i><sub>0</sub> + \e 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>-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 throw()
{ 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>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e Phi the centrifugal potential (m<sup>2</sup> s<sup>-2</su * @return &Phi; the centrifugal potential (m<sup>2</sup>
p>). * 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 throw()
{ 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.
* *
* @param[in] lat latitude of the point (degrees). * @param[in] lat latitude 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[in] caps bitor'ed combination of GravityModel::mask values * @param[in] caps bitor'ed combination of GravityModel::mask values
* specifying the capabilities of the resulting GravityCircle object. * specifying the capabilities of the resulting GravityCircle object.
* @exception std::bad_alloc if the memory necessary for creating a
* GravityCircle can't be allocated.
* @return a GravityCircle object whose member functions computes the * @return a GravityCircle object whose member functions computes the
* gravitational field at a particular values of \e lon. * gravitational field at a particular values of \e lon.
* *
* The GravityModel::mask values are * The GravityModel::mask values are
* - \e caps |= GravityModel::GRAVITY * - \e caps |= GravityModel::GRAVITY
* - \e caps |= GravityModel::DISTURBANCE * - \e caps |= GravityModel::DISTURBANCE
* - \e caps |= GravityModel::DISTURBING_POTENTIAL * - \e caps |= GravityModel::DISTURBING_POTENTIAL
* - \e caps |= GravityModel::SPHERICAL_ANOMALY * - \e caps |= GravityModel::SPHERICAL_ANOMALY
* - \e caps |= GravityModel::GEOID_HEIGHT * - \e caps |= GravityModel::GEOID_HEIGHT
* . * .
skipping to change at line 458 skipping to change at line 463
* @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 throw() { 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 throw() { return _earth.MajorRadius(); }
/** /**
* @return \e GM the mass constant of the model * @return \e GM the mass constant of the model (m<sup>3</sup>
* (m<sup>3</sup> s<sup>-2</sup>); this is the product of \e G the * s<sup>&minus;2</sup>); this is the product of \e G the gravitation
* gravitational constant and \e M the mass of the earth (usually al
* including the mass of the earth's atmosphere). * constant and \e M the mass of the earth (usually including the mas
s of
* the earth's atmosphere).
********************************************************************** / ********************************************************************** /
Math::real MassConstant() const throw() { return _GMmodel; } Math::real MassConstant() const throw() { 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>-2</sup>). * (m<sup>3</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real ReferenceMassConstant() const throw() Math::real ReferenceMassConstant() const throw()
{ return _earth.MassConstant(); } { return _earth.MassConstant(); }
/** /**
* @return \e omega the angular velocity of the model and the * @return &omega; the angular velocity of the model and the
* ReferenceEllipsoid() (rad s<sup>-1</sup>). * ReferenceEllipsoid() (rad s<sup>&minus;1</sup>).
********************************************************************** / ********************************************************************** /
Math::real AngularVelocity() const throw() Math::real AngularVelocity() const throw()
{ 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 throw() { return _earth.Flattening(); }
///@} ///@}
skipping to change at line 511 skipping to change at line 516
* otherwise, it is "egm96". The GravityModel class does not use * otherwise, it is "egm96". The GravityModel class does not use
* this function; it is just provided as a convenience for a calling * this function; it is just provided as a convenience for a calling
* program when constructing a GravityModel object. * program when constructing a GravityModel object.
********************************************************************** / ********************************************************************** /
static std::string DefaultGravityName(); static std::string DefaultGravityName();
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning (pop) # pragma warning (pop)
#endif #endif
#endif // GEOGRAPHICLIB_GRAVITYMODEL_HPP #endif // GEOGRAPHICLIB_GRAVITYMODEL_HPP
 End of changes. 37 change blocks. 
71 lines changed or deleted 80 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, 2011) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2010-2012) <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 \ #define GEOGRAPHICLIB_LAMBERTCONFORMALCONIC_HPP 1
"$Id: 6b365254690f981dea955760b03204d7d8e00582 $"
#include <algorithm> #include <algorithm>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Lambert conformal conic projection * \brief Lambert conformal conic projection
* *
* Implementation taken from the report, * Implementation taken from the report,
skipping to change at line 64 skipping to change at line 63
* *
* <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 GEOGRAPHIC_EXPORT LambertConformalConic { class GEOGRAPHIC_EXPORT LambertConformalConic {
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; 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) throw() { 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 throw() {
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);
skipping to change at line 150 skipping to change at line 149
/** /**
* 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.
* @param[in] k0 scale on the standard parallel. * @param[in] k0 scale on the standard parallel.
* * @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k0 i
* An exception is thrown if \e a or \e k0 is not positive or if \e std s
lat * not positive.
* is not in the range [-90, 90]. * @exception GeographicErr if \e stdlat is not in [&minus;90&deg;,
* 90&deg;].
********************************************************************** / ********************************************************************** /
LambertConformalConic(real a, real f, real stdlat, real k0); LambertConformalConic(real a, real f, real stdlat, real k0);
/** /**
* Constructor with two standard parallels. * Constructor with two standard parallels.
* *
* @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] stdlat1 first standard parallel (degrees). * @param[in] stdlat1 first standard parallel (degrees).
* @param[in] stdlat2 second standard parallel (degrees). * @param[in] stdlat2 second standard parallel (degrees).
* @param[in] k1 scale on the standard parallels. * @param[in] k1 scale on the standard parallels.
* * @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k1 i
* An exception is thrown if \e a or \e k0 is not positive or if \e std s
lat1 * not positive.
* or \e stdlat2 is not in the range [-90, 90]. In addition, if either * @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
\e * [&minus;90&deg;, 90&deg;], or if either \e stdlat1 or \e
* stdlat1 or \e stdlat2 is a pole, then an exception is thrown if \e * stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2.
* stdlat1 is not equal \e stdlat2.
********************************************************************** / ********************************************************************** /
LambertConformalConic(real a, real f, real stdlat1, real stdlat2, real k1); LambertConformalConic(real a, real f, real stdlat1, real stdlat2, real k1);
/** /**
* Constructor with two standard parallels specified by sines and cosin es. * Constructor with two standard parallels specified by sines and cosin es.
* *
* @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] sinlat1 sine of first standard parallel. * @param[in] sinlat1 sine of first standard parallel.
* @param[in] coslat1 cosine of first standard parallel. * @param[in] coslat1 cosine of first standard parallel.
* @param[in] sinlat2 sine of second standard parallel. * @param[in] sinlat2 sine of second standard parallel.
* @param[in] coslat2 cosine of second standard parallel. * @param[in] coslat2 cosine of second standard parallel.
* @param[in] k1 scale on the standard parallels. * @param[in] k1 scale on the standard parallels.
* @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k1 i
s
* not positive.
* @exception GeographicErr if \e stdlat1 or \e stdlat2 is not in
* [&minus;90&deg;, 90&deg;], or if either \e stdlat1 or \e
* stdlat2 is a pole and \e stdlat1 is not equal \e stdlat2.
* *
* This allows parallels close to the poles to be specified accurately. * This allows parallels close to the poles to be specified accurately.
* This routine computes the latitude of origin and the scale at this * This routine computes the latitude of origin and the scale at this
* latitude. In the case where \e lat1 and \e lat2 are different, the * latitude. In the case where \e lat1 and \e lat2 are different, the
* errors in this routines are as follows: if \e dlat = abs(\e lat2 - \ * errors in this routines are as follows: if \e dlat = abs(\e lat2 &mi
e nus;
* lat1) <= 160<sup>o</sup> and max(abs(\e lat1), abs(\e lat2)) <= 90 - * \e lat1) &le; 160&deg; and max(abs(\e lat1), abs(\e lat2)) &le; 90
* min(0.0002, 2.2e-6(180 - \e dlat), 6e-8 <i>dlat</i><sup>2</sup>) (in * &minus; min(0.0002, 2.2 &times; 10<sup>&minus;6</sup>(180 &minus; \e
* degrees), then the error in the latitude of origin is less than * dlat), 6 &times 10<sup>&minus;8</sup> <i>dlat</i><sup>2</sup>) (in
* 4.5e-14<sup>o</sup> and the relative error in the scale is less than * degrees), then the error in the latitude of origin is less than 4.5
* 7e-15. * &times; 10<sup>&minus;14</sup>d and the relative error in the scale
is
* less than 7 &times; 10<sup>&minus;15</sup>.
********************************************************************** / ********************************************************************** /
LambertConformalConic(real a, real f, LambertConformalConic(real a, real f,
real sinlat1, real coslat1, real sinlat1, real coslat1,
real sinlat2, real coslat2, real sinlat2, real coslat2,
real k1); real k1);
/** /**
* Set the scale for the projection. * Set the scale for the projection.
* *
* @param[in] lat (degrees). * @param[in] lat (degrees).
* @param[in] k scale at latitude \e lat (default 1). * @param[in] k scale at latitude \e lat (default 1).
* * @exception GeographicLib \e k is not positive.
* This allows a "latitude of true scale" to be specified. An exceptio * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
n is * 90&deg;].
* thrown if \e k is not positive or if \e stdlat is not in the range [
-90,
* 90]
********************************************************************** / ********************************************************************** /
void SetScale(real lat, real k = real(1)); void SetScale(real lat, real k = real(1));
/** /**
* Forward projection, from geographic to Lambert conformal conic. * Forward projection, from geographic to Lambert conformal conic.
* *
* @param[in] lon0 central meridian longitude (degrees). * @param[in] lon0 central meridian longitude (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).
* @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 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
* [-90, 90]; \e lon and \e lon0 should be in the range [-180, 360]. T * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
he * range [&minus;540&deg;, 540&deg;). The error in the projection
* error in the projection is less than about 10 nm (10 nanometers), tr * is less than about 10 nm (10 nanometers), true distance, and the err
ue ors
* distance, and the errors in the meridian convergence and scale are * in the meridian convergence and scale are consistent with this. The
* consistent with this. The values of \e x and \e y returned for poin * values of \e x and \e y returned for points which project to infinit
ts y
* which project to infinity (i.e., one or both of the poles) will be l * (i.e., one or both of the poles) will be large but finite.
arge
* 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 throw();
/** /**
* 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).
* @param[out] k scale of projection at point. * @param[out] k scale of projection at point.
* *
* 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
* [-180, 360]. The value of \e lon returned is in the range [-180, 18 * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
0). * the range [&minus;180&deg;, 180&deg;). The error in the
* The error in the projection is less than about 10 nm (10 nanometers) * projection is less than about 10 nm (10 nanometers), true distance,
, and
* true distance, and the errors in the meridian convergence and scale * the errors in the meridian convergence and scale are consistent with
are * this.
* consistent with 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 throw();
/** /**
* 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 throw() {
 End of changes. 10 change blocks. 
45 lines changed or deleted 46 lines changed or added


 LocalCartesian.hpp   LocalCartesian.hpp 
/** /**
* \file LocalCartesian.hpp * \file LocalCartesian.hpp
* \brief Header for GeographicLib::LocalCartesian class * \brief Header for GeographicLib::LocalCartesian class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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_LOCALCARTESIAN_HPP) #if !defined(GEOGRAPHICLIB_LOCALCARTESIAN_HPP)
#define GEOGRAPHICLIB_LOCALCARTESIAN_HPP \ #define GEOGRAPHICLIB_LOCALCARTESIAN_HPP 1
"$Id: 31995a29f5216e6346a238edeedeb0e848452954 $"
#include <GeographicLib/Geocentric.hpp> #include <GeographicLib/Geocentric.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Local cartesian coordinates * \brief Local cartesian coordinates
* *
* Convert between geodetic coordinates latitude = \e lat, longitude = \e * Convert between geodetic coordinates latitude = \e lat, longitude = \e
skipping to change at line 62 skipping to change at line 61
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
* 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) throw()
: _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
skipping to change at line 87 skipping to change at line 89
throw() 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
* lon0 should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void Reset(real lat0, real lon0, real h0 = 0) void Reset(real lat0, real lon0, real h0 = 0) throw();
throw();
/** /**
* 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 [-90, 90]; \e lon and \e lon0 should b * \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
e in * should be in the range [&minus;540&deg;, 540&deg;).
* the range [-180, 360].
********************************************************************** / ********************************************************************** /
void Forward(real lat, real lon, real h, real& x, real& y, real& z) void Forward(real lat, real lon, real h, real& x, real& y, real& z)
const throw() { const throw() {
IntForward(lat, lon, h, x, y, z, NULL); 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).
* @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).
* @param[out] M if the length of the vector is 9, fill with the rotati on * @param[out] M if the length of the vector is 9, fill with the rotati on
* matrix in row-major order. * matrix in row-major order.
* *
* \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
* should be in the range [&minus;540&deg;, 540&deg;).
*
* Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
* express \e v as \e column vectors in one of two ways * express \e v as \e column vectors in one of two ways
* - 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 \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 . \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 throw() {
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()); copy(t, t + dim2_, M.begin());
} else } else
IntForward(lat, lon, h, x, y, z, NULL); IntForward(lat, lon, h, x, y, z, NULL);
skipping to change at line 154 skipping to change at line 161
/** /**
* 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 [-180, 180). * The value of \e lon returned is in the range [&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 throw() {
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.
* *
skipping to change at line 183 skipping to change at line 191
* *
* Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can * Let \e v be a unit vector located at (\e lat, \e lon, \e h). We can
* express \e v as \e column vectors in one of two ways * express \e v as \e column vectors in one of two ways
* - 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 \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^T . \e v0, where \e M^T is the transpose o * Then we have \e v1 = \e M<sup>T</sup> &sdot; \e v0, where \e
f \e * M<sup>T</sup> is the transpose of \e M.
* 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 throw() {
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()); copy(t, t + dim2_, M.begin());
} else } else
IntReverse(x, y, z, lat, lon, h, NULL); IntReverse(x, y, z, lat, lon, h, NULL);
 End of changes. 9 change blocks. 
12 lines changed or deleted 18 lines changed or added


 MGRS.hpp   MGRS.hpp 
/** /**
* \file MGRS.hpp * \file MGRS.hpp
* \brief Header for GeographicLib::MGRS class * \brief Header for GeographicLib::MGRS class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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_MGRS_HPP) #if !defined(GEOGRAPHICLIB_MGRS_HPP)
#define GEOGRAPHICLIB_MGRS_HPP "$Id: 80e08da6eca9d9cf92c5adad148c64302df257 3d $" #define GEOGRAPHICLIB_MGRS_HPP 1
#include <sstream> #include <sstream>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/UTMUPS.hpp> #include <GeographicLib/UTMUPS.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs string // Squelch warnings about dll vs string
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#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">
skipping to change at line 135 skipping to change at line 135
/** /**
* Convert UTM or UPS coordinate to an MGRS coordinate. * Convert UTM or UPS coordinate to an MGRS coordinate.
* *
* @param[in] zone UTM zone (zero means UPS). * @param[in] zone 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] 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
* allowed range.
* @exception GeographicErr if the memory for the MGRS string can't be
* allocated.
* *
* \e prec specifies the precision of the MGRS string as follows: * \e prec specifies the precision of the MGRS string as follows:
* - 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 um * - 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
* 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 [-9000 km, 9500 km] for the "northern" hemisphere * the northings are [&minus;9000 km, 9500 km] for the "northern"
and * hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.)
* [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 that 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
skipping to change at line 210 skipping to change at line 214
* Convert UTM or UPS coordinate to an MGRS coordinate when the latitud e is * Convert UTM or UPS coordinate to an MGRS coordinate when the latitud e is
* known. * known.
* *
* @param[in] zone UTM zone (zero means UPS). * @param[in] zone 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] 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] lat latitude (degrees). * @param[in] lat latitude (degrees).
* @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
* allowed range.
* @exception GeographicErr if \e lat is inconsistent with the given UT
M
* coordinates.
* @exception std::bad_alloc if the memory for \e mgrs can't be allocat
ed.
* *
* The latitude is ignored for \e zone = 0 (UPS); otherwise the latitud e is * The latitude is ignored for \e zone = 0 (UPS); otherwise the latitud e is
* used to determine the latitude band and this is checked for consiste ncy * used to determine the latitude band and this is checked for consiste ncy
* using the same tests as Reverse. * using the same tests as Reverse.
********************************************************************** / ********************************************************************** /
static void Forward(int zone, bool northp, real x, real y, real lat, static void Forward(int zone, bool northp, real x, real y, real lat,
int prec, std::string& mgrs); int prec, std::string& mgrs);
/** /**
* Convert a MGRS coordinate to UTM or UPS coordinates. * Convert a MGRS coordinate to UTM or UPS coordinates.
* *
* @param[in] mgrs MGRS string. * @param[in] mgrs MGRS string.
* @param[out] zone UTM zone (zero means UPS). * @param[out] zone 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).
* @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] prec precision relative to 100 km. * @param[out] prec precision relative to 100 km.
* @param[in] centerp if true (default), return center of the MGRS squa re, * @param[in] centerp if true (default), return center of the MGRS squa re,
* else return SW (lower left) corner. * else return SW (lower left) corner.
* @exception GeographicErr if \e mgrs is illegal.
* *
* All conversions from MGRS to UTM/UPS are permitted provided the MGRS * All conversions from MGRS to UTM/UPS are permitted provided the MGRS
* coordinate is a possible result of a conversion in the other directi on. * coordinate is a possible result of a conversion in the other directi on.
* (The leading 0 may be dropped from an input MGRS coordinate for UTM * (The leading 0 may be dropped from an input MGRS coordinate for UTM
* zones 1&ndash;9.) In addition, MGRS coordinates with a neighboring * zones 1&ndash;9.) In addition, MGRS coordinates with a neighboring
* latitude band letter are permitted provided that some portion of the * latitude band letter are permitted provided that some portion of the
* 100 km block is within the given latitude band. Thus * 100 km block is within the given latitude band. Thus
* - 38VLS and 38WLS are allowed (latitude 64N intersects the square * - 38VLS and 38WLS are allowed (latitude 64N intersects the square
* 38[VW]LS); but 38VMS is not permitted (all of 38VMS is north of 64N) * 38[VW]LS); but 38VMS is not permitted (all of 38VMS is north of 64N)
* - 38MPE and 38NPF are permitted (they straddle the equator); but 3 8NPE * - 38MPE and 38NPF are permitted (they straddle the equator); but 3 8NPE
skipping to change at line 250 skipping to change at line 260
* 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 an error is thrown, then the arguments are unchanged. * 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.
*
* 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).
skipping to change at line 289 skipping to change at line 302
* @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() throw()
{ 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
#endif // GEOGRAPHICLIB_MGRS_HPP #endif // GEOGRAPHICLIB_MGRS_HPP
 End of changes. 9 change blocks. 
9 lines changed or deleted 24 lines changed or added


 MagneticCircle.hpp   MagneticCircle.hpp 
/** /**
* \file MagneticCircle.hpp * \file MagneticCircle.hpp
* \brief Header for GeographicLib::MagneticCircle class * \brief Header for GeographicLib::MagneticCircle class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_MAGNETICCIRCLE_HPP) #if !defined(GEOGRAPHICLIB_MAGNETICCIRCLE_HPP)
#define GEOGRAPHICLIB_MAGNETICCIRCLE_HPP \ #define GEOGRAPHICLIB_MAGNETICCIRCLE_HPP 1
"$Id: 5b3adc58d894f36ca4206864eb565541f24ff492 $"
#include <string> #include <string>
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/CircularEngine.hpp> #include <GeographicLib/CircularEngine.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Geomagnetic field on a circle of latitude * \brief Geomagnetic field on a circle of latitude
* *
* Evaluate the earth's magnetic field on a circle of constant height and * Evaluate the earth's magnetic field on a circle of constant height and
* latitude. This uses a CircleEngine to pre-evaluate the inner sum of t he * latitude. This uses a CircularEngine to pre-evaluate the inner sum of the
* spherical harmonic sum, allowing the values of the field at several * spherical harmonic sum, allowing the values of the field at several
* different longitudes to be evaluated rapidly. * different longitudes to be evaluated rapidly.
* *
* Use MagneticModel::Circle to create a MagneticCircle object. (The * Use MagneticModel::Circle to create a MagneticCircle object. (The
* constructor for this class is private.) * constructor for this class is private.)
* *
* Example of use: * Example of use:
* \include example-MagneticCircle.cpp * \include example-MagneticCircle.cpp
* *
* <a href="MagneticField.1.html">MagneticField</a> is a command-line uti lity * <a href="MagneticField.1.html">MagneticField</a> is a command-line uti lity
 End of changes. 2 change blocks. 
3 lines changed or deleted 2 lines changed or added


 MagneticModel.hpp   MagneticModel.hpp 
/** /**
* \file MagneticModel.hpp * \file MagneticModel.hpp
* \brief Header for GeographicLib::MagneticModel class * \brief Header for GeographicLib::MagneticModel class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_MAGNETICMODEL_HPP) #if !defined(GEOGRAPHICLIB_MAGNETICMODEL_HPP)
#define GEOGRAPHICLIB_MAGNETICMODEL_HPP \ #define GEOGRAPHICLIB_MAGNETICMODEL_HPP 1
"$Id: 7f8c59ee3cdbfce252d1172c1bb4d7db7cf5ef38 $"
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/Geocentric.hpp> #include <GeographicLib/Geocentric.hpp>
#include <GeographicLib/SphericalHarmonic.hpp> #include <GeographicLib/SphericalHarmonic.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs vector // Squelch warnings about dll vs vector
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
class MagneticCircle; class MagneticCircle;
/** /**
* \brief Model of the earth's magnetic field * \brief Model of the earth's magnetic field
* *
* Evaluate the earth's magnetic field according to a model. At present only * Evaluate the earth's magnetic field according to a model. At present only
skipping to change at line 94 skipping to change at line 93
/** \name Setting up the magnetic model /** \name Setting up the magnetic model
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Construct a magnetic model. * Construct a magnetic model.
* *
* @param[in] name the name of the model. * @param[in] name the name of the model.
* @param[in] path (optional) directory for data file. * @param[in] path (optional) directory for data file.
* @param[in] earth (optional) Geocentric object for converting * @param[in] earth (optional) Geocentric object for converting
* coordinates; default Geocentric::WGS84. * coordinates; default Geocentric::WGS84.
* @exception GeographicErr if the data file cannot be found, is
* unreadable, or is corrupt.
* @exception std::bad_alloc if the memory necessary for storing the mo
del
* can't be allocated.
* *
* A filename is formed by appending ".wmm" (World Magnetic Model) to t he * A filename is formed by appending ".wmm" (World Magnetic Model) to t he
* name. If \e path is specified (and is non-empty), then the file is * name. If \e path is specified (and is non-empty), then the file is
* loaded from directory, \e path. Otherwise the path is given by the * loaded from directory, \e path. Otherwise the path is given by the
* DefaultMagneticPath(). This may throw an exception because the file * DefaultMagneticPath().
* does not exist, is unreadable, or is corrupt.
* *
* This file contains the metadata which specifies the properties of th e * This file contains the metadata which specifies the properties of th e
* model. The coefficients for the spherical harmonic sums are obtaine d * model. The coefficients for the spherical harmonic sums are obtaine d
* from a file obtained by appending ".cof" to metadata file (so the * from a file obtained by appending ".cof" to metadata file (so the
* filename ends in ".wwm.cof"). * filename ends in ".wwm.cof").
* *
* The model is not tied to a particular ellipsoidal model of the earth . * The model is not tied to a particular ellipsoidal model of the earth .
* The final earth argument to the constructor specify an ellipsoid to * The final earth argument to the constructor specifies an ellipsoid t o
* allow geodetic coordinates to the transformed into the spherical * allow geodetic coordinates to the transformed into the spherical
* coordinates used in the spherical harmonic sum. * coordinates used in the spherical harmonic sum.
********************************************************************** / ********************************************************************** /
explicit MagneticModel(const std::string& name, explicit MagneticModel(const std::string& name,
const std::string& path = "", const std::string& path = "",
const Geocentric& earth = Geocentric::WGS84); const Geocentric& earth = Geocentric::WGS84);
///@} ///@}
/** \name Compute the magnetic field /** \name Compute the magnetic field
********************************************************************** / ********************************************************************** /
skipping to change at line 167 skipping to change at line 169
} }
/** /**
* 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).
* @param[in] h the height of the point above the ellipsoid (meters). * @param[in] h the height of the point above the ellipsoid (meters).
* @exception std::bad_alloc if the memory necessary for creating a
* MagneticCircle can't be allocated.
* @return a MagneticCircle object whose MagneticCircle::operator()(rea l * @return a MagneticCircle object whose MagneticCircle::operator()(rea l
* lon) member function computes the field at particular values of \e * lon) member function computes the field at particular values of \e
* lon. * lon.
* *
* If the field at several points on a circle of latitude need to be * If the field at several points on a circle of latitude need to be
* calculated then creating a MagneticCircle and using its member funct ions * calculated then creating a MagneticCircle and using its member funct ions
* will be substantially faster, especially for high-degree models. * will be substantially faster, especially for high-degree models.
********************************************************************** / ********************************************************************** /
MagneticCircle Circle(real t, real lat, real h) const; MagneticCircle Circle(real t, real lat, real h) const;
skipping to change at line 339 skipping to change at line 343
* otherwise, it is "wmm2010". The MagneticModel class does not use th is * otherwise, it is "wmm2010". The MagneticModel class does not use th is
* function; it is just provided as a convenience for a calling program * function; it is just provided as a convenience for a calling program
* when constructing a MagneticModel object. * when constructing a MagneticModel object.
********************************************************************** / ********************************************************************** /
static std::string DefaultMagneticName(); static std::string DefaultMagneticName();
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning (pop) # pragma warning (pop)
#endif #endif
#endif // GEOGRAPHICLIB_MAGNETICMODEL_HPP #endif // GEOGRAPHICLIB_MAGNETICMODEL_HPP
 End of changes. 7 change blocks. 
8 lines changed or deleted 13 lines changed or added


 Math.hpp   Math.hpp 
skipping to change at line 15 skipping to change at line 15
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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 "$Id: edd244e4c5c74e696096c2b6d598728957a0d3 6d $" #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)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) # if defined(__GXX_EXPERIMENTAL_CXX0X__)
# 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
#if !defined(GEOGRAPHICLIB_PREC) #if !defined(GEOGRAPHICLIB_PREC)
/** /**
* The precision of floating point numbers used in %GeographicLib. 0 means * The precision of floating point numbers used in %GeographicLib. 0 means
* float; 1 (default) means double; 2 means long double. Nearly all the * float; 1 (default) means double; 2 means long double. Nearly all the
* testing has been carried out with doubles and that's the recommended * testing has been carried out with doubles and that's the recommended
* configuration. In order for long double to be used, HAVE_LONG_DOUBLE ne eds * configuration. In order for long double to be used, HAVE_LONG_DOUBLE ne eds
* to be defined. Note that with Microsoft Visual Studio, long double is t he * to be defined. Note that with Microsoft Visual Studio, long double is t he
* same as double. * same as double.
**********************************************************************/ **********************************************************************/
#define GEOGRAPHICLIB_PREC 1 # define GEOGRAPHICLIB_PREC 1
#endif #endif
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
namespace GeographicLib { namespace GeographicLib {
/** /**
skipping to change at line 97 skipping to change at line 97
typedef double real; typedef double real;
#elif GEOGRAPHICLIB_PREC == 0 #elif GEOGRAPHICLIB_PREC == 0
typedef float real; typedef float real;
#elif GEOGRAPHICLIB_PREC == 2 #elif GEOGRAPHICLIB_PREC == 2
typedef extended real; typedef extended real;
#else #else
typedef double real; typedef double real;
#endif #endif
/** /**
* 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 \e pi. * @return &pi;.
********************************************************************** / ********************************************************************** /
template<typename T> static inline T pi() throw() template<typename T> static inline T pi() throw()
{ 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() throw() { return pi<real>(); }
/** /**
* @tparam T the type of the returned value. * @tparam T the type of the returned value.
skipping to change at line 125 skipping to change at line 125
********************************************************************** / ********************************************************************** /
template<typename T> static inline T degree() throw() template<typename T> static inline T degree() throw()
{ 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() throw() { 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) throw()
{ 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.
skipping to change at line 155 skipping to change at line 155
T a = (std::max)(x, y), T a = (std::max)(x, y),
b = (std::min)(x, y) / (a ? a : 1); b = (std::min)(x, y) / (a ? a : 1);
return a * std::sqrt(1 + b * b); return a * std::sqrt(1 + b * b);
} }
#elif GEOGRAPHICLIB_CPLUSPLUS11_MATH #elif GEOGRAPHICLIB_CPLUSPLUS11_MATH
template<typename T> static inline T hypot(T x, T y) throw() template<typename T> static inline T hypot(T x, T y) throw()
{ return std::hypot(x, y); } { return std::hypot(x, y); }
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
static inline double hypot(double x, double y) throw() static inline double hypot(double x, double y) throw()
{ return _hypot(x, y); } { return _hypot(x, y); }
#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) throw()
{ 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) throw()
{ return _hypotf(x, y); } { return _hypotf(x, y); }
#endif # endif
#if defined(HAVE_LONG_DOUBLE) # if defined(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) throw()
{ return _hypot(x, y); } { return _hypot(x, y); }
#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) throw()
{ return ::hypot(x, y); } { return ::hypot(x, y); }
static inline float hypot(float x, float y) throw() static inline float hypot(float x, float y) throw()
{ return ::hypotf(x, y); } { return ::hypotf(x, y); }
#if defined(HAVE_LONG_DOUBLE) # if defined(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) throw()
{ 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) - 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) - 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) throw() {
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) throw()
{ 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) throw() { return ::expm1(x); }
static inline float expm1(float x) throw() { return ::expm1f(x); } static inline float expm1(float x) throw() { return ::expm1f(x); }
#if defined(HAVE_LONG_DOUBLE) # if defined(HAVE_LONG_DOUBLE)
static inline long double expm1(long double x) throw() static inline long double expm1(long double x) throw()
{ return ::expm1l(x); } { return ::expm1l(x); }
#endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_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.
skipping to change at line 240 skipping to change at line 240
// 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) throw()
{ 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) throw() { return ::log1p(x); }
static inline float log1p(float x) throw() { return ::log1pf(x); } static inline float log1p(float x) throw() { return ::log1pf(x); }
#if defined(HAVE_LONG_DOUBLE) # if defined(HAVE_LONG_DOUBLE)
static inline long double log1p(long double x) throw() static inline long double log1p(long double x) throw()
{ return ::log1pl(x); } { return ::log1pl(x); }
#endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_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
skipping to change at line 267 skipping to change at line 267
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) throw()
{ 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) throw() { return ::asinh(x); }
static inline float asinh(float x) throw() { return ::asinhf(x); } static inline float asinh(float x) throw() { return ::asinhf(x); }
#if defined(HAVE_LONG_DOUBLE) # if defined(HAVE_LONG_DOUBLE)
static inline long double asinh(long double x) throw() static inline long double asinh(long double x) throw()
{ return ::asinhl(x); } { return ::asinhl(x); }
#endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_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
skipping to change at line 294 skipping to change at line 294
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) throw()
{ 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) throw() { return ::atanh(x); }
static inline float atanh(float x) throw() { return ::atanhf(x); } static inline float atanh(float x) throw() { return ::atanhf(x); }
#if defined(HAVE_LONG_DOUBLE) # if defined(HAVE_LONG_DOUBLE)
static inline long double atanh(long double x) throw() static inline long double atanh(long double x) throw()
{ return ::atanhl(x); } { return ::atanhl(x); }
#endif # endif
#endif #endif
#if defined(DOXYGEN) || (defined(_MSC_VER) && !GEOGRAPHICLIB_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) throw() {
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) throw()
{ 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) throw() { return ::cbrt(x); }
static inline float cbrt(float x) throw() { return ::cbrtf(x); } static inline float cbrt(float x) throw() { return ::cbrtf(x); }
#if defined(HAVE_LONG_DOUBLE) # if defined(HAVE_LONG_DOUBLE)
static inline long double cbrt(long double x) throw() { return ::cbrtl( x); } static inline long double cbrt(long double x) throw() { return ::cbrtl( x); }
# endif
#endif #endif
#endif
/**
* Normalize an angle (restricted input range).
*
* @tparam T the type of the argument and returned value.
* @param[in] x the angle in degrees.
* @return the angle reduced to the range [&minus;180&deg;,
* 180&deg;).
*
* \e x must lie in [&minus;540&deg;, 540&deg;).
**********************************************************************
/
template<typename T> static inline T AngNormalize(T x) throw()
{ return x >= 180 ? x - 360 : (x < -180 ? x + 360 : x); }
/**
* Normalize an arbitrary angle.
*
* @tparam T the type of the argument and returned value.
* @param[in] x the angle in degrees.
* @return the angle reduced to the range [&minus;180&deg;,
* 180&deg;).
*
* The range of \e x is unrestricted.
**********************************************************************
/
template<typename T> static inline T AngNormalize2(T x) throw()
{ return AngNormalize<T>(std::fmod(x, T(360))); }
/** /**
* 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) throw() {
#if defined(DOXYGEN) #if defined(DOXYGEN)
 End of changes. 25 change blocks. 
25 lines changed or deleted 52 lines changed or added


 NormalGravity.hpp   NormalGravity.hpp 
/** /**
* \file NormalGravity.hpp * \file NormalGravity.hpp
* \brief Header for GeographicLib::NormalGravity class * \brief Header for GeographicLib::NormalGravity class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_NORMALGRAVITY_HPP) #if !defined(GEOGRAPHICLIB_NORMALGRAVITY_HPP)
#define GEOGRAPHICLIB_NORMALGRAVITY_HPP \ #define GEOGRAPHICLIB_NORMALGRAVITY_HPP 1
"$Id: e4b65c9c5787d8ee14f476cbb518fd5007006344 $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/Geocentric.hpp> #include <GeographicLib/Geocentric.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief The normal gravity of the earth * \brief The normal gravity of the earth
* *
* "Normal" gravity refers to an idealization of the earth which is model ed * "Normal" gravity refers to an idealization of the earth which is model ed
skipping to change at line 39 skipping to change at line 38
* There is a closed solution to this problem which is implemented here. * There is a closed solution to this problem which is implemented here.
* Series "approximations" are only used to evaluate certain combinations of * Series "approximations" are only used to evaluate certain combinations of
* elementary functions where use of the closed expression results in a l oss * elementary functions where use of the closed expression results in a l oss
* of accuracy for small arguments due to cancellation of the two leading * of accuracy for small arguments due to cancellation of the two leading
* terms. However these series include sufficient terms to give full mac hine * terms. However these series include sufficient terms to give full mac hine
* precision. * precision.
* *
* Definitions: * Definitions:
* - <i>V</i><sub>0</sub>, the gravitational contribution to the normal * - <i>V</i><sub>0</sub>, the gravitational contribution to the normal
* potential; * potential;
* - \e Phi, the rotational contribution to the normal potential; * - &Phi;, the rotational contribution to the normal potential;
* - \e U = <i>V</i><sub>0</sub> + \e Phi, the total * - \e U = <i>V</i><sub>0</sub> + &Phi;, the total
* potential; * potential;
* - <b>Gamma</b> = <b>grad</b> <i>V</i><sub>0</sub>, the acceleration du e to * - <b>&Gamma;</b> = &nabla;<i>V</i><sub>0</sub>, the acceleration due t o
* mass of the earth; * mass of the earth;
* - <b>f</b> = <b>grad</b> \e Phi, the centrifugal acceleration; * - <b>f</b> = &nabla;&Phi;, the centrifugal acceleration;
* - <b>gamma</b> = <b>grad</b> \e U = <b>Gamma</b> + <b>f</b>, the norma * - <b>&gamma;</b> = &nabla;\e U = <b>&Gamma;</b> + <b>f</b>, the normal
l
* acceleration; * acceleration;
* - \e X, \e Y, \e Z, geocentric coordinates; * - \e X, \e Y, \e Z, geocentric coordinates;
* - \e x, \e y, \e z, local cartesian coordinates used to denote the eas t, * - \e x, \e y, \e z, local cartesian coordinates used to denote the eas t,
* north and up directions. * north and up directions.
* *
* References: * References:
* - W. A. Heiskanen and H. Moritz, Physical Geodesy (Freeman, San * - W. A. Heiskanen and H. Moritz, Physical Geodesy (Freeman, San
* Francisco, 1967), Secs. 1-19, 2-7, 2-8 (2-9, 2-10), 6-2 (6-3). * Francisco, 1967), Secs. 1-19, 2-7, 2-8 (2-9, 2-10), 6-2 (6-3).
* - H. Moritz, Geodetic Reference System 1980, J. Geod. 54(3), 395-405 * - H. Moritz, Geodetic Reference System 1980, J. Geodesy 54(3), 395-405
* (1980) http://dx.doi.org/10.1007/BF02521480 * (1980) http://dx.doi.org/10.1007/BF02521480
* *
* Example of use: * Example of use:
* \include example-NormalGravity.cpp * \include example-NormalGravity.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHIC_EXPORT NormalGravity { class GEOGRAPHIC_EXPORT NormalGravity {
private: private:
static const int maxit_ = 10; static const int maxit_ = 10;
typedef Math::real real; typedef Math::real real;
skipping to change at line 85 skipping to change at line 84
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* 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
* (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \ e G * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \ e G
* the gravitational constant and \e M the mass of the earth (usually * the gravitational constant and \e M the mass of the earth (usually
* including the mass of the earth's atmosphere). * including the mass of the earth's atmosphere).
* @param[in] omega the angular velocity (rad s<sup>-1</sup>). * @param[in] omega the angular velocity (rad s<sup>&minus;1</sup>).
* @param[in] f the flattening of the ellipsoid. * @param[in] f the flattening of the ellipsoid.
* @param[in] J2 dynamical form factor. * @param[in] J2 dynamical form factor.
* @exception if \e a is not positive or the other constants are
* inconsistent (see below).
* *
* Exactly one of \e f and \e J2 should be positive and this will be us ed * Exactly one of \e f and \e J2 should be positive and this will be us ed
* to define the ellipsoid. The shape of the ellipsoid can be given in one * to define the ellipsoid. The shape of the ellipsoid can be given in one
* of two ways: * of two ways:
* - geometrically, the ellipsoid is defined by the flattening \e f = * - geometrically, the ellipsoid is defined by the flattening \e f = (
* (\e a - \e b) / \e a, where \e a and \e b are the equatorial radiu \e a
s * &minus; \e b) / \e a, where \e a and \e b are the equatorial radiu
s
* and the polar semi-axis. * and the polar semi-axis.
* - physically, the ellipsoid is defined by the dynamical form factor * - physically, the ellipsoid is defined by the dynamical form factor
* <i>J</i><sub>2</sub> = (\e C - \e A) / <i>Ma</i><sup>2</sup>, wher * <i>J</i><sub>2</sub> = (\e C &minus; \e A) / <i>Ma</i><sup>2</sup>
e \e ,
* A and \e C are the equatorial and polar moments of inertia and \e * where \e A and \e C are the equatorial and polar moments of inerti
M is a
* the mass of the earth. * and \e M is the mass of the earth.
********************************************************************** / ********************************************************************** /
NormalGravity(real a, real GM, real omega, real f, real J2); NormalGravity(real a, real GM, real omega, real f, real J2);
/** /**
* A default constructor for the normal gravity. This sets up an * A default constructor for the normal gravity. This sets up an
* uninitialized object and is used by GravityModel which constructs th is * uninitialized object and is used by GravityModel which constructs th is
* object before it has read in the parameters for the reference ellips oid. * object before it has read in the parameters for the reference ellips oid.
********************************************************************** / ********************************************************************** /
NormalGravity() : _a(-1) {} NormalGravity() : _a(-1) {}
///@} ///@}
/** \name Compute the gravity /** \name Compute the gravity
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
* Evaluate the gravity on the surface of the ellipsoid. * Evaluate the gravity on the surface of the ellipsoid.
* *
* @param[in] lat the geographic latitude (degrees). * @param[in] lat the geographic latitude (degrees).
* @return \e gamma the acceleration due to gravity, positive downwards * @return &gamma; the acceleration due to gravity, positive downwards
* (m s<sup>-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 throw();
/** /**
* 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>-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>-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 throw();
/** /**
* 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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gammaY the \e Y component of the acceleration * @param[out] gammaY the \e Y component of the acceleration
* (m s<sup>-2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] gammaZ the \e Z component of the acceleration * @param[out] gammaZ the \e Z component of the acceleration
* (m s<sup>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e U = <i>V</i><sub>0</sub> + \e 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>-2</sup>). * (m<sup>2</sup> s<sup>&minus;2</sup>).
* *
* The acceleration given by <b>gamma</b> = <b>grad</b> \e U = <b>grad< * The acceleration given by <b>&gamma;</b> = &nabla;\e U =
/b> * &nabla;<i>V</i><sub>0</sub> + &nabla;&Phi; = <b>&Gamma;</b> + <b>f</
* <i>V</i><sub>0</sub> + <b>grad</b> \e Phi = <b>Gamma</b> + <b>f</b>. 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 throw();
/** /**
* 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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] GammaY the \e Y component of the acceleration due to gra vity * @param[out] GammaY the \e Y component of the acceleration due to gra vity
* (m s<sup>-2</sup>). * (m s<sup>&minus;2</sup>).
* @param[out] GammaZ the \e Z component of the acceleration due to gra vity * @param[out] GammaZ the \e Z component of the acceleration due to gra vity
* (m s<sup>-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>-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 throw();
/** /**
* 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>-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>-2</sup>). * (m s<sup>&minus;2</sup>).
* @return \e Phi the centrifugal potential (m<sup>2</sup> s<sup>-2</su * @return &Phi; the centrifugal potential (m<sup>2</sup>
p>). * s<sup>&minus;2</sup>).
* *
* \e 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 throw();
///@} ///@}
/** \name Inspector functions /** \name Inspector functions
********************************************************************** / ********************************************************************** /
///@{ ///@{
/** /**
skipping to change at line 230 skipping to change at line 232
/** /**
* @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 throw()
{ 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>-2</sup>). This is the value used in the * (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 throw()
{ 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 is odd. In most gravity applications, fu * \e J<sub>n</sub> = 0 if \e n is odd. In most gravity applications,
lly * fully normalized Legendre functions are used and the corresponding
* normalized Legendre functions are used and the corresponding coeffic * coefficient is <i>C</i><sub><i>n</i>0</sub> = &minus;\e J<sub>n</sub
ient > /
* is <i>C</i><sub><i>n</i>0</sub> = -\e J<sub>n</sub> / sqrt(2 \e n + * sqrt(2 \e n + 1).
1).
********************************************************************** / ********************************************************************** /
Math::real DynamicalFormFactor(int n = 2) const throw() Math::real DynamicalFormFactor(int n = 2) const throw()
{ return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN<real>(); } { return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN<real>(); }
/** /**
* @return \e omega the angular velocity of the ellipsoid * @return &omega; the angular velocity of the ellipsoid (rad
* (rad s<sup>-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 throw()
{ return Init() ? _omega : Math::NaN<real>(); } { return Init() ? _omega : Math::NaN<real>(); }
/** /**
* @return <i>f</i> the flattening of the ellipsoid (\e a - \e b)/\e a. * @return <i>f</i> the flattening of the ellipsoid (\e a &minus; \e b)
/\e
* a.
********************************************************************** / ********************************************************************** /
Math::real Flattening() const throw() Math::real Flattening() const throw()
{ return Init() ? _f : Math::NaN<real>(); } { return Init() ? _f : Math::NaN<real>(); }
/** /**
* @return <i>gamma</i><sub>e</sub> the normal gravity at equator * @return &gamma;<sub>e</sub> the normal gravity at equator (m
* (m s<sup>-2</sup>). * s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real EquatorialGravity() const throw() Math::real EquatorialGravity() const throw()
{ return Init() ? _gammae : Math::NaN<real>(); } { return Init() ? _gammae : Math::NaN<real>(); }
/** /**
* @return <i>gamma</i><sub>p</sub> the normal gravity at poles * @return &gamma;<sub>p</sub> the normal gravity at poles (m
* (m s<sup>-2</sup>). * s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real PolarGravity() const throw() Math::real PolarGravity() const throw()
{ return Init() ? _gammap : Math::NaN<real>(); } { return Init() ? _gammap : Math::NaN<real>(); }
/** /**
* @return <i>f*</i> the gravity flattening * @return <i>f*</i> the gravity flattening (&gamma;<sub>p</sub> &minus
* (<i>gamma</i><sub>p</sub> - <i>gamma</i><sub>e</sub>) / ;
* <i>gamma</i><sub>e</sub>. * &gamma;<sub>e</sub>) / &gamma;<sub>e</sub>.
********************************************************************** / ********************************************************************** /
Math::real GravityFlattening() const throw() Math::real GravityFlattening() const throw()
{ 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>-2</sup>). * surface of the ellipsoid (m<sup>2</sup> s<sup>&minus;2</sup>).
********************************************************************** / ********************************************************************** /
Math::real SurfacePotential() const throw() Math::real SurfacePotential() const throw()
{ 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 throw() { return _earth; }
///@} ///@}
 End of changes. 32 change blocks. 
57 lines changed or deleted 59 lines changed or added


 OSGB.hpp   OSGB.hpp 
/** /**
* \file OSGB.hpp * \file OSGB.hpp
* \brief Header for GeographicLib::OSGB class * \brief Header for GeographicLib::OSGB class
* *
* Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2010-2011) <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_OSGB_HPP) #if !defined(GEOGRAPHICLIB_OSGB_HPP)
#define GEOGRAPHICLIB_OSGB_HPP "$Id: e91367e693ad63bb500c953e9c21445bef0174 64 $" #define GEOGRAPHICLIB_OSGB_HPP 1
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/TransverseMercator.hpp> #include <GeographicLib/TransverseMercator.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs string // Squelch warnings about dll vs string
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Ordnance Survey grid system for Great Britain * \brief Ordnance Survey grid system for Great Britain
* *
* The class implements the coordinate system used by the Ordnance Survey for * The class implements the coordinate system used by the Ordnance Survey for
* maps of Great Britain and conversions to the grid reference system. * maps of Great Britain and conversions to the grid reference system.
* *
skipping to change at line 83 skipping to change at line 83
/** /**
* 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 [-90, 90]; \e lon and \e lon0 should b * \e lat should be in the range [&minus;90&deg;, 90&deg;]; \e lon
e in * should be in the range [&minus;540&deg;, 540&deg;).
* the range [-180, 360].
********************************************************************** / ********************************************************************** /
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) throw() {
OSGBTM_.Forward(OriginLongitude(), lat, lon, x, y, gamma, k); OSGBTM_.Forward(OriginLongitude(), lat, lon, x, y, gamma, k);
x += FalseEasting(); x += FalseEasting();
y += northoffset_; y += northoffset_;
} }
/** /**
* 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 [-180, 180). * The value of \e lon returned is in the range [&minus;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) throw() {
x -= FalseEasting(); x -= FalseEasting();
y -= northoffset_; y -= northoffset_;
OSGBTM_.Reverse(OriginLongitude(), x, y, lat, lon, gamma, k); OSGBTM_.Reverse(OriginLongitude(), x, y, lat, lon, gamma, k);
} }
/** /**
skipping to change at line 136 skipping to change at line 137
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.
* @param[out] gridref National Grid reference. * @param[out] gridref National Grid reference.
* @exception GeographicErr if \e prec, \e x, or \e y is outside its
* allowed range.
* @exception std::bad_alloc if the memory for \e gridref can't be
* allocatied.
* *
* \e prec specifies the precision of the grid reference string as foll ows: * \e prec specifies the precision of the grid reference string as foll ows:
* - prec = 0 (min), 100km * - prec = 0 (min), 100km
* - prec = 1, 10km * - prec = 1, 10km
* - prec = 2, 1km * - prec = 2, 1km
* - prec = 3, 100m * - prec = 3, 100m
* - prec = 4, 10m * - prec = 4, 10m
* - prec = 5, 1m * - prec = 5, 1m
* - prec = 6, 0.1m * - prec = 6, 0.1m
* - prec = 11 (max), 1um * - prec = 11 (max), 1&mu;m
* *
* The easting must be in the range [-1000 km, 1500 km) and the northin * The easting must be in the range [&minus;1000 km, 1500 km) and the
g * northing must be in the range [&minus;500 km, 2000 km). These bound
* must be in the range [-500 km, 2000 km). An exception is thrown if s
* either the easting and northing is outside these bounds. These boun
ds
* are consistent with rules for the letter designations for the grid * are consistent with rules for the letter designations for the grid
* system. * system.
********************************************************************** / ********************************************************************** /
static void GridReference(real x, real y, int prec, std::string& gridre f); static void GridReference(real x, real y, int prec, std::string& gridre f);
/** /**
* Convert OSGB coordinates to a grid reference. * Convert OSGB coordinates to a grid reference.
* *
* @param[in] gridref National Grid reference. * @param[in] gridref National Grid reference.
* @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] prec precision relative to 100 km. * @param[out] prec precision relative to 100 km.
* @param[in] centerp if true (default), return center of the grid squa re, * @param[in] centerp if true (default), return center of the grid squa re,
* else return SW (lower left) corner. * else return SW (lower left) corner.
* @exception GeographicErr if \e gridref is illegal.
* *
* The grid reference must be of the form: two letters (not including I ) * The grid reference must be of the form: two letters (not including I )
* followed by an even number of digits (up to 22). * followed by an even number of digits (up to 22).
********************************************************************** / ********************************************************************** /
static void GridReference(const std::string& gridref, static void GridReference(const std::string& gridref,
real& x, real& y, int& prec, real& x, real& y, int& prec,
bool centerp = true); bool centerp = true);
/** \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^(9.48401603-10) m. (The Airy 1830 value is returned because the * 10<sup>9.48401603&minus;10</sup> m. (The Airy 1830 value is returne
OSGB d
* projection is based on this ellipsoid.) * because the OSGB projection is based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
static Math::real MajorRadius() throw() static Math::real MajorRadius() throw()
// 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 - 20853810)/20923713 = 7767/2324857 * thus the flattening = (20923713 &minus; 20853810)/20923713 =
= * 7767/2324857 = 1/299.32496459... (The Airy 1830 value is returned
* 1/299.32496459... (The Airy 1830 value is returned because the OSGB * because the OSGB projection is based on this ellipsoid.)
* projection is based on this ellipsoid.)
********************************************************************** / ********************************************************************** /
static Math::real Flattening() throw() static Math::real Flattening() throw()
{ 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() throw() { return 1/Flattening(); }
skipping to change at line 217 skipping to change at line 222
********************************************************************** / ********************************************************************** /
static Math::real CentralScale() throw() static Math::real CentralScale() throw()
{ return real(0.9996012717L); } { return real(0.9996012717L); }
/** /**
* @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() throw() { return real(49); }
/** /**
* @return longitude of the origin for the OSGB projection (-2 degrees) * @return longitude of the origin for the OSGB projection (&minus;2
. * degrees).
********************************************************************** / ********************************************************************** /
static Math::real OriginLongitude() throw() { return real(-2); } static Math::real OriginLongitude() throw() { return real(-2); }
/** /**
* @return false northing the OSGB projection (-100000 meters). * @return false northing the OSGB projection (&minus;100000 meters).
********************************************************************** / ********************************************************************** /
static Math::real FalseNorthing() throw() { return real(-100000); } static Math::real FalseNorthing() throw() { 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() throw() { return real(400000); }
///@} ///@}
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning (pop) # pragma warning (pop)
#endif #endif
#endif #endif
 End of changes. 14 change blocks. 
25 lines changed or deleted 27 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-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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 \ #define GEOGRAPHICLIB_POLARSTEREOGRAPHIC_HPP 1
"$Id: a8bf5e616f8e1b6b95de40c60ac70d34360c843b $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Polar stereographic projection * \brief Polar stereographic projection
* *
* Implementation taken from the report, * Implementation taken from the report,
* - J. P. Snyder, * - J. P. Snyder,
skipping to change at line 63 skipping to change at line 62
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.
* @param[in] k0 central scale factor. * @param[in] k0 central scale factor.
* * @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k0 i
* An exception is thrown if either of the axes of the ellipsoid is s
* not positive \e a or if \e k0 is not positive. * not positive.
********************************************************************** / ********************************************************************** /
PolarStereographic(real a, real f, real k0); PolarStereographic(real a, real f, real k0);
/** /**
* Set the scale for the projection. * Set the scale for the projection.
* *
* @param[in] lat (degrees) assuming \e northp = true. * @param[in] lat (degrees) assuming \e northp = true.
* @param[in] k scale at latitude \e lat (default 1). * @param[in] k scale at latitude \e lat (default 1).
* * @exception GeographicLib \e k is not positive.
* This allows a "latitude of true scale" to be specified. An exceptio * @exception GeographicErr if \e lat is not in (&minus;90&deg;,
n is * 90&deg;].
* thrown if \e k is not positive or if \e lat is not in the range (-90
,
* 90].
********************************************************************** / ********************************************************************** /
void SetScale(real lat, real k = real(1)); void SetScale(real lat, real k = real(1));
/** /**
* Forward projection, from geographic to polar stereographic. * Forward projection, from geographic to polar stereographic.
* *
* @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] 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.
* *
* 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
* (-90, 90] for \e northp = true and in the range [-90, 90) for \e nor * (&minus;90&deg;, 90&deg;] for \e northp = true and in the range
thp * [&minus;90&deg;, 90&deg;) for \e northp = false; \e lon should
* = false; \e lon should be in the range [-180, 360]. * 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 throw();
/** /**
* 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 [-180, 180). * 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 throw();
/** /**
* 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 throw() {
real gamma, k; real gamma, k;
 End of changes. 5 change blocks. 
15 lines changed or deleted 11 lines changed or added


 PolygonArea.hpp   PolygonArea.hpp 
/** /**
* \file PolygonArea.hpp * \file PolygonArea.hpp
* \brief Header for GeographicLib::PolygonArea class * \brief Header for GeographicLib::PolygonArea class
* *
* Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2010-2011) <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_POLYGONAREA_HPP) #if !defined(GEOGRAPHICLIB_POLYGONAREA_HPP)
#define GEOGRAPHICLIB_POLYGONAREA_HPP \ #define GEOGRAPHICLIB_POLYGONAREA_HPP 1
"$Id: 04dc2b7450ed688972073405ebe13d5ac5da5d89 $"
#include <GeographicLib/Geodesic.hpp> #include <GeographicLib/Geodesic.hpp>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/Accumulator.hpp> #include <GeographicLib/Accumulator.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Polygon areas * \brief Polygon areas
* *
* This computes the area of a geodesic polygon using the method given * This computes the area of a geodesic polygon using the method given
* Section 15 of * Section 6 of
* - C. F. F. Karney, * - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1102.1215v1">Geodesics * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* on an ellipsoid of revolution</a>, * Algorithms for geodesics</a>,
* Feb. 2011; * J. Geodesy, 2012;
* preprint * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
* <a href="http://arxiv.org/abs/1102.1215v1">arxiv:1102.1215v1</a>. * 10.1007/s00190-012-0578-z</a>.
* .
* See also Section 6 of
* - C. F. F. Karney,
* <a href="http://arxiv.org/abs/1109.4448">Algorithms for geodesics</a
>,
* Sept. 2011;
* preprint
* <a href="http://arxiv.org/abs/1109.4448">arxiv:1109.4448</a>.
* *
* This class lets you add vertices one at a time to the polygon. The ar ea * This class lets you add vertices one at a time to the polygon. The ar ea
* and perimeter are accumulated in two times the standard floating point * and perimeter are accumulated in two times the standard floating point
* precision to guard against the loss of accuracy with many-sided polygo ns. * precision to guard against the loss of accuracy with many-sided polygo ns.
* At any point you can ask for the perimeter and area so far. There's a n * At any point you can ask for the perimeter and area so far. There's a n
* option to treat the points as defining a polyline instead of a polygon ; in * option to treat the points as defining a polyline instead of a polygon ; in
* that case, only the perimeter is computed. * that case, only the perimeter is computed.
* *
* Example of use: * Example of use:
* \include example-PolygonArea.cpp * \include example-PolygonArea.cpp
skipping to change at line 64 skipping to change at line 56
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;
// Copied from Geodesic class // Copied from Geodesic class (now the Math class)
static inline real AngNormalize(real x) throw() { static inline real AngNormalize(real x) throw() {
// Place angle in [-180, 180). Assumes x is in [-540, 540). // Place angle in [-180, 180). Assumes x is in [-540, 540).
// //
// g++ 4.4.4 holds a temporary in an extended register causing an err or // g++ 4.4.4 holds a temporary in an extended register causing an err or
// with the triangle 89,0.1;89,90.1;89,-179.9. The volatile declarat ion // with the triangle 89,0.1;89,90.1;89,-179.9. The volatile declarat ion
// fixes this. (The bug probably triggered because transit and // fixes this. (The bug probably triggered because transit and
// AngNormalize are inline functions. So don't port this change over to // AngNormalize are inline functions. So don't port this change over to
// Geodesic.hpp.) // Geodesic.hpp.)
volatile real y = x; volatile real y = x;
return y >= 180 ? y - 360 : (y < -180 ? y + 360 : y); return y >= 180 ? y - 360 : (y < -180 ? y + 360 : y);
skipping to change at line 124 skipping to change at line 116
_perimetersum = 0; _perimetersum = 0;
_lat0 = _lon0 = _lat1 = _lon1 = 0; _lat0 = _lon0 = _lat1 = _lon1 = 0;
} }
/** /**
* 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 latitude of the point (degrees). * @param[in] lon the latitude of the point (degrees).
* *
* \e lat should be in the range [-90, 90] and \e lon should be in the * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
* range [-180, 360]. * lon should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
void AddPoint(real lat, real lon) throw(); void AddPoint(real lat, real lon) throw();
/** /**
* 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^2); only set if * @param[out] area the area of the polygon (meters<sup>2</sup>); only
* polyline is false in the constructor. set
* if 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 throw();
/** /**
* 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
skipping to change at line 163 skipping to change at line 155
* *
* @param[in] lat the latitude of the test point (degrees). * @param[in] lat the latitude of the test point (degrees).
* @param[in] lon the longitude of the test point (degrees). * @param[in] lon the longitude of the test point (degrees).
* @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 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 (meters^2); onl * @param[out] area the approximate area of the polygon
y * (meters<sup>2</sup>); only set if polyline is false in the
* 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 [-90, 90] and \e lon should be in the * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
* range [-180, 360]. * lon should be in the range [&minus;540&deg;, 540&deg;).
********************************************************************** / ********************************************************************** /
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 throw();
/** \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.
 End of changes. 9 change blocks. 
27 lines changed or deleted 19 lines changed or added


 SphericalEngine.hpp   SphericalEngine.hpp 
/** /**
* \file SphericalEngine.hpp * \file SphericalEngine.hpp
* \brief Header for GeographicLib::SphericalEngine class * \brief Header for GeographicLib::SphericalEngine class
* *
* Copyright (c) Charles Karney (2011, 2012) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2011-2012) <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_SPHERICALENGINE_HPP) #if !defined(GEOGRAPHICLIB_SPHERICALENGINE_HPP)
#define GEOGRAPHICLIB_SPHERICALENGINE_HPP \ #define GEOGRAPHICLIB_SPHERICALENGINE_HPP 1
"$Id: 164f95e6b036576cad0e2e8a176149658f3034e9 $"
#include <vector> #include <vector>
#include <istream> #include <istream>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
// Squelch warnings about dll vs vector // Squelch warnings about dll vs vector
#pragma warning (push) # pragma warning (push)
#pragma warning (disable: 4251) # pragma warning (disable: 4251)
#endif #endif
namespace GeographicLib { namespace GeographicLib {
class CircularEngine; class CircularEngine;
/** /**
* \brief The evaluation engine for SphericalHarmonic * \brief The evaluation engine for SphericalHarmonic
* *
* This serves as the backend to SphericalHarmonic, SphericalHarmonic1, a nd * This serves as the backend to SphericalHarmonic, SphericalHarmonic1, a nd
skipping to change at line 115 skipping to change at line 114
, _Cnm(Z_.begin()) , _Cnm(Z_.begin())
, _Snm(Z_.begin()) {} , _Snm(Z_.begin()) {}
/** /**
* The general constructor. * The general constructor.
* *
* @param[in] C a vector of coefficients for the cosine terms. * @param[in] C a vector of coefficients for the cosine terms.
* @param[in] S a vector of coefficients for the sine terms. * @param[in] S a vector of coefficients for the sine terms.
* @param[in] N the degree giving storage layout for \e C and \e S. * @param[in] N the degree giving storage layout for \e C and \e S.
* @param[in] nmx the maximum degree to be used. * @param[in] nmx the maximum degree to be used.
* @param[in] mmx the maximum order to be used. * @param[in] mmx the maximum order to be used.
* * @exception GeographicErr if \e N, \e nmx, and \e mmx do not satisf
* This requires \e N >= \e nmx >= \e mmx >= -1. \e C and \e S must y
also * \e N &ge; \e nmx &ge; \e mmx &ge; &minus;1.
* be large enough to hold the coefficients. Otherwise an exception * @exception GeographicErr if \e C or \e S is not big enough to hold
is the
* thrown. * coefficients.
* @exception std::bad_alloc if the memory for the square root table
* can't be allocated.
******************************************************************** **/ ******************************************************************** **/
coeff(const std::vector<real>& C, coeff(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, int nmx, int mmx) int N, int nmx, int mmx)
: _N(N) : _N(N)
, _nmx(nmx) , _nmx(nmx)
, _mmx(mmx) , _mmx(mmx)
, _Cnm(C.begin()) , _Cnm(C.begin())
, _Snm(S.begin()) , _Snm(S.begin())
{ {
skipping to change at line 142 skipping to change at line 143
index(_nmx, _mmx) < int(S.size()) + (_N + 1))) index(_nmx, _mmx) < int(S.size()) + (_N + 1)))
throw GeographicErr("Arrays too small in coeff"); throw GeographicErr("Arrays too small in coeff");
SphericalEngine::RootTable(_nmx); SphericalEngine::RootTable(_nmx);
} }
/** /**
* The constructor for full coefficient vectors. * The constructor for full coefficient vectors.
* *
* @param[in] C a vector of coefficients for the cosine terms. * @param[in] C a vector of coefficients for the cosine terms.
* @param[in] S a vector of coefficients for the sine terms. * @param[in] S a vector of coefficients for the sine terms.
* @param[in] N the maximum degree and order. * @param[in] N the maximum degree and order.
* * @exception GeographicErr if \e N does not satisfy \e N &ge; &minus
* This requires \e N >= -1. \e C and \e S must also be large enough ;1.
to * @exception GeographicErr if \e C or \e S is not big enough to hold
* hold the coefficients. Otherwise an exception is thrown. the
* coefficients.
* @exception std::bad_alloc if the memory for the square root table
* can't be allocated.
******************************************************************** **/ ******************************************************************** **/
coeff(const std::vector<real>& C, coeff(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N) int N)
: _N(N) : _N(N)
, _nmx(N) , _nmx(N)
, _mmx(N) , _mmx(N)
, _Cnm(C.begin()) , _Cnm(C.begin())
, _Snm(S.begin()) , _Snm(S.begin())
{ {
skipping to change at line 230 skipping to change at line 233
{ return m > _mmx || n > _nmx ? 0 : *(_Snm + (k - (_N + 1))) * f; } { return m > _mmx || n > _nmx ? 0 : *(_Snm + (k - (_N + 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) static inline int Csize(int N, int M) throw()
{ 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) static inline int Ssize(int N, int M) throw ()
{ 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.
* @exception GeographicErr if \e N and \e M do not satisfy \e N &ge;
* \e M &ge; &minus;1.
* @exception GeographicErr if there's an error reading the data.
* @exception std::bad_alloc if the memory for \e C or \e S can't be
* allocated.
* *
* \e N and \e M are read as 4-byte ints. \e C and \e S are resized to * \e N and \e M are read as 4-byte ints. \e C and \e S are resized to
* accommodate all the coefficients (with the \e m = 0 coefficients f or * accommodate all the coefficients (with the \e m = 0 coefficients f or
* \e S excluded) and the data for these coefficients read as 8-byte * \e S excluded) and the data for these coefficients read as 8-byte
* doubles. The coefficients are stored in column major order. The * doubles. The coefficients are stored in column major order. The
* bytes in the stream should use little-endian ordering. IEEE float ing * bytes in the stream should use little-endian ordering. IEEE float ing
* point is assumed for the coefficients. * point is assumed for the coefficients.
******************************************************************** **/ ******************************************************************** **/
static void readcoeffs(std::istream& stream, int& N, int& M, static void readcoeffs(std::istream& stream, int& N, int& M,
std::vector<real>& C, std::vector<real>& S); std::vector<real>& C, std::vector<real>& S);
skipping to change at line 281 skipping to change at line 289
* @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] x the \e x component of the cartesian position. * @param[in] x the \e x component of the cartesian position.
* @param[in] y the \e y component of the cartesian position. * @param[in] y the \e y component of the cartesian position.
* @param[in] z the \e z component of the cartesian position. * @param[in] z the \e z component of the cartesian position.
* @param[in] a the normalizing radius. * @param[in] a the normalizing radius.
* @param[out] gradx the \e x component of the gradient. * @param[out] gradx the \e x component of the gradient.
* @param[out] grady the \e y component of the gradient. * @param[out] grady the \e y component of the gradient.
* @param[out] gradz the \e z component of the gradient. * @param[out] gradz the \e z component of the gradient.
* @result the spherical harmonic sum. * @result the spherical harmonic sum.
* *
* See the SphericalHarmonic class for the definition of the sum. * See the SphericalHarmonic class for the definition of the sum. The
* The coefficients used by this function are, for example, * coefficients used by this function are, for example, c[0].Cv + f[1]
* c[0].Cv + f[1] * c[1].Cv + ... + f[L-1] * c[L-1].Cv. (Note *
* that f[0] is \e not used.) The upper limits on the sum are * c[1].Cv + ... + f[L&minus;1] * c[L&minus;1].Cv. (Note that f[0] is
* determined by c[0].nmx() and c[0].mmx(); these limits apply to \e
* \e all the components of the coefficients. The parameters \e * not used.) The upper limits on the sum are determined by c[0].nmx()
* gradp, \e norm, and \e L are template parameters, to allow more and
* optimization to be done at compile time. * c[0].mmx(); these limits apply to \e all the components of the
* coefficients. The parameters \e gradp, \e norm, and \e L are templa
te
* 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) throw( );
skipping to change at line 311 skipping to change at line 318
* *
* @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> +
* <i>y</i><sup>2</sup>). * <i>y</i><sup>2</sup>).
* @param[in] z the height of the circle. * @param[in] z the height of the circle.
* @param[in] a the normalizing radius. * @param[in] a the normalizing radius.
* @exception std::bad_alloc if the memory for the CircularEngine can't
be
* allocated.
* @result the CircularEngine object. * @result the CircularEngine object.
* *
* If you need to evaluate the spherical harmonic sum for several point s * If you need to evaluate the spherical harmonic sum for several point s
* with constant \e f, \e p = sqrt(<i>x</i><sup>2</sup> + * with constant \e f, \e p = sqrt(<i>x</i><sup>2</sup> +
* <i>y</i><sup>2</sup>), \e z, and \e a, it is more efficient to const ruct * <i>y</i><sup>2</sup>), \e z, and \e a, it is more efficient to const ruct
* call SphericalEngine::Circle to give a CircularEngine object and the n * call SphericalEngine::Circle to give a CircularEngine object and the n
* call CircularEngine::operator()() with arguments <i>x</i>/\e p and * call CircularEngine::operator()() with arguments <i>x</i>/\e p and
* <i>y</i>/\e p. * <i>y</i>/\e p.
********************************************************************** / ********************************************************************** /
template<bool gradp, normalization norm, int L> template<bool gradp, normalization norm, int L>
static CircularEngine Circle(const coeff c[], const real f[], static CircularEngine Circle(const coeff c[], const real f[],
real p, real z, real a); real p, real z, real a);
/** /**
* Check that the static table of square roots is big enough and enlarg e it * Check that the static table of square roots is big enough and enlarg e it
* if necessary. * if necessary.
* *
* @param[in] N the maximum degree to be used in SphericalEngine. * @param[in] N the maximum degree to be used in SphericalEngine.
* @exception std::bad_alloc if the memory for the square root table ca
n't
* be allocated.
* *
* Typically, there's no need for an end-user to call this routine, bec ause * Typically, there's no need for an end-user to call this routine, bec ause
* the constructors for SphericalEngine::coeff do so. However, since t his * the constructors for SphericalEngine::coeff do so. However, since t his
* updates a static table, there's a possible race condition in a * updates a static table, there's a possible race condition in a
* multi-threaded environment. Because this routine does nothing if th e * multi-threaded environment. Because this routine does nothing if th e
* table is already large enough, one way to avoid race conditions is t o * table is already large enough, one way to avoid race conditions is t o
* call this routine at program start up (when it's still single thread ed), * call this routine at program start up (when it's still single thread ed),
* supplying the largest degree that your program will use. E.g., * supplying the largest degree that your program will use. E.g.,
\code \code
GeographicLib::SphericalEngine::RootTable(2190); GeographicLib::SphericalEngine::RootTable(2190);
\endcode \endcode
* suffices to accommodate extant magnetic and gravity models. * suffices to accommodate extant magnetic and gravity models.
********************************************************************** / ********************************************************************** /
static void RootTable(int N); static void RootTable(int N);
/** /**
* Clear the static table of square roots and release the memory. Call * Clear the static table of square roots and release the memory. Call
* this only when you are sure you no longer will be using SphericalEng ine. * this only when you are sure you no longer will be using SphericalEng ine.
* Your program will crash if you call SphericalEngine after calling th is * Your program will crash if you call SphericalEngine after calling th is
* routine. <b>It's safest not to call this routine at all.</b> (The s pace * routine. <b>It's safest not to call this routine at all.</b> (The s pace
skipping to change at line 359 skipping to change at line 370
********************************************************************** / ********************************************************************** /
static void ClearRootTable() { static void ClearRootTable() {
std::vector<real> temp(0); std::vector<real> temp(0);
root_.swap(temp); root_.swap(temp);
} }
}; };
} // namespace GeographicLib } // namespace GeographicLib
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning (pop) # pragma warning (pop)
#endif #endif
#endif // GEOGRAPHICLIB_SPHERICALENGINE_HPP #endif // GEOGRAPHICLIB_SPHERICALENGINE_HPP
 End of changes. 13 change blocks. 
27 lines changed or deleted 45 lines changed or added


 SphericalHarmonic.hpp   SphericalHarmonic.hpp 
/** /**
* \file SphericalHarmonic.hpp * \file SphericalHarmonic.hpp
* \brief Header for GeographicLib::SphericalHarmonic class * \brief Header for GeographicLib::SphericalHarmonic class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC_HPP) #if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC_HPP)
#define GEOGRAPHICLIB_SPHERICALHARMONIC_HPP \ #define GEOGRAPHICLIB_SPHERICALHARMONIC_HPP 1
"$Id: ef47b5e3bd16594a8a82242fa7cac8dcbf5d7dee $"
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/SphericalEngine.hpp> #include <GeographicLib/SphericalEngine.hpp>
#include <GeographicLib/CircularEngine.hpp> #include <GeographicLib/CircularEngine.hpp>
#include <GeographicLib/Geocentric.hpp> #include <GeographicLib/Geocentric.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Spherical harmonic series * \brief Spherical harmonic series
* *
* This class evaluates the spherical harmonic sum \verbatim * This class evaluates the spherical harmonic sum \verbatim
V(x, y, z) = sum(n = 0..N)[ q^(n+1) * sum(m = 0..n)[ V(x, y, z) = sum(n = 0..N)[ q^(n+1) * sum(m = 0..n)[
(C[n,m] * cos(m*lambda) + S[n,m] * sin(m*lambda)) * (C[n,m] * cos(m*lambda) + S[n,m] * sin(m*lambda)) *
P[n,m](cos(theta)) ] ] P[n,m](cos(theta)) ] ]
\endverbatim \endverbatim
* where * where
* - <i>p</i><sup>2</sup> = <i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>, * - <i>p</i><sup>2</sup> = <i>x</i><sup>2</sup> + <i>y</i><sup>2</sup>,
* - <i>r</i><sup>2</sup> = <i>p</i><sup>2</sup> + <i>z</i><sup>2</sup>, * - <i>r</i><sup>2</sup> = <i>p</i><sup>2</sup> + <i>z</i><sup>2</sup>,
* - \e q = <i>a</i>/<i>r</i>, * - \e q = <i>a</i>/<i>r</i>,
* - \e theta = atan2(\e p, \e z) = the spherical \e colatitude, * - &theta; = atan2(\e p, \e z) = the spherical \e colatitude,
* - \e lambda = atan2(\e y, \e x) = the longitude. * - &lambda; = atan2(\e y, \e x) = the longitude.
* - P<sub>\e nm</sub>(\e t) is the associated Legendre polynomial of deg ree * - P<sub>\e nm</sub>(\e t) is the associated Legendre polynomial of deg ree
* \e n and order \e m. * \e n and order \e m.
* *
* Two normalizations are supported for P<sub>\e nm</sub> * Two normalizations are supported for P<sub>\e nm</sub>
* - fully normalized denoted by SphericalHarmonic::FULL. * - fully normalized denoted by SphericalHarmonic::FULL.
* - Schmidt semi-normalized denoted by SphericalHarmonic::SCHMIDT. * - Schmidt semi-normalized denoted by SphericalHarmonic::SCHMIDT.
* *
* Clenshaw summation is used for the sums over both \e n and \e m. This * Clenshaw summation is used for the sums over both \e n and \e m. This
* allows the computation to be carried out without the need for any * allows the computation to be carried out without the need for any
* temporary arrays. See SphericalEngine.cpp for more information on the * temporary arrays. See SphericalEngine.cpp for more information on the
* implementation. * implementation.
* *
* References: * References:
* - C. W. Clenshaw, A note on the summation of Chebyshev series, * - C. W. Clenshaw, A note on the summation of Chebyshev series,
* %Math. Tables Aids Comput. 9(51), 118-120 (1955). * %Math. Tables Aids Comput. 9(51), 118&ndash;120 (1955).
* - R. E. Deakin, Derivatives of the earth's potentials, Geomatics * - R. E. Deakin, Derivatives of the earth's potentials, Geomatics
* Research Australasia 68, 31-60, (June 1998). * Research Australasia 68, 31&ndash;60, (June 1998).
* - W. A. Heiskanen and H. Moritz, Physical Geodesy, (Freeman, San * - W. A. Heiskanen and H. Moritz, Physical Geodesy, (Freeman, San
* Francisco, 1967). (See Sec. 1-14, for a definition of Pbar.) * Francisco, 1967). (See Sec. 1-14, for a definition of Pbar.)
* - S. A. Holmes and W. E. Featherstone, A unified approach to the * - S. A. Holmes and W. E. Featherstone, A unified approach to the Clens
* Clenshaw summation and the recursive computation of very high degree haw
* and order normalised associated Legendre functions, J. Geod. 76(5), * summation and the recursive computation of very high degree and orde
* 279-299 (2002). r
* normalised associated Legendre functions, J. Geodesy 76(5),
* 279&ndash;299 (2002).
* - C. C. Tscherning and K. Poder, Some geodetic applications of Clensha w * - C. C. Tscherning and K. Poder, Some geodetic applications of Clensha w
* summation, Boll. Geod. Sci. Aff. 41(4), 349-375 (1982). * summation, Boll. Geod. Sci. Aff. 41(4), 349&ndash;375 (1982).
* *
* Example of use: * Example of use:
* \include example-SphericalHarmonic.cpp * \include example-SphericalHarmonic.cpp
**********************************************************************/ **********************************************************************/
class GEOGRAPHIC_EXPORT SphericalHarmonic { class GEOGRAPHIC_EXPORT SphericalHarmonic {
public: public:
/** /**
* Supported normalizations for the associated Legendre polynomials. * Supported normalizations for the associated Legendre polynomials.
********************************************************************** / ********************************************************************** /
enum normalization { enum normalization {
/** /**
* Fully normalized associated Legendre polynomials. * Fully normalized associated Legendre polynomials.
* *
* These are defined by <i>P</i><sub><i>nm</i></sub><sup>full</sup>(\ e z) * These are defined by <i>P</i><sub><i>nm</i></sub><sup>full</sup>(\ e z)
* = (-1)<sup><i>m</i></sup> sqrt(\e k (2\e n + 1) (\e n - \e m)! / ( * = (&minus;1)<sup><i>m</i></sup> sqrt(\e k (2\e n + 1) (\e n &minus
\e n ; \e
* + \e m)!) <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), wh * m)! / (\e n + \e m)!)
ere * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), where
* <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers * <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers
* function (also known as the Legendre function on the cut or the * function (also known as the Legendre function on the cut or the
* associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and \e k * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and \e k
* = 1 for \e m = 0 and \e k = 2 otherwise. * = 1 for \e m = 0 and \e k = 2 otherwise.
* *
* The mean squared value of * The mean squared value of
* <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cos \e theta) cos(\e m * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cos&theta;)
\e * cos(<i>m</i>&lambda;) and
* lambda) and <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cos \e the * <i>P</i><sub><i>nm</i></sub><sup>full</sup>(cos&theta;)
ta) * sin(<i>m</i>&lambda;) over the sphere is 1.
* sin(\e m \e lambda) over the sphere is 1.
* *
* @hideinitializer * @hideinitializer
******************************************************************** **/ ******************************************************************** **/
FULL = SphericalEngine::FULL, FULL = SphericalEngine::FULL,
/** /**
* Schmidt semi-normalized associated Legendre polynomials. * Schmidt semi-normalized associated Legendre polynomials.
* *
* These are defined by <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup >(\e * These are defined by <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup >(\e
* z) = (-1)<sup><i>m</i></sup> sqrt(\e k (\e n - \e m)! / (\e n + \e * z) = (&minus;1)<sup><i>m</i></sup> sqrt(\e k (\e n &minus; \e m)!
* m)!) <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z), where /
* <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferrers * (\e n + \e m)!) <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e
z),
* where <b>P</b><sub><i>n</i></sub><sup><i>m</i></sup>(\e z) is Ferr
ers
* function (also known as the Legendre function on the cut or the * function (also known as the Legendre function on the cut or the
* associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and \e k * associated Legendre polynomial) http://dlmf.nist.gov/14.7.E10 and \e k
* = 1 for \e m = 0 and \e k = 2 otherwise. * = 1 for \e m = 0 and \e k = 2 otherwise.
* *
* The mean squared value of * The mean squared value of
* <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cos \e theta) cos(\ * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cos&theta;)
e m * cos(<i>m</i>&lambda;) and
* \e lambda) and <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cos * <i>P</i><sub><i>nm</i></sub><sup>schmidt</sup>(cos&theta;)
\e * sin(<i>m</i>&lambda;) over the sphere is 1/(2\e n + 1).
* theta) sin(\e m \e lambda) over the sphere is 1/(2\e n + 1).
* *
* @hideinitializer * @hideinitializer
******************************************************************** **/ ******************************************************************** **/
SCHMIDT = SphericalEngine::SCHMIDT, SCHMIDT = SphericalEngine::SCHMIDT,
/// \cond SKIP /// \cond SKIP
// These are deprecated... // These are deprecated...
full = FULL, full = FULL,
schmidt = SCHMIDT, schmidt = SCHMIDT,
/// \endcond /// \endcond
}; };
skipping to change at line 135 skipping to change at line 137
* Constructor with a full set of coefficients specified. * Constructor with a full set of coefficients specified.
* *
* @param[in] C the coefficients \e C<sub>\e nm</sub>. * @param[in] C the coefficients \e C<sub>\e nm</sub>.
* @param[in] S the coefficients \e S<sub>\e nm</sub>. * @param[in] S the coefficients \e S<sub>\e nm</sub>.
* @param[in] N the maximum degree and order of the sum * @param[in] N the maximum degree and order of the sum
* @param[in] a the reference radius appearing in the definition of the * @param[in] a the reference radius appearing in the definition of the
* sum. * sum.
* @param[in] norm the normalization for the associated Legendre * @param[in] norm the normalization for the associated Legendre
* polynomials, either SphericalHarmonic::full (the default) or * polynomials, either SphericalHarmonic::full (the default) or
* SphericalHarmonic::schmidt. * SphericalHarmonic::schmidt.
* @exception GeographicErr if \e N does not satisfy \e N &ge; &minus;1
.
* @exception GeographicErr if \e C or \e S is not big enough to hold t
he
* coefficients.
* *
* The coefficients \e C<sub>\e nm</sub> and \e S<sub>\e nm</sub> are * The coefficients \e C<sub>\e nm</sub> and \e S<sub>\e nm</sub> are
* stored in the one-dimensional vectors \e C and \e S which must conta in * stored in the one-dimensional vectors \e C and \e S which must conta in
* (\e N + 1)(\e N + 2)/2 and N (\e N + 1)/2 elements, respectively, st ored * (\e N + 1)(\e N + 2)/2 and N (\e N + 1)/2 elements, respectively, st ored
* in "column-major" order. Thus for \e N = 3, the order would be: * in "column-major" order. Thus for \e N = 3, the order would be:
* <i>C</i><sub>00</sub>, * <i>C</i><sub>00</sub>,
* <i>C</i><sub>10</sub>, * <i>C</i><sub>10</sub>,
* <i>C</i><sub>20</sub>, * <i>C</i><sub>20</sub>,
* <i>C</i><sub>30</sub>, * <i>C</i><sub>30</sub>,
* <i>C</i><sub>11</sub>, * <i>C</i><sub>11</sub>,
* <i>C</i><sub>21</sub>, * <i>C</i><sub>21</sub>,
* <i>C</i><sub>31</sub>, * <i>C</i><sub>31</sub>,
* <i>C</i><sub>22</sub>, * <i>C</i><sub>22</sub>,
* <i>C</i><sub>32</sub>, * <i>C</i><sub>32</sub>,
* <i>C</i><sub>33</sub>. * <i>C</i><sub>33</sub>.
* In general the (\e n,\e m) element is at index \e m*\e N - \e m*(\e * In general the (\e n,\e m) element is at index \e m \e N &minus; \e
m - m
* 1)/2 + \e n. The layout of \e S is the same except that the first * (\e m &minus; 1)/2 + \e n. The layout of \e S is the same except th
* column is omitted (since the \e m = 0 terms never contribute to the at
sum) * the first column is omitted (since the \e m = 0 terms never contribu
* and the 0th element is <i>S</i><sub>11</sub> te
* to the sum) and the 0th element is <i>S</i><sub>11</sub>
* *
* The class stores <i>pointers</i> to the first elements of \e C and \ e S. * The class stores <i>pointers</i> to the first elements of \e C and \ e S.
* These arrays should not be altered or destroyed during the lifetime of a * These arrays should not be altered or destroyed during the lifetime of a
* SphericalHarmonic object. * SphericalHarmonic object.
********************************************************************** / ********************************************************************** /
SphericalHarmonic(const std::vector<real>& C, SphericalHarmonic(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, real a, unsigned norm = FULL) int N, real a, unsigned norm = FULL)
: _a(a) : _a(a)
, _norm(norm) , _norm(norm)
skipping to change at line 181 skipping to change at line 186
* @param[in] N the degree used to determine the layout of \e C and \e S. * @param[in] N the degree used to determine the layout of \e C and \e S.
* @param[in] nmx the maximum degree used in the sum. The sum over \e n is * @param[in] nmx the maximum degree used in the sum. The sum over \e n is
* from 0 thru \e nmx. * from 0 thru \e nmx.
* @param[in] mmx the maximum order used in the sum. The sum over \e m is * @param[in] mmx the maximum order used in the sum. The sum over \e m is
* from 0 thru min(\e n, \e mmx). * from 0 thru min(\e n, \e mmx).
* @param[in] a the reference radius appearing in the definition of the * @param[in] a the reference radius appearing in the definition of the
* sum. * sum.
* @param[in] norm the normalization for the associated Legendre * @param[in] norm the normalization for the associated Legendre
* polynomials, either SphericalHarmonic::FULL (the default) or * polynomials, either SphericalHarmonic::FULL (the default) or
* SphericalHarmonic::SCHMIDT. * SphericalHarmonic::SCHMIDT.
* @exception GeographicErr if \e N, \e nmx, and \e mmx do not satisfy
* \e N &ge; \e nmx &ge; \e mmx &ge; &minus;1.
* @exception GeographicErr if \e C or \e S is not big enough to hold t
he
* coefficients.
* *
* The class stores <i>pointers</i> to the first elements of \e C and \ e S. * The class stores <i>pointers</i> to the first elements of \e C and \ e S.
* These arrays should not be altered or destroyed during the lifetime of a * These arrays should not be altered or destroyed during the lifetime of a
* SphericalHarmonic object. * SphericalHarmonic object.
********************************************************************** / ********************************************************************** /
SphericalHarmonic(const std::vector<real>& C, SphericalHarmonic(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, int nmx, int mmx, int N, int nmx, int mmx,
real a, unsigned norm = FULL) real a, unsigned norm = FULL)
: _a(a) : _a(a)
skipping to change at line 270 skipping to change at line 279
} }
/** /**
* Create a CircularEngine to allow the efficient evaluation of several * Create a CircularEngine to allow the efficient evaluation of several
* points on a circle of latitude. * points on a circle of latitude.
* *
* @param[in] p the radius of the circle. * @param[in] p the radius of the circle.
* @param[in] z the height of the circle above the equatorial plane. * @param[in] z the height of the circle above the equatorial plane.
* @param[in] gradp if true the returned object will be able to compute the * @param[in] gradp if true the returned object will be able to compute the
* gradient of the sum. * gradient of the sum.
* @exception std::bad_alloc if the memory for the CircularEngine can't
be
* allocated.
* @return the CircularEngine object. * @return the CircularEngine object.
* *
* SphericalHarmonic::operator()() exchanges the order of the sums in t he * SphericalHarmonic::operator()() exchanges the order of the sums in t he
* definition, i.e., sum(n = 0..N)[sum(m = 0..n)[...]] becomes sum(m = * definition, i.e., &sum;<sub>n = 0..N</sub> &sum;<sub>m = 0..n</sub>
* 0..N)[sum(n = m..N)[...]]. SphericalHarmonic::Circle performs the i * becomes &sum;<sub>m = 0..N</sub> &sum;<sub>n = m..N</sub>.
nner * SphericalHarmonic::Circle performs the inner sum over degree \e n (w
* sum over degree \e n (which entails about <i>N</i><sup>2</sup> hich
* operations). Calling CircularEngine::operator()() on the returned * entails about <i>N</i><sup>2</sup> operations). Calling
* object performs the outer sum over the order \e m (about \e N * CircularEngine::operator()() on the returned object performs the out
* operations). This routine may throw a bad_alloc exception in the er
* CircularEngine constructor. * sum over the order \e m (about \e N operations).
* *
* Here's an example of computing the spherical sum at a sequence of * Here's an example of computing the spherical sum at a sequence of
* longitudes without using a CircularEngine object * longitudes without using a CircularEngine object
\code \code
SphericalHarmonic h(...); // Create the SphericalHarmonic object SphericalHarmonic h(...); // Create the SphericalHarmonic object
double r = 2, lat = 33, lon0 = 44, dlon = 0.01; double r = 2, lat = 33, lon0 = 44, dlon = 0.01;
double double
phi = lat * Math::degree<double>(), phi = lat * Math::degree<double>(),
z = r * sin(phi), p = r * cos(phi); z = r * sin(phi), p = r * cos(phi);
for (int i = 0; i <= 100; ++i) { for (int i = 0; i <= 100; ++i) {
real real
lon = lon0 + i * dlon, lon = lon0 + i * dlon,
lam = lon * Math::degree<double>(); lam = lon * Math::degree<double>();
std::cout << lon << " " << h(p * cos(lam), p * sin(lam), z) << "\n"; std::cout << lon << " " << h(p * cos(lam), p * sin(lam), z) << "\n";
} }
\endcode \endcode
* Here is the same calculation done using a CircularEngine object. Th is * Here is the same calculation done using a CircularEngine object. Th is
* will be about <i>N</i>/2 times faster. * will be about <i>N</i>/2 times faster.
\code \code
SphericalHarmonic h(...); // Create the SphericalHarmonic object SphericalHarmonic h(...); // Create the SphericalHarmonic object
double r = 2, lat = 33, lon0 = 44, dlon = 0.01; double r = 2, lat = 33, lon0 = 44, dlon = 0.01;
double double
phi = lat * Math::degree<double>(), phi = lat * Math::degree<double>(),
z = r * sin(phi), p = r * cos(phi); z = r * sin(phi), p = r * cos(phi);
CircularEngine c(h(p, z, false)); // Create the CircularEngine object CircularEngine c(h(p, z, false)); // Create the CircularEngine object
for (int i = 0; i <= 100; ++i) { for (int i = 0; i <= 100; ++i) {
real real
lon = lon0 + i * dlon; lon = lon0 + i * dlon;
std::cout << lon << " " << c(lon) << "\n"; std::cout << lon << " " << c(lon) << "\n";
} }
\endcode \endcode
********************************************************************** / ********************************************************************** /
CircularEngine Circle(real p, real z, bool gradp) const { CircularEngine Circle(real p, real z, bool gradp) const {
real f[] = {1}; real f[] = {1};
switch (_norm) { switch (_norm) {
case FULL: case FULL:
return gradp ? return gradp ?
SphericalEngine::Circle<true, SphericalEngine::FULL, 1> SphericalEngine::Circle<true, SphericalEngine::FULL, 1>
(_c, f, p, z, _a) : (_c, f, p, z, _a) :
SphericalEngine::Circle<false, SphericalEngine::FULL, 1> SphericalEngine::Circle<false, SphericalEngine::FULL, 1>
 End of changes. 18 change blocks. 
68 lines changed or deleted 84 lines changed or added


 SphericalHarmonic1.hpp   SphericalHarmonic1.hpp 
/** /**
* \file SphericalHarmonic1.hpp * \file SphericalHarmonic1.hpp
* \brief Header for GeographicLib::SphericalHarmonic1 class * \brief Header for GeographicLib::SphericalHarmonic1 class
* *
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed un der
* the MIT/X11 License. For more information, see * the MIT/X11 License. For more information, see
* http://geographiclib.sourceforge.net/ * http://geographiclib.sourceforge.net/
**********************************************************************/ **********************************************************************/
#if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP) #if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP)
#define GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP \ #define GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP 1
"$Id: 7164de400276831319d8b0a3792042b1529ecabd $"
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/SphericalEngine.hpp> #include <GeographicLib/SphericalEngine.hpp>
#include <GeographicLib/CircularEngine.hpp> #include <GeographicLib/CircularEngine.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Spherical harmonic series with a correction to the coefficients * \brief Spherical harmonic series with a correction to the coefficients
skipping to change at line 81 skipping to change at line 80
* @param[in] N the maximum degree and order of the sum * @param[in] N the maximum degree and order of the sum
* @param[in] C1 the coefficients \e C'<sub>\e nm</sub>. * @param[in] C1 the coefficients \e C'<sub>\e nm</sub>.
* @param[in] S1 the coefficients \e S'<sub>\e nm</sub>. * @param[in] S1 the coefficients \e S'<sub>\e nm</sub>.
* @param[in] N1 the maximum degree and order of the correction * @param[in] N1 the maximum degree and order of the correction
* coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>. * coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>.
* @param[in] a the reference radius appearing in the definition of the * @param[in] a the reference radius appearing in the definition of the
* sum. * sum.
* @param[in] norm the normalization for the associated Legendre * @param[in] norm the normalization for the associated Legendre
* polynomials, either SphericalHarmonic1::FULL (the default) or * polynomials, either SphericalHarmonic1::FULL (the default) or
* SphericalHarmonic1::SCHMIDT. * SphericalHarmonic1::SCHMIDT.
* @exception GeographicErr if \e N and \e N1 do not satisfy \e N &ge;
* \e N1 &ge; &minus;1.
* @exception GeographicErr if any of the vectors of coefficients is no
t
* large enough.
* *
* See SphericalHarmonic for the way the coefficients should be stored. * See SphericalHarmonic for the way the coefficients should be stored.
\e
* N1 should satisfy \e N1 <= \e N.
* *
* The class stores <i>pointers</i> to the first elements of \e C, \e S , \e * The class stores <i>pointers</i> to the first elements of \e C, \e S , \e
* C', and \e S'. These arrays should not be altered or destroyed duri ng * C', and \e S'. These arrays should not be altered or destroyed duri ng
* the lifetime of a SphericalHarmonic object. * the lifetime of a SphericalHarmonic object.
********************************************************************** / ********************************************************************** /
SphericalHarmonic1(const std::vector<real>& C, SphericalHarmonic1(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, int N,
const std::vector<real>& C1, const std::vector<real>& C1,
const std::vector<real>& S1, const std::vector<real>& S1,
skipping to change at line 125 skipping to change at line 127
* @param[in] S1 the coefficients \e S'<sub>\e nm</sub>. * @param[in] S1 the coefficients \e S'<sub>\e nm</sub>.
* @param[in] N1 the degree used to determine the layout of \e C' and \ e * @param[in] N1 the degree used to determine the layout of \e C' and \ e
* S'. * S'.
* @param[in] nmx1 the maximum degree used for \e C' and \e S'. * @param[in] nmx1 the maximum degree used for \e C' and \e S'.
* @param[in] mmx1 the maximum order used for \e C' and \e S'. * @param[in] mmx1 the maximum order used for \e C' and \e S'.
* @param[in] a the reference radius appearing in the definition of the * @param[in] a the reference radius appearing in the definition of the
* sum. * sum.
* @param[in] norm the normalization for the associated Legendre * @param[in] norm the normalization for the associated Legendre
* polynomials, either SphericalHarmonic1::FULL (the default) or * polynomials, either SphericalHarmonic1::FULL (the default) or
* SphericalHarmonic1::SCHMIDT. * SphericalHarmonic1::SCHMIDT.
* @exception GeographicErr if the parameters do not satisfy \e N &ge;
\e
* nmx &ge; \e mmx &ge; &minus;1; \e N1 &ge; \e nmx1 &ge; \e mmx1 &ge
;
* &minus;1; \e N &ge; \e N1; \e nmx &ge; \e nmx1; \e mmx &ge; \e mmx
1.
* @exception GeographicErr if any of the vectors of coefficients is no
t
* large enough.
* *
* The class stores <i>pointers</i> to the first elements of \e C, \e S , \e * The class stores <i>pointers</i> to the first elements of \e C, \e S , \e
* C', and \e S'. These arrays should not be altered or destroyed duri ng * C', and \e S'. These arrays should not be altered or destroyed duri ng
* the lifetime of a SphericalHarmonic object. * the lifetime of a SphericalHarmonic object.
********************************************************************** / ********************************************************************** /
SphericalHarmonic1(const std::vector<real>& C, SphericalHarmonic1(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, int nmx, int mmx, int N, int nmx, int mmx,
const std::vector<real>& C1, const std::vector<real>& C1,
const std::vector<real>& S1, const std::vector<real>& S1,
skipping to change at line 227 skipping to change at line 234
/** /**
* Create a CircularEngine to allow the efficient evaluation of several * Create a CircularEngine to allow the efficient evaluation of several
* points on a circle of latitude at a fixed value of \e tau. * points on a circle of latitude at a fixed value of \e tau.
* *
* @param[in] tau the multiplier for the correction coefficients. * @param[in] tau the multiplier for the correction coefficients.
* @param[in] p the radius of the circle. * @param[in] p the radius of the circle.
* @param[in] z the height of the circle above the equatorial plane. * @param[in] z the height of the circle above the equatorial plane.
* @param[in] gradp if true the returned object will be able to compute the * @param[in] gradp if true the returned object will be able to compute the
* gradient of the sum. * gradient of the sum.
* @exception std::bad_alloc if the memory for the CircularEngine can't
be
* allocated.
* @return the CircularEngine object. * @return the CircularEngine object.
* *
* SphericalHarmonic1::operator()() exchanges the order of the sums in the * SphericalHarmonic1::operator()() exchanges the order of the sums in the
* definition, i.e., sum(n = 0..N)[sum(m = 0..n)[...]] becomes sum(m = * definition, i.e., &sum;<sub>n = 0..N</sub> &sum;<sub>m = 0..n</sub>
* 0..N)[sum(n = m..N)[...]]. SphericalHarmonic1::Circle performs the * becomes &sum;<sub>m = 0..N</sub> &sum;<sub>n = m..N</sub>.
* inner sum over degree \e n (which entails about <i>N</i><sup>2</sup> * SphericalHarmonic1::Circle performs the inner sum over degree \e n
* operations). Calling CircularEngine::operator()() on the returned * (which entails about <i>N</i><sup>2</sup> operations). Calling
* object performs the outer sum over the order \e m (about \e N * CircularEngine::operator()() on the returned object performs the out
* operations). This routine may throw a bad_alloc exception in the er
* CircularEngine constructor. * sum over the order \e m (about \e N operations).
* *
* See SphericalHarmonic::Circle for an example of its use. * See SphericalHarmonic::Circle for an example of its use.
********************************************************************** / ********************************************************************** /
CircularEngine Circle(real tau, real p, real z, bool gradp) const { CircularEngine Circle(real tau, real p, real z, bool gradp) const {
real f[] = {1, tau}; real f[] = {1, tau};
switch (_norm) { switch (_norm) {
case FULL: case FULL:
return gradp ? return gradp ?
SphericalEngine::Circle<true, SphericalEngine::FULL, 2> SphericalEngine::Circle<true, SphericalEngine::FULL, 2>
(_c, f, p, z, _a) : (_c, f, p, z, _a) :
 End of changes. 6 change blocks. 
12 lines changed or deleted 26 lines changed or added


 SphericalHarmonic2.hpp   SphericalHarmonic2.hpp 
/** /**
* \file SphericalHarmonic2.hpp * \file SphericalHarmonic2.hpp
* \brief Header for GeographicLib::SphericalHarmonic2 class * \brief Header for GeographicLib::SphericalHarmonic2 class
* *
* Copyright (c) Charles Karney (2011, 2012) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2011-2012) <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_SPHERICALHARMONIC2_HPP) #if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP)
#define GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP \ #define GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP 1
"$Id: 6dbe2934b6bc0ae3d9d457030210a41fb461984b $"
#include <vector> #include <vector>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/SphericalEngine.hpp> #include <GeographicLib/SphericalEngine.hpp>
#include <GeographicLib/CircularEngine.hpp> #include <GeographicLib/CircularEngine.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Spherical harmonic series with two corrections to the coefficie nts * \brief Spherical harmonic series with two corrections to the coefficie nts
skipping to change at line 88 skipping to change at line 87
* coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>. * coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>.
* @param[in] C2 the coefficients \e C''<sub>\e nm</sub>. * @param[in] C2 the coefficients \e C''<sub>\e nm</sub>.
* @param[in] S2 the coefficients \e S''<sub>\e nm</sub>. * @param[in] S2 the coefficients \e S''<sub>\e nm</sub>.
* @param[in] N2 the maximum degree and order of the second correction * @param[in] N2 the maximum degree and order of the second correction
* coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>. * coefficients \e C'<sub>\e nm</sub> and \e S'<sub>\e nm</sub>.
* @param[in] a the reference radius appearing in the definition of the * @param[in] a the reference radius appearing in the definition of the
* sum. * sum.
* @param[in] norm the normalization for the associated Legendre * @param[in] norm the normalization for the associated Legendre
* polynomials, either SphericalHarmonic2::FULL (the default) or * polynomials, either SphericalHarmonic2::FULL (the default) or
* SphericalHarmonic2::SCHMIDT. * SphericalHarmonic2::SCHMIDT.
* @exception GeographicErr if \e N and \e N1 do not satisfy \e N &ge;
* \e N1 &ge; &minus;1, and similarly for \e N2.
* @exception GeographicErr if any of the vectors of coefficients is no
t
* large enough.
* *
* See SphericalHarmonic for the way the coefficients should be stored. \e * See SphericalHarmonic for the way the coefficients should be stored. \e
* N1 and \e N2 should satisfy \e N1 <= \e N and \e N2 <= \e N. * N1 and \e N2 should satisfy \e N1 ≤ \e N and \e N2 &le; \e N.
* *
* The class stores <i>pointers</i> to the first elements of \e C, \e S , \e * The class stores <i>pointers</i> to the first elements of \e C, \e S , \e
* C', \e S', \e C'', and \e S''. These arrays should not be altered o r * C', \e S', \e C'', and \e S''. These arrays should not be altered o r
* destroyed during the lifetime of a SphericalHarmonic object. * destroyed during the lifetime of a SphericalHarmonic object.
********************************************************************** / ********************************************************************** /
SphericalHarmonic2(const std::vector<real>& C, SphericalHarmonic2(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, int N,
const std::vector<real>& C1, const std::vector<real>& C1,
const std::vector<real>& S1, const std::vector<real>& S1,
skipping to change at line 142 skipping to change at line 145
* @param[in] S2 the coefficients \e S''<sub>\e nm</sub>. * @param[in] S2 the coefficients \e S''<sub>\e nm</sub>.
* @param[in] N2 the degree used to determine the layout of \e C'' and \e * @param[in] N2 the degree used to determine the layout of \e C'' and \e
* S''. * S''.
* @param[in] nmx2 the maximum degree used for \e C'' and \e S''. * @param[in] nmx2 the maximum degree used for \e C'' and \e S''.
* @param[in] mmx2 the maximum order used for \e C'' and \e S''. * @param[in] mmx2 the maximum order used for \e C'' and \e S''.
* @param[in] a the reference radius appearing in the definition of the * @param[in] a the reference radius appearing in the definition of the
* sum. * sum.
* @param[in] norm the normalization for the associated Legendre * @param[in] norm the normalization for the associated Legendre
* polynomials, either SphericalHarmonic2::FULL (the default) or * polynomials, either SphericalHarmonic2::FULL (the default) or
* SphericalHarmonic2::SCHMIDT. * SphericalHarmonic2::SCHMIDT.
* @exception GeographicErr if the parameters do not satisfy \e N &ge;
\e
* nmx &ge; \e mmx &ge; &minus;1; \e N1 &ge; \e nmx1 &ge; \e mmx1 &ge
;
* &minus;1; \e N &ge; \e N1; \e nmx &ge; \e nmx1; \e mmx &ge; \e mmx
1;
* and similarly for \e N2, \e nmx2, and \e mmx2.
* @exception GeographicErr if any of the vectors of coefficients is no
t
* large enough.
* *
* The class stores <i>pointers</i> to the first elements of \e C, \e S , \e * The class stores <i>pointers</i> to the first elements of \e C, \e S , \e
* C', \e S', \e C'', and \e S''. These arrays should not be altered o r * C', \e S', \e C'', and \e S''. These arrays should not be altered o r
* destroyed during the lifetime of a SphericalHarmonic object. * destroyed during the lifetime of a SphericalHarmonic object.
********************************************************************** / ********************************************************************** /
SphericalHarmonic2(const std::vector<real>& C, SphericalHarmonic2(const std::vector<real>& C,
const std::vector<real>& S, const std::vector<real>& S,
int N, int nmx, int mmx, int N, int nmx, int mmx,
const std::vector<real>& C1, const std::vector<real>& C1,
const std::vector<real>& S1, const std::vector<real>& S1,
int N1, int nmx1, int mmx1, int N1, int nmx1, int mmx1,
const std::vector<real>& C2, const std::vector<real>& C2,
const std::vector<real>& S2, const std::vector<real>& S2,
int N2, int nmx2, int mmx2, int N2, int nmx2, int mmx2,
real a, unsigned norm = FULL) real a, unsigned norm = FULL)
: _a(a) : _a(a)
, _norm(norm) { , _norm(norm) {
if (!(nmx1 <= nmx && nmx2 <= nmx)) if (!(nmx1 <= nmx && nmx2 <= nmx))
throw GeographicErr("nmx1 and nmx2 cannot be larger that nmx"); throw GeographicErr("nmx1 and nmx2 cannot be larger that nmx");
if (!(mmx1 <= mmx && mmx2 <= mmx)) if (!(mmx1 <= mmx && mmx2 <= mmx))
throw GeographicErr("mmx1 and mmx2cannot be larger that mmx"); throw GeographicErr("mmx1 and mmx2 cannot be larger that mmx");
_c[0] = SphericalEngine::coeff(C, S, N, nmx, mmx); _c[0] = SphericalEngine::coeff(C, S, N, nmx, mmx);
_c[1] = SphericalEngine::coeff(C1, S1, N1, nmx1, mmx1); _c[1] = SphericalEngine::coeff(C1, S1, N1, nmx1, mmx1);
_c[2] = SphericalEngine::coeff(C2, S2, N2, nmx2, mmx2); _c[2] = SphericalEngine::coeff(C2, S2, N2, nmx2, mmx2);
} }
/** /**
* A default constructor so that the object can be created when the * A default constructor so that the object can be created when the
* constructor for another object is initialized. This default object can * constructor for another object is initialized. This default object can
* then be reset with the default copy assignment operator. * then be reset with the default copy assignment operator.
********************************************************************** / ********************************************************************** /
skipping to change at line 252 skipping to change at line 261
/** /**
* Create a CircularEngine to allow the efficient evaluation of several * Create a CircularEngine to allow the efficient evaluation of several
* points on a circle of latitude at fixed values of \e tau1 and \e tau 2. * points on a circle of latitude at fixed values of \e tau1 and \e tau 2.
* *
* @param[in] tau1 multiplier for correction coefficients \e C' and \e S'. * @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
* @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] p the radius of the circle. * @param[in] p the radius of the circle.
* @param[in] z the height of the circle above the equatorial plane. * @param[in] z the height of the circle above the equatorial plane.
* @param[in] gradp if true the returned object will be able to compute the * @param[in] gradp if true the returned object will be able to compute the
* gradient of the sum. * gradient of the sum.
* @exception std::bad_alloc if the memory for the CircularEngine can't
be
* allocated.
* @return the CircularEngine object. * @return the CircularEngine object.
* *
* SphericalHarmonic2::operator()() exchanges the order of the sums in the * SphericalHarmonic2::operator()() exchanges the order of the sums in the
* definition, i.e., sum(n = 0..N)[sum(m = 0..n)[...]] becomes sum(m = * definition, i.e., &sum;<sub>n = 0..N</sub> &sum;<sub>m = 0..n</sub>
* 0..N)[sum(n = m..N)[...]]. SphericalHarmonic2::Circle performs the * becomes &sum;<sub>m = 0..N</sub> &sum;<sub>n = m..N</sub>..
* inner sum over degree \e n (which entails about <i>N</i><sup>2</sup> * SphericalHarmonic2::Circle performs the inner sum over degree \e n
* operations). Calling CircularEngine::operator()() on the returned * (which entails about <i>N</i><sup>2</sup> operations). Calling
* object performs the outer sum over the order \e m (about \e N * CircularEngine::operator()() on the returned object performs the out
* operations). This routine may throw a bad_alloc exception in the er
* CircularEngine constructor. * sum over the order \e m (about \e N operations).
* *
* See SphericalHarmonic::Circle for an example of its use. * See SphericalHarmonic::Circle for an example of its use.
********************************************************************** / ********************************************************************** /
CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp) CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp)
const { const {
real f[] = {1, tau1, tau2}; real f[] = {1, tau1, tau2};
switch (_norm) { switch (_norm) {
case FULL: case FULL:
return gradp ? return gradp ?
SphericalEngine::Circle<true, SphericalEngine::FULL, 3> SphericalEngine::Circle<true, SphericalEngine::FULL, 3>
 End of changes. 8 change blocks. 
12 lines changed or deleted 29 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-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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 \ #define GEOGRAPHICLIB_TRANSVERSEMERCATOR_HPP 1
"$Id: 967bdfb37093c5355c1ac8e399b06195e33494da $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#if !defined(TM_TX_MAXPOW) #if !defined(TM_TX_MAXPOW)
/** /**
* The order of the series approximation used in TransverseMercator. * The order of the series approximation used in TransverseMercator.
* TM_TX_MAXPOW can be set to any integer in [4, 8]. * TM_TX_MAXPOW can be set to any integer in [4, 8].
**********************************************************************/ **********************************************************************/
#define TM_TX_MAXPOW \ # define TM_TX_MAXPOW \
(GEOGRAPHICLIB_PREC == 1 ? 6 : (GEOGRAPHICLIB_PREC == 0 ? 4 : 8)) (GEOGRAPHICLIB_PREC == 1 ? 6 : (GEOGRAPHICLIB_PREC == 0 ? 4 : 8))
#endif #endif
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Transverse Mercator projection * \brief Transverse Mercator projection
* *
* This uses Kr&uuml;ger's method which evaluates the projection and its * This uses Kr&uuml;ger's method which evaluates the projection and its
* inverse in terms of a series. See * inverse in terms of a series. See
* - L. Kr&uuml;ger, * - L. Kr&uuml;ger,
* <a href="http://dx.doi.org/10.2312/GFZ.b103-krueger28"> Konforme * <a href="http://dx.doi.org/10.2312/GFZ.b103-krueger28"> Konforme
* Abbildung des Erdellipsoids in der Ebene</a> (Conformal mapping of the * Abbildung des Erdellipsoids in der Ebene</a> (Conformal mapping of the
* ellipsoidal earth to the plane), Royal Prussian Geodetic Institute, New * ellipsoidal earth to the plane), Royal Prussian Geodetic Institute, New
* Series 52, 172 pp. (1912). * Series 52, 172 pp. (1912).
* - C. F. F. Karney, * - C. F. F. Karney,
* <a href="http://dx.doi.org/10.1007/s00190-011-0445-3"> * <a href="http://dx.doi.org/10.1007/s00190-011-0445-3">
* Transverse Mercator with an accuracy of a few nanometers,</a> * Transverse Mercator with an accuracy of a few nanometers,</a>
* J. Geodesy 85(8), 475-485 (Aug. 2011); * J. Geodesy 85(8), 475&ndash;485 (Aug. 2011);
* preprint * preprint
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>. * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>.
* *
* Kr&uuml;ger's method has been extended from 4th to 6th order. The max imum * Kr&uuml;ger's method has been extended from 4th to 6th order. The max imum
* error is 5 nm (5 nanometers), ground distance, for all positions withi n 35 * error is 5 nm (5 nanometers), ground distance, for all positions withi n 35
* degrees of the central meridian. The error in the convergence is * degrees of the central meridian. The error in the convergence is 2
* 2e-15&quot; and the relative error in the scale is 6e-12%%. See Sec. * &times; 10<sup>&minus;15</sup>&quot; and the relative error in the sca
4 of le
* is 6 &minus; 10<sup>&minus;12</sup>%%. See Sec. 4 of
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for detai ls. * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for detai ls.
* The speed penalty in going to 6th order is only about 1%. * The speed penalty in going to 6th order is only about 1%.
* TransverseMercatorExact is an alternative implementation of the projec tion * TransverseMercatorExact is an alternative implementation of the projec tion
* using exact formulas which yield accurate (to 8 nm) results over the * using exact formulas which yield accurate (to 8 nm) results over the
* entire ellipsoid. * entire ellipsoid.
* *
* The ellipsoid parameters and the central scale are set in the construc tor. * The ellipsoid parameters and the central scale are set in the construc tor.
* The central meridian (which is a trivial shift of the longitude) is * The central meridian (which is a trivial shift of the longitude) is
* specified as the \e lon0 argument of the TransverseMercator::Forward a nd * specified as the \e lon0 argument of the TransverseMercator::Forward a nd
* TransverseMercator::Reverse functions. The latitude of origin is take n to * TransverseMercator::Reverse functions. The latitude of origin is take n to
skipping to change at line 114 skipping to change at line 114
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.
* @param[in] k0 central scale factor. * @param[in] k0 central scale factor.
* * @exception GeographicLib if \e a, (1 &minus; \e f ) \e a, or \e k0 i
* An exception is thrown if either of the axes of the ellipsoid or \e s
k0 * not positive.
* is not positive.
********************************************************************** / ********************************************************************** /
TransverseMercator(real a, real f, real k0); TransverseMercator(real a, real f, real k0);
/** /**
* Forward projection, from geographic to transverse Mercator. * Forward projection, from geographic to transverse Mercator.
* *
* @param[in] lon0 central meridian of the projection (degrees). * @param[in] lon0 central meridian of the 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).
* @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
* [-90, 90]; \e lon and \e lon0 should be in the range [-180, 360]. * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
* 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 throw();
/** /**
* 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
* [-180, 360]. The value of \e lon returned is in the range [-180, 18 * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
0). * 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 throw();
/** /**
* 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 throw() {
real gamma, k; real gamma, k;
 End of changes. 7 change blocks. 
14 lines changed or deleted 14 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-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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 \ #define GEOGRAPHICLIB_TRANSVERSEMERCATOREXACT_HPP 1
"$Id: 1ec9c881231a9ed2d2256832a9e642e0197deaa1 $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <GeographicLib/EllipticFunction.hpp> #include <GeographicLib/EllipticFunction.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief An exact implementation of the transverse Mercator projection * \brief An exact implementation of the transverse Mercator projection
* *
* Implementation of the Transverse Mercator Projection given in * Implementation of the Transverse Mercator Projection given in
skipping to change at line 34 skipping to change at line 33
* <a href="http://dx.doi.org/10.3138/X687-1574-4325-WM62"> Conformal * <a href="http://dx.doi.org/10.3138/X687-1574-4325-WM62"> Conformal
* Projections Based On Jacobian Elliptic Functions</a>, Part V of * Projections Based On Jacobian Elliptic Functions</a>, Part V of
* Conformal Projections Based on Elliptic Functions, * Conformal Projections Based on Elliptic Functions,
* (B. V. Gutsell, Toronto, 1976), 128pp., * (B. V. Gutsell, Toronto, 1976), 128pp.,
* ISBN: 0919870163 * ISBN: 0919870163
* (also appeared as: * (also appeared as:
* Monograph 16, Suppl. No. 1 to Canadian Cartographer, Vol 13). * Monograph 16, Suppl. No. 1 to Canadian Cartographer, Vol 13).
* - C. F. F. Karney, * - C. F. F. Karney,
* <a href="http://dx.doi.org/10.1007/s00190-011-0445-3"> * <a href="http://dx.doi.org/10.1007/s00190-011-0445-3">
* Transverse Mercator with an accuracy of a few nanometers,</a> * Transverse Mercator with an accuracy of a few nanometers,</a>
* J. Geodesy 85(8), 475-485 (Aug. 2011); * J. Geodesy 85(8), 475&ndash;485 (Aug. 2011);
* preprint * preprint
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>. * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a>.
* *
* Lee gives the correct results for forward and reverse transformations * Lee gives the correct results for forward and reverse transformations
* subject to the branch cut rules (see the description of the \e extendp * subject to the branch cut rules (see the description of the \e extendp
* argument to the constructor). The maximum error is about 8 nm (8 * argument to the constructor). The maximum error is about 8 nm (8
* nanometers), ground distance, for the forward and reverse transformati ons. * nanometers), ground distance, for the forward and reverse transformati ons.
* The error in the convergence is 2e-15&quot;, the relative error in the * The error in the convergence is 2 &times; 10<sup>&minus;15</sup>&quot;
* scale is 7e-12%%. See Sec. 3 of ,
* the relative error in the scale is 7 &times; 10<sup>&minus;12</sup>%%.
* See Sec. 3 of
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for detai ls. * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for detai ls.
* The method is "exact" in the sense that the errors are close to the * The method is "exact" in the sense that the errors are close to the
* round-off limit and that no changes are needed in the algorithms for t hem * round-off limit and that no changes are needed in the algorithms for t hem
* to be used with reals of a higher precision. Thus the errors using lo ng * to be used with reals of a higher precision. Thus the errors using lo ng
* double (with a 64-bit fraction) are about 2000 times smaller than usin g * double (with a 64-bit fraction) are about 2000 times smaller than usin g
* double (with a 53-bit fraction). * double (with a 53-bit fraction).
* *
* This algorithm is about 4.5 times slower than the 6th-order Kr&uuml;ge r * This algorithm is about 4.5 times slower than the 6th-order Kr&uuml;ge r
* method, TransverseMercator, taking about 11 us for a combined forward and * method, TransverseMercator, taking about 11 us for a combined forward and
* reverse projection on a 2.66 GHz Intel machine (g++, version 4.3.0, -O 3). * reverse projection on a 2.66 GHz Intel machine (g++, version 4.3.0, -O 3).
skipping to change at line 138 skipping to change at line 138
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.
* @param[in] extendp use extended domain. * @param[in] extendp use extended domain.
* @exception GeographicLib if \e a, \e f, or \e k0 is not positive.
* *
* The transverse Mercator projection has a branch point singularity at \e * The transverse Mercator projection has a branch point singularity at \e
* lat = 0 and \e lon - \e lon0 = 90 (1 - \e e) or (for * lat = 0 and \e lon &minus; \e lon0 = 90 (1 &minus; \e e) or (for
* TransverseMercatorExact::UTM) x = 18381 km, y = 0m. The \e extendp * TransverseMercatorExact::UTM) x = 18381 km, y = 0m. The \e extendp
* argument governs where the branch cut is placed. With \e extendp = * argument governs where the branch cut is placed. With \e extendp =
* false, the "standard" convention is followed, namely the cut is plac ed * false, the "standard" convention is followed, namely the cut is plac ed
* along x > 18381 km, y = 0m. Forward can be called with any \e lat a * along \e x > 18381 km, \e y = 0m. Forward can be called with any \e
nd lat
* \e lon then produces the transformation shown in Lee, Fig 46. Rever * and \e lon then produces the transformation shown in Lee, Fig 46.
se * Reverse analytically continues this in the &plusmn; \e x direction.
* analytically continues this in the +/- \e x direction. As a As
* consequence, Reverse may map multiple points to the same geographic * a consequence, Reverse may map multiple points to the same geographi
c
* location; for example, for TransverseMercatorExact::UTM, \e x = * location; for example, for TransverseMercatorExact::UTM, \e x =
* 22051449.037349 m, \e y = -7131237.022729 m and \e x = 29735142.3783 * 22051449.037349 m, \e y = &minus;7131237.022729 m and \e x =
57 * 29735142.378357 m, \e y = 4235043.607933 m both map to \e lat =
* m, \e y = 4235043.607933 m both map to \e lat = -2 deg, \e lon = 88 * &minus;2&deg;, \e lon = 88&deg;.
deg.
* *
* With \e extendp = true, the branch cut is moved to the lower left * With \e extendp = true, the branch cut is moved to the lower left
* quadrant. The various symmetries of the transverse Mercator project ion * quadrant. The various symmetries of the transverse Mercator project ion
* can be used to explore the projection on any sheet. In this mode th e * can be used to explore the projection on any sheet. In this mode th e
* domains of \e lat, \e lon, \e x, and \e y are restricted to * domains of \e lat, \e lon, \e x, and \e y are restricted to
* - the union of * - the union of
* - \e lat in [0, 90] and \e lon - \e lon0 in [0, 90] * - \e lat in [0, 90] and \e lon &minus; \e lon0 in [0, 90]
* - \e lat in (-90, 0] and \e lon - \e lon0 in [90 (1 - \e e), 90] * - \e lat in (-90, 0] and \e lon &minus; \e lon0 in [90 (1 &minus;
\e
e), 90]
* - the union of * - the union of
* - <i>x</i>/(\e k0 \e a) in [0, inf) and * - <i>x</i>/(\e k0 \e a) in [0, &infin;) and
* <i>y</i>/(\e k0 \e a) in [0, E(<i>e</i><sup>2</sup>)] * <i>y</i>/(\e k0 \e a) in [0, E(<i>e</i><sup>2</sup>)]
* - <i>x</i>/(\e k0 \e a) in [K(1 - <i>e</i><sup>2</sup>) - E(1 - * - <i>x</i>/(\e k0 \e a) in [K(1 &minus; <i>e</i><sup>2</sup>) &min
* <i>e</i><sup>2</sup>), inf) and <i>y</i>/(\e k0 \e a) in (-inf, us;
0] * E(1 &minus; <i>e</i><sup>2</sup>), &infin;) and <i>y</i>/(\e k0
\e
* a) in (&minus;&infin;, 0]
* . * .
* See Sec. 5 of * See Sec. 5 of
* <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for a f ull * <a href="http://arxiv.org/abs/1002.1417">arXiv:1002.1417</a> for a f ull
* discussion of the treatment of the branch cut. * discussion of the treatment of the branch cut.
* *
* The method will work for all ellipsoids used in terrestrial geodesy. * The method will work for all ellipsoids used in terrestrial geodesy.
* The method cannot be applied directly to the case of a sphere (\e f = 0) * The method cannot be applied directly to the case of a sphere (\e f = 0)
* because some the constants characterizing this method diverge in tha t * because some the constants characterizing this method diverge in tha t
* limit, and in practice, \e f should be larger than about numeric_lim * limit, and in practice, \e f should be larger than about
its< * numeric_limits<real>::epsilon(). However, TransverseMercator treats
* real >::%epsilon(). However, TransverseMercator treats the sphere the
* exactly. An exception is thrown if either axis of the ellipsoid or * sphere exactly.
\e
* k0 is not positive or if \e f <= 0.
********************************************************************** / ********************************************************************** /
TransverseMercatorExact(real a, real f, real k0, bool extendp = false); TransverseMercatorExact(real a, real f, real k0, bool extendp = false);
/** /**
* Forward projection, from geographic to transverse Mercator. * Forward projection, from geographic to transverse Mercator.
* *
* @param[in] lon0 central meridian of the projection (degrees). * @param[in] lon0 central meridian of the 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).
* @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
* [-90, 90]; \e lon and \e lon0 should be in the range [-180, 360]. * [&minus;90&deg;, 90&deg;]; \e lon and \e lon0 should be in the
* 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 throw();
/** /**
* 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
* [-180, 360]. The value of \e lon returned is in the range [-180, 18 * [&minus;540&deg;, 540&deg;). The value of \e lon returned is in
0). * 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 throw();
/** /**
* 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 throw() {
 End of changes. 13 change blocks. 
31 lines changed or deleted 36 lines changed or added


 UTMUPS.hpp   UTMUPS.hpp 
/** /**
* \file UTMUPS.hpp * \file UTMUPS.hpp
* \brief Header for GeographicLib::UTMUPS class * \brief Header for GeographicLib::UTMUPS class
* *
* Copyright (c) Charles Karney (2008-2011) <charles@karney.com> and licens ed * Copyright (c) Charles Karney (2008-2011) <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_UTMUPS_HPP) #if !defined(GEOGRAPHICLIB_UTMUPS_HPP)
#define GEOGRAPHICLIB_UTMUPS_HPP \ #define GEOGRAPHICLIB_UTMUPS_HPP 1
"$Id: ae9e09602676178c7d9a7e3fdb1c6018b3d87bc9 $"
#include <sstream> #include <sstream>
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
namespace GeographicLib { namespace GeographicLib {
/** /**
* \brief Convert between geographic coordinates and UTM/UPS * \brief Convert between geographic coordinates and UTM/UPS
* *
* UTM and UPS are defined * UTM and UPS are defined
skipping to change at line 85 skipping to change at line 84
// 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:
/** /**
* In this class we bring together the UTM and UPS coordinates systems. * In this class we bring together the UTM and UPS coordinates systems.
* The UTM divides the earth between latitudes -80 and 84 into 60 zones * The UTM divides the earth between latitudes &minus;80&deg; and 84&de
* numbered 1 thru 60. Zone assign zone number 0 to the UPS regions, g;
* covering the two poles. Within UTMUPS, non-negative zone numbers re * into 60 zones numbered 1 thru 60. Zone assign zone number 0 to the
fer UPS
* to one of the "physical" zones, 0 for UPS and [1, 60] for UTM. Nega * regions, covering the two poles. Within UTMUPS, non-negative zone
tive * numbers refer to one of the "physical" zones, 0 for UPS and [1, 60]
* "pseudo-zone" numbers are used to select one of the physical zones. for
* UTM. Negative "pseudo-zone" numbers are used to select one of the
* physical zones.
********************************************************************** / ********************************************************************** /
enum zonespec { enum zonespec {
/** /**
* The smallest pseudo-zone number. * The smallest pseudo-zone number.
******************************************************************** **/ ******************************************************************** **/
MINPSEUDOZONE = -4, MINPSEUDOZONE = -4,
/** /**
* A marker for an undefined or invalid zone. Equivalent to NaN. * A marker for an undefined or invalid zone. Equivalent to NaN.
******************************************************************** **/ ******************************************************************** **/
INVALID = -4, INVALID = -4,
/** /**
* If a coordinate already include zone information (e.g., it is an M GRS * If a coordinate already include zone information (e.g., it is an M GRS
* coordinate), use that, otherwise apply the UTMUPS::STANDARD rules. * coordinate), use that, otherwise apply the UTMUPS::STANDARD rules.
******************************************************************** **/ ******************************************************************** **/
MATCH = -3, MATCH = -3,
/** /**
* Apply the standard rules for UTM zone assigment extending the UTM zone * Apply the standard rules for UTM zone assigment extending the UTM zone
* to each pole to give a zone number in [1, 60]. For example, use U TM * to each pole to give a zone number in [1, 60]. For example, use U TM
* zone 38 for longitude in [42, 48). The rules include the Norway a * zone 38 for longitude in [42&deg;, 48&deg;). The rules include th
nd e
* Svalbard exceptions. * Norway and Svalbard exceptions.
******************************************************************** **/ ******************************************************************** **/
UTM = -2, UTM = -2,
/** /**
* Apply the standard rules for zone assignment to give a zone number in * Apply the standard rules for zone assignment to give a zone number in
* [0, 60]. If the latitude is not in [-80, 84), then use UTMUPS::UP * [0, 60]. If the latitude is not in [&minus;80&deg;, 84&deg;), the
S = n
* 0, otherwise apply the rules for UTMUPS::UTM. The tests on latitu * use UTMUPS::UPS = 0, otherwise apply the rules for UTMUPS::UTM. T
des he
* and longitudes are all closed on the lower end open on the upper. * tests on latitudes and longitudes are all closed on the lower end
* Thus for UTM zone 38, latitude is in [-80, 84) and longitude is in open
* [42, 48). * on the upper. Thus for UTM zone 38, latitude is in [&minus;80&deg
;,
* 84&deg;) and longitude is in [42&deg;, 48&deg;).
******************************************************************** **/ ******************************************************************** **/
STANDARD = -1, STANDARD = -1,
/** /**
* The largest pseudo-zone number. * The largest pseudo-zone number.
******************************************************************** **/ ******************************************************************** **/
MAXPSEUDOZONE = -1, MAXPSEUDOZONE = -1,
/** /**
* The smallest physical zone number. * The smallest physical zone number.
******************************************************************** **/ ******************************************************************** **/
MINZONE = 0, MINZONE = 0,
skipping to change at line 152 skipping to change at line 152
* The largest physical zone number. * The largest physical zone number.
******************************************************************** **/ ******************************************************************** **/
MAXZONE = 60, MAXZONE = 60,
}; };
/** /**
* The standard zone. * The standard zone.
* *
* @param[in] lat latitude (degrees). * @param[in] lat latitude (degrees).
* @param[in] lon longitude (degrees). * @param[in] lon longitude (degrees).
* @param[in] setzone zone override (optional). * @param[in] setzone zone override (optional). If omitted, use the
* standard rules for picking the zone. If \e setzone is given then
use
* that zone if it is non-negative, otherwise apply the rules given i
n
* UTMUPS::zonespec.
* @exception GeographicErr if \e setzone is outside the range
* [UTMUPS::MINPSEUDOZONE, UTMUPS::MAXZONE] = [&minus;4, 60].
* *
* This is exact. If the optional argument \e setzone is given then us * This is exact.
e
* that zone if it is non-negative, otherwise apply the rules given in
* UTMUPS::zonespec. Throws an error if \e setzone is outsize the rang
e
* [UTMUPS::MINPSEUDOZONE, UTMUPS::MAXZONE] = [-4, 60].
********************************************************************** / ********************************************************************** /
static int StandardZone(real lat, real lon, int setzone = STANDARD); static int StandardZone(real lat, real lon, int setzone = STANDARD);
/** /**
* Forward projection, from geographic to UTM/UPS. * Forward projection, from geographic to UTM/UPS.
* *
* @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] 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).
* @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.
* @param[in] setzone zone override. * @param[in] setzone zone override (optional).
* @param[in] mgrslimits if true enforce the stricter MGRS limits on th e * @param[in] mgrslimits if true enforce the stricter MGRS limits on th e
* coordinates (default = false). * coordinates (default = false).
* * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
* The preferred zone for the result can be specified with \e setzone, * 90&deg;].
see * @exception GeographicErr if \e lon is not in [&minus;540&deg;,
* UTMUPS::StandardZone. Throw error if the resulting easting or north * 540&deg;).
ing * @exception GeographicLib if the resulting \e x or \e y is out of all
* is outside the allowed range (see Reverse), in which case the argume owed
nts * range (see Reverse); in this case, these arguments are unchanged.
* are unchanged. This also returns meridian convergence \e gamma *
* (degrees) and scale \e k. The accuracy of the conversion is about 5 * If \e setzone is omitted, use the standard rules for picking the zon
nm. e.
* If \e setzone is given then use that zone if it is non-negative,
* otherwise apply the rules given in UTMUPS::zonespec. The accuracy o
f
* the conversion is about 5nm.
*
* The northing \e y jumps by UTMUPS::UTMShift() when crossing the equa
tor
* in the southerly direction. Sometimes it is useful to remove this
* discontinuity in \e y by extending the "northern" hemisphere with
* \code
double lat = -1, lon = 123;
int zone;
bool northp;
double x, y, gamma, k;
GeographicLib::UTMUPS::Forward(lat, lon, zone, northp, x, y, gamma, k);
if (zone > 0 && !northp) {
northp = true;
y -= GeographicLib::UTMUPS::UTMShift();
}
\endcode
********************************************************************** / ********************************************************************** /
static void Forward(real lat, real lon, static void Forward(real lat, real lon,
int& zone, bool& northp, real& x, real& y, int& zone, bool& northp, real& x, real& y,
real& gamma, real& k, real& gamma, real& k,
int setzone = STANDARD, bool mgrslimits = false); int setzone = STANDARD, bool mgrslimits = false);
/** /**
* Reverse projection, from UTM/UPS to geographic. * Reverse projection, from UTM/UPS to geographic.
* *
* @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] 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.
* @param[in] mgrslimits if true enforce the stricter MGRS limits on th e * @param[in] mgrslimits if true enforce the stricter MGRS limits on th e
* coordinates (default = false). * coordinates (default = false).
* @exception GeographicLib if \e zone, \e x, or \e y is out of allowed
* range; this this case the arguments are unchanged.
* *
* Throw error if easting or northing is outside the allowed range (see * The accuracy of the conversion is about 5nm.
* below), in which case the arguments are unchanged. 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 northing s * [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, 3100km] 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
skipping to change at line 253 skipping to change at line 275
real gamma, k; real gamma, k;
Reverse(zone, northp, x, y, lat, lon, gamma, k, mgrslimits); Reverse(zone, northp, x, y, lat, lon, gamma, k, mgrslimits);
} }
/** /**
* 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 of \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 ere * hemisphere letter, N or S. For UPS, it consists just of the hemisph ere
* letter. The returned value of \e zone is UTMUPS::UPS = 0 for UPS. Note * letter. The returned value of \e zone is UTMUPS::UPS = 0 for UPS. Note
* well that "38S" indicates the southern hemisphere of zone 38 and not * well that "38S" indicates the southern hemisphere of zone 38 and not
* latitude band S, [32, 40]. N, 01S, 2N, 38S are legal. 0N, 001S, 61 N, * latitude band S, [32, 40]. N, 01S, 2N, 38S are legal. 0N, 001S, 61 N,
* 38P are illegal. INV is a special value for which the returned valu e of * 38P are illegal. INV is a special value for which the returned valu e of
* \e is UTMUPS::INVALID. Throws an error is the zone string is malfor med. * \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[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 of \e zone is out of range (see below).
* @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);
 End of changes. 15 change blocks. 
44 lines changed or deleted 72 lines changed or added


 Utility.hpp   Utility.hpp 
/** /**
* \file Utility.hpp * \file Utility.hpp
* \brief Header for GeographicLib::Utility class * \brief Header for GeographicLib::Utility class
* *
* Copyright (c) Charles Karney (2011, 2012) <charles@karney.com> and licen sed * Copyright (c) Charles Karney (2011-2012) <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_UTILITY_HPP) #if !defined(GEOGRAPHICLIB_UTILITY_HPP)
#define GEOGRAPHICLIB_UTILITY_HPP \ #define GEOGRAPHICLIB_UTILITY_HPP 1
"$Id: 92c92fcb8ea92116fed01909c2611934b708e4cd $"
#include <GeographicLib/Constants.hpp> #include <GeographicLib/Constants.hpp>
#include <iomanip> #include <iomanip>
#include <vector> #include <vector>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
namespace GeographicLib { namespace GeographicLib {
skipping to change at line 115 skipping to change at line 114
} }
/** /**
* 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.
* @param[in] check whether to check the date. * @param[in] check whether to check the date.
* @exception GeographicErr if the date is invalid and \e check is true .
* @return the sequential day number. * @return the sequential day number.
*
* If \e check is true and the date is invalid an exception is thrown.
********************************************************************** / ********************************************************************** /
static int day(int y, int m, int d, bool check) { static int day(int y, int m, int d, bool check) {
int s = day(y, m, d); int s = day(y, m, d);
if (!check) if (!check)
return s; return s;
int y1, m1, d1; int y1, m1, d1;
date(s, y1, m1, d1); date(s, y1, m1, d1);
if (!(s > 0 && y == y1 && m == m1 && d == d1)) if (!(s > 0 && y == y1 && m == m1 && d == d1))
throw GeographicErr("Invalid date " + throw GeographicErr("Invalid date " +
str(y) + "-" + str(m) + "-" + str(d) str(y) + "-" + str(m) + "-" + str(d)
skipping to change at line 172 skipping to change at line 170
/** /**
* Given a date as a string in the format yyyy, yyyy-mm, or yyyy-mm-dd, * Given a date as a string in the format yyyy, yyyy-mm, or yyyy-mm-dd,
* return the numeric values for the year, month, and day. No checking is * return the numeric values for the year, month, and day. No checking is
* done on these values. * done on these values.
* *
* @param[in] s the date in string format. * @param[in] s the date in string format.
* @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.
* @exception GeographicErr is \e s is malformed.
********************************************************************** / ********************************************************************** /
static void date(const std::string& s, int& y, int& m, int& d) { static void date(const std::string& s, int& y, int& m, int& d) {
int y1, m1 = 1, d1 = 1; int y1, m1 = 1, d1 = 1;
const char* digits = "0123456789"; const char* digits = "0123456789";
std::string::size_type p1 = s.find_first_not_of(digits); std::string::size_type p1 = s.find_first_not_of(digits);
if (p1 == std::string::npos) if (p1 == std::string::npos)
y1 = num<int>(s); y1 = num<int>(s);
else if (s[p1] != '-') else if (s[p1] != '-')
throw GeographicErr("Delimiter not hyphen in date " + s); throw GeographicErr("Delimiter not hyphen in date " + s);
else if (p1 == 0) else if (p1 == 0)
skipping to change at line 210 skipping to change at line 209
} }
y = y1; m = m1; d = d1; y = y1; m = m1; d = d1;
} }
/** /**
* 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, 1 - * @return the day of the week with Sunday, Monday&ndash;Saturday = 0,
6. * 1&ndash;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) throw() { 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, 1 - * @return the day of the week with Sunday, Monday&ndash;Saturday = 0,
6. * 1&ndash;6.
********************************************************************** / ********************************************************************** /
static int dow(int s) throw() { static int dow(int s) throw() {
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.
* @return the fractional year. * @return the fractional year.
* *
* The string is first read as an ordinary number (e.g., 2010 or 2012.5 ); * The string is first read as an ordinary number (e.g., 2010 or 2012.5 );
* if this is successful, the value is returned. Otherwise the string * if this is successful, the value is returned. Otherwise the string
* should be of the form yyyy-mm or yyyy-mm-dd and this is converted to a * should be of the form yyyy-mm or yyyy-mm-dd and this is converted to a
* number with 2010-01-01 giving 2010.0 and 2012-07-03 giving 2012.5. * number with 2010-01-01 giving 2010.0 and 2012-07-03 giving 2012.5.
********************************************************************** / ********************************************************************** /
template<typename T> static T fractionalyear(const std::string& s) { template<typename T> static T fractionalyear(const std::string& s) {
try { try {
return num<T>(s); return num<T>(s);
skipping to change at line 253 skipping to change at line 255
date(s, y, m, d); date(s, y, m, d);
int t = day(y, m, d, true); int t = day(y, m, d, true);
return T(y) + T(t - day(y)) / T(day(y + 1) - day(y)); return T(y) + T(t - day(y)) / T(day(y + 1) - day(y));
} }
/** /**
* Convert a object of type T to a string. * Convert a object of type T to a string.
* *
* @tparam T the type of the argument. * @tparam T the type of the argument.
* @param[in] x the value to be converted. * @param[in] x the value to be converted.
* @param[in] p the precision used (default -1). * @param[in] p the precision used (default &minus;1).
* @exception std::bad_alloc if memory for the string can't be allocate
d.
* @return the string representation. * @return the string representation.
* *
* If \e p >= 0, then the number fixed format is used with p bits of * If \e p 0, then the number fixed format is used with p bits of
* precision. With p < 0, there is no manipulation of the format. * precision. With p < 0, there is no manipulation of the format.
********************************************************************** / ********************************************************************** /
template<typename T> static std::string str(T x, int p = -1) { template<typename T> static std::string str(T x, int p = -1) {
if (!std::numeric_limits<T>::is_integer && !Math::isfinite<T>(x)) if (!std::numeric_limits<T>::is_integer && !Math::isfinite<T>(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 (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.
* @return object of type T * @return object of type T
********************************************************************** / ********************************************************************** /
template<typename T> static T num(const std::string& s) { template<typename T> static T num(const std::string& s) {
T x; T x;
std::string errmsg; std::string errmsg;
do { // Executed once (provides the ability to br eak) do { // Executed once (provides the ability to br eak)
std::istringstream is(s); std::istringstream is(s);
if (!(is >> x)) { if (!(is >> x)) {
errmsg = "Cannot decode " + s; errmsg = "Cannot decode " + s;
break; break;
skipping to change at line 302 skipping to change at line 306
if (x == 0) if (x == 0)
throw GeographicErr(errmsg); throw GeographicErr(errmsg);
return x; return x;
} }
/** /**
* Match "nan" and "inf" (and variants thereof) in a string. * Match "nan" and "inf" (and variants thereof) in a string.
* *
* @tparam T the type of the return value. * @tparam T the type of the return value.
* @param[in] s the string to be matched. * @param[in] s the string to be matched.
* @return appropriate special value (+/-inf, nan) or 0 is none is foun * @return appropriate special value (&plusmn;&infin;, nan) or 0 is non
d. e is
* found.
********************************************************************** / ********************************************************************** /
template<typename T> static T nummatch(const std::string& s) { template<typename T> static T nummatch(const std::string& s) {
if (s.length() < 3) if (s.length() < 3)
return 0; return 0;
std::string t; std::string t;
t.resize(s.length()); t.resize(s.length());
std::transform(s.begin(), s.end(), t.begin(), (int(*)(int))std::toupp er); std::transform(s.begin(), s.end(), t.begin(), (int(*)(int))std::toupp er);
for (size_t i = s.length(); i--;) for (size_t i = s.length(); i--;)
t[i] = std::toupper(s[i]); t[i] = std::toupper(s[i]);
int sign = t[0] == '-' ? -1 : 1; int sign = t[0] == '-' ? -1 : 1;
skipping to change at line 332 skipping to change at line 337
else if (t == "INF" || t == "1.#INF") else if (t == "INF" || t == "1.#INF")
return sign * Math::infinity<T>(); return sign * Math::infinity<T>();
return 0; return 0;
} }
/** /**
* Read a simple fraction, e.g., 3/4, from a string to an object of typ e T. * Read a simple fraction, e.g., 3/4, from a string to an object of typ e 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 fraction of ty pe T.
* @return object of type T * @return object of type T
********************************************************************** / ********************************************************************** /
template<typename T> static T fract(const std::string& s) { template<typename T> static T fract(const std::string& s) {
std::string::size_type delim = s.find('/'); std::string::size_type delim = s.find('/');
return return
!(delim != std::string::npos && delim >= 1 && delim + 2 <= s.size() ) ? !(delim != std::string::npos && delim >= 1 && delim + 2 <= s.size() ) ?
num<T>(s) : num<T>(s) :
// delim in [1, size() - 2] // delim in [1, size() - 2]
num<T>(s.substr(0, delim)) / num<T>(s.substr(delim + 1)); num<T>(s.substr(0, delim)) / num<T>(s.substr(delim + 1));
} }
/** /**
* 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
-1 * &minus;1 is the character is not present.
* 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) throw() {
std::string::size_type r = s.find(toupper(c)); std::string::size_type r = s.find(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).
* @tparam bigendp true if the external storage format is big-endian. * @tparam bigendp true if the external storage format is big-endian.
* @param[in] str the input stream containing the data of type ExtT * @param[in] str the input stream containing the data of type ExtT
* (external). * (external).
* @param[out] array the output array of type IntT (internal). * @param[out] array the output array of type IntT (internal).
* @param[in] num the size of the array. * @param[in] num the size of the array.
* @exception GeographicErr if the data cannot be read.
********************************************************************** / ********************************************************************** /
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 (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())
skipping to change at line 416 skipping to change at line 423
* Read data of type ExtT from a binary stream to a vector array of typ e * Read data of type ExtT from a binary stream to a vector array of typ e
* IntT. The data in the file is in (bigendp ? big : little)-endian * IntT. The data in the file is in (bigendp ? big : little)-endian
* format. * 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).
* @tparam bigendp true if the external storage format is big-endian. * @tparam bigendp true if the external storage format is big-endian.
* @param[in] str the input stream containing the data of type ExtT * @param[in] str the input stream containing the data of type ExtT
* (external). * (external).
* @param[out] array the output vector of type IntT (internal). * @param[out] array the output vector of type IntT (internal).
* @exception GeographicErr if the data cannot be read.
********************************************************************** / ********************************************************************** /
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,
std::vector<IntT>& array) { std::vector<IntT>& array) {
readarray<ExtT, IntT, bigendp>(str, &array[0], array.size()); readarray<ExtT, IntT, bigendp>(str, &array[0], array.size());
} }
/** /**
* 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.
* 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).
* @tparam bigendp true if the external storage format is big-endian. * @tparam bigendp true if the external storage format is big-endian.
* @param[out] str the output stream for the data of type ExtT (externa l). * @param[out] str the output stream for the data of type ExtT (externa l).
* @param[in] array the input array of type IntT (internal). * @param[in] array the input array of type IntT (internal).
* @param[in] num the size of the array. * @param[in] num the size of the array.
* @exception GeographicErr if the data cannot be written.
********************************************************************** / ********************************************************************** /
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 (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(ExtT) ); str.write(reinterpret_cast<const char *>(array), num * sizeof(ExtT) );
skipping to change at line 474 skipping to change at line 483
/** /**
* 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.
* 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).
* @tparam bigendp true if the external storage format is big-endian. * @tparam bigendp true if the external storage format is big-endian.
* @param[out] str the output stream for the data of type ExtT (externa l). * @param[out] str the output stream for the data of type ExtT (externa l).
* @param[in] array the input vector of type IntT (internal). * @param[in] array the input vector of type IntT (internal).
* @exception GeographicErr if the data cannot be written.
********************************************************************** / ********************************************************************** /
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,
std::vector<IntT>& array) { std::vector<IntT>& array) {
writearray<ExtT, IntT, bigendp>(str, &array[0], array.size()); writearray<ExtT, IntT, bigendp>(str, &array[0], array.size());
} }
/** /**
* Parse a KEY VALUE line. * Parse a KEY VALUE line.
* *
* @param[in] line the input line. * @param[in] line the input line.
* @param[out] key the key. * @param[out] key the key.
* @param[out] val the value. * @param[out] val the value.
* @exception std::bad_alloc if memory for the internal strings can't b
e
* allocated.
* @return whether a key was found. * @return whether a key was found.
* *
* A # character and everything after it are discarded. If the results is * A # character and everything after it are discarded. If the results is
* just white space, the routine returns false (and \e key and \e val a re * just white space, the routine returns false (and \e key and \e val a re
* not set). Otherwise the first token is taken to be the key and the rest * not set). Otherwise the first token is taken to be the key and the rest
* of the line (trimmed of leading and trailing white space) is the val ue. * of the line (trimmed of leading and trailing white space) is the val ue.
********************************************************************** / ********************************************************************** /
static bool ParseLine(const std::string& line, static bool ParseLine(const std::string& line,
std::string& key, std::string& val); std::string& key, std::string& val);
 End of changes. 19 change blocks. 
16 lines changed or deleted 27 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/