ADD: new track message, Entity class and Position class
This commit is contained in:
1521
libs/geographiclib/examples/AuxLatitude.cpp
Normal file
1521
libs/geographiclib/examples/AuxLatitude.cpp
Normal file
File diff suppressed because it is too large
Load Diff
505
libs/geographiclib/examples/AuxLatitude.hpp
Normal file
505
libs/geographiclib/examples/AuxLatitude.hpp
Normal file
@@ -0,0 +1,505 @@
|
||||
/**
|
||||
* \file AuxLatitude.hpp
|
||||
* \brief Header for the GeographicLib::AuxLatitude and GeographicLib::AuxAngle
|
||||
* classes.
|
||||
*
|
||||
* \note This is just sample code. It is not part of GeographicLib itself.
|
||||
*
|
||||
* This file is an implementation of the methods described in
|
||||
* - C. F. F. Karney,
|
||||
* On auxiliary latitudes,
|
||||
* Technical Report, SRI International, December 2022.
|
||||
* https://arxiv.org/abs/2212.05818
|
||||
* .
|
||||
* Copyright (c) Charles Karney (2022) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* https://geographiclib.sourceforge.io/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(AUXLATITUDE_HPP)
|
||||
#define AUXLATITUDE_HPP 1
|
||||
|
||||
#include <GeographicLib/Math.hpp>
|
||||
|
||||
#if !defined(GEOGRAPHICLIB_AUXLATITUDE_ORDER)
|
||||
/**
|
||||
* The order of the series approximation used in AuxLatitude.
|
||||
* GEOGRAPHICLIB_AUXLATITUDE_ORDER can be set to one of [4, 6, 8].
|
||||
**********************************************************************/
|
||||
# define GEOGRAPHICLIB_AUXLATITUDE_ORDER 6
|
||||
#endif
|
||||
|
||||
namespace GeographicLib {
|
||||
|
||||
/**
|
||||
* \brief An accurate representation of angles.
|
||||
*
|
||||
* \note This is just sample code. It is not part of GeographicLib itself.
|
||||
*
|
||||
* This class is an implementation of the methods described in
|
||||
* - C. F. F. Karney,
|
||||
* On auxiliary latitudes,
|
||||
* Technical Report, SRI International, December 2022.
|
||||
* https://arxiv.org/abs/2212.05818
|
||||
*
|
||||
* An angle is represented be the \e y and \e x coordinates of a point in the
|
||||
* 2d plane. The two coordinates are proportional to the sine and cosine of
|
||||
* the angle. This allows angles close to the cardinal points to be
|
||||
* represented accurately. Only angles in [−180°, 180°] can be
|
||||
* represented. (A possible extension would be to keep count of the number
|
||||
* of turns.)
|
||||
*
|
||||
* @tparam T the floating-point type to use for real numbers.
|
||||
**********************************************************************/
|
||||
template<typename T = double>
|
||||
class AuxAngle {
|
||||
public:
|
||||
/**
|
||||
* The floating-point type for real numbers. This just connects to the
|
||||
* template parameters for the class.
|
||||
**********************************************************************/
|
||||
typedef T real;
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param[in] y the \e y coordinate.
|
||||
* @param[in] x the \e x coordinate.
|
||||
*
|
||||
* \note the \e y coordinate is specified \e first.
|
||||
* \warning either \e x or \e y can be infinite, but not both.
|
||||
*
|
||||
* The defaults (\e x = 1 and \e y = 0) are such that
|
||||
* + no arguments gives an angle of 0;
|
||||
* + 1 argument specifies the tangent of the angle.
|
||||
**********************************************************************/
|
||||
AuxAngle(real y = 0, real x = 1) : _y(y), _x(x) {}
|
||||
/**
|
||||
* @return the \e y component. This is the sine of the angle if the
|
||||
* AuxAngle has been normalized.
|
||||
**********************************************************************/
|
||||
real y() const { return _y; }
|
||||
/**
|
||||
* @return the \e x component. This is the cosine of the angle if the
|
||||
* AuxAngle has been normalized.
|
||||
**********************************************************************/
|
||||
real x() const { return _x; }
|
||||
/**
|
||||
* @return a reference to the \e y component. This allows this component
|
||||
* to be altered.
|
||||
**********************************************************************/
|
||||
real& y() { return _y; }
|
||||
/**
|
||||
* @return a reference to the \e x component. This allows this component
|
||||
* to be altered.
|
||||
**********************************************************************/
|
||||
real& x() { return _x; }
|
||||
/**
|
||||
* @return the AuxAngle converted to the conventional angle measured in
|
||||
* degrees.
|
||||
**********************************************************************/
|
||||
real degrees() const;
|
||||
/**
|
||||
* @return the AuxAngle converted to the conventional angle measured in
|
||||
* radians.
|
||||
**********************************************************************/
|
||||
real radians() const;
|
||||
/**
|
||||
* @return the tangent of the angle.
|
||||
**********************************************************************/
|
||||
real tan() const { return _y / _x; }
|
||||
/**
|
||||
* @return a new normalized AuxAngle with the point lying on the unit
|
||||
* circle and the \e y and \e x components are equal to the sine and
|
||||
* cosine of the angle.
|
||||
**********************************************************************/
|
||||
AuxAngle normalized() const;
|
||||
/**
|
||||
* Normalize the AuxAngle in place so that the \e y and \e x components are
|
||||
* equal to the sine and cosine of the angle.
|
||||
**********************************************************************/
|
||||
void normalize() { *this = normalized(); }
|
||||
/**
|
||||
* Set the quadrant for the AuxAngle.
|
||||
*
|
||||
* @param[in] p the AuxAngle from which the quadrant information is taken.
|
||||
* @return the new AuxAngle in the same quadrant as \e p.
|
||||
**********************************************************************/
|
||||
AuxAngle copyquadrant(const AuxAngle& p) const;
|
||||
/**
|
||||
* Add an AuxAngle.
|
||||
*
|
||||
* @param[in] p the AuxAngle to be added.
|
||||
* @return a reference to the new AuxAngle.
|
||||
*
|
||||
* The addition is done in place, altering the current AuxAngle.
|
||||
*
|
||||
* \warning Neither *this nor \e p should have an infinite component. If
|
||||
* necessary, invoke AuxAngle::normalize on these angles first.
|
||||
**********************************************************************/
|
||||
AuxAngle& operator+=(const AuxAngle& p);
|
||||
/**
|
||||
* Convert degrees to an AuxAngle.
|
||||
*
|
||||
* @param[in] d the angle measured in degrees.
|
||||
* @return the corresponding AuxAngle.
|
||||
*
|
||||
* This allows a new AuxAngle to be initialized as an angle in degrees with
|
||||
* @code
|
||||
* AuxAngle<real> phi = AuxAngle<real>::degrees(d);
|
||||
* @endcode
|
||||
* This is the so-called "named constructor" idiom.
|
||||
**********************************************************************/
|
||||
static AuxAngle degrees(real d);
|
||||
/**
|
||||
* Convert radians to an AuxAngle.
|
||||
*
|
||||
* @param[in] r the angle measured in radians.
|
||||
* @return the corresponding AuxAngle.
|
||||
*
|
||||
* This allows a new AuxAngle to be initialized as an angle in radians with
|
||||
* @code
|
||||
* AuxAngle<real> phi = AuxAngle<real>::radians(r);
|
||||
* @endcode
|
||||
* This is the so-called "named constructor" idiom.
|
||||
**********************************************************************/
|
||||
static AuxAngle radians(real r);
|
||||
/**
|
||||
* @return a "NaN" AuxAngle.
|
||||
**********************************************************************/
|
||||
static AuxAngle NaN();
|
||||
/**
|
||||
* Compute the absolute error in another angle.
|
||||
*
|
||||
* @tparam T1 the floating-point type of the other angle.
|
||||
* @param[in] p the other angle
|
||||
* @return the absolute error between p and *this considered as angles in
|
||||
* radians.
|
||||
**********************************************************************/
|
||||
template<typename T1>
|
||||
real AbsError(const AuxAngle<T1>& p) const;
|
||||
/**
|
||||
* Compute the relative error in another angle.
|
||||
*
|
||||
* @tparam T1 the floating-point type of the other angle.
|
||||
* @param[in] p the other angle
|
||||
* @return the relative error between p.tan() and this->tan().
|
||||
**********************************************************************/
|
||||
template<typename T1>
|
||||
real RelError(const AuxAngle<T1>& p) const;
|
||||
private:
|
||||
real _y, _x;
|
||||
};
|
||||
|
||||
/// \cond SKIP
|
||||
template<typename T>
|
||||
inline AuxAngle<T> AuxAngle<T>::degrees(real d) {
|
||||
real y, x;
|
||||
Math::sincosd(d, y, x);
|
||||
return AuxAngle(y, x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline AuxAngle<T> AuxAngle<T>::radians(real r) {
|
||||
using std::sin; using std::cos;
|
||||
return AuxAngle(sin(r), cos(r));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AuxAngle<T>::degrees() const {
|
||||
return Math::atan2d(_y, _x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AuxAngle<T>::radians() const {
|
||||
using std::atan2; return atan2(_y, _x);
|
||||
}
|
||||
|
||||
template<typename T> template<typename T1>
|
||||
inline T AuxAngle<T>::AbsError(const AuxAngle<T1>& p) const {
|
||||
using std::fabs;
|
||||
return fabs((AuxAngle(-T(p.y()), T(p.x())) += *this).radians());
|
||||
}
|
||||
|
||||
template<typename T> template<typename T1>
|
||||
inline T AuxAngle<T>::RelError(const AuxAngle<T1>& p) const {
|
||||
using std::fabs;
|
||||
return fabs((T(p.y()) / T(p.x()) - tan()) / tan());
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
/**
|
||||
* \brief Conversions between auxiliary latitudes.
|
||||
*
|
||||
* \note This is just sample code. It is not part of GeographicLib itself.
|
||||
*
|
||||
* This class is an implementation of the methods described in
|
||||
* - C. F. F. Karney,
|
||||
* On auxiliary latitudes,
|
||||
* Technical Report, SRI International, December 2022.
|
||||
* https://arxiv.org/abs/2212.05818
|
||||
*
|
||||
* The provides accurate conversions between geographic (\e phi, φ),
|
||||
* parametric (\e beta, β), geocentric (\e theta, θ), rectifying
|
||||
* (\e mu, μ), conformal (\e chi, χ), and authalic (\e xi, ξ)
|
||||
* latitudes for an ellipsoid of revolution. A latitude is represented by an
|
||||
* AuxAngle in order to maintain precision close to the poles.
|
||||
*
|
||||
* The class implements two methods for the conversion:
|
||||
* - Direct evaluation of the defining equations, the \e exact method. These
|
||||
* equations are formulated so as to preserve relative accuracy of the
|
||||
* tangent of the latitude, ensuring high accuracy near the equator and the
|
||||
* poles. Newton's method is used for those conversions that can't be
|
||||
* expressed in closed form.
|
||||
* - Expansions in powers of &e n, the third flattening, the \e series
|
||||
* method. This delivers full accuracy for abs(\e f) ≤ 1/150. Here, \e
|
||||
* f is the flattening of the ellipsoid.
|
||||
*
|
||||
* The series method is the preferred method of conversion for any conversion
|
||||
* involving μ, χ, or ξ, with abs(\e f) ≤ 1/150. The equations
|
||||
* for the conversions between φ, β, and θ are sufficiently
|
||||
* simple that the exact method should be used for such conversions and also
|
||||
* for conversions with with abs(\e f) > 1/150.
|
||||
*
|
||||
* @tparam T the floating-point type to use.
|
||||
*
|
||||
* Example of use:
|
||||
* \include example-AuxLatitude.cpp
|
||||
*
|
||||
* For more information on this projection, see \ref auxlat.
|
||||
**********************************************************************/
|
||||
template<typename T = double>
|
||||
class AuxLatitude {
|
||||
public:
|
||||
/**
|
||||
* The floating-point type for real numbers. This just connects to the
|
||||
* template parameters for the class.
|
||||
**********************************************************************/
|
||||
typedef T real;
|
||||
/**
|
||||
* The type used to represent angles.
|
||||
**********************************************************************/
|
||||
typedef AuxAngle<real> angle;
|
||||
/**
|
||||
* The different auxiliary latitudes.
|
||||
**********************************************************************/
|
||||
enum aux {
|
||||
/**
|
||||
* Geographic latitude, \e phi, φ
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
GEOGRAPHIC = 0,
|
||||
/**
|
||||
* Parametric latitude, \e beta, β
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
PARAMETRIC = 1,
|
||||
/**
|
||||
* %Geocentric latitude, \e theta, θ
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
GEOCENTRIC = 2,
|
||||
/**
|
||||
* Rectifying latitude, \e mu, μ
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
RECTIFYING = 3,
|
||||
/**
|
||||
* Conformal latitude, \e chi, χ
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
CONFORMAL = 4,
|
||||
/**
|
||||
* Authalic latitude, \e xi, ξ
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
AUTHALIC = 5,
|
||||
/**
|
||||
* The total number of auxiliary latitudes
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
AUXNUMBER = 6,
|
||||
/**
|
||||
* An alias for GEOGRAPHIC
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
COMMON = GEOGRAPHIC,
|
||||
/**
|
||||
* An alias for GEOGRAPHIC
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
GEODETIC = GEOGRAPHIC,
|
||||
/**
|
||||
* An alias for PARAMETRIC
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
REDUCED = PARAMETRIC,
|
||||
};
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
|
||||
* Negative \e f gives a prolate ellipsoid.
|
||||
*
|
||||
* \note the constructor does not precompute the coefficients for the
|
||||
* Fourier series for the series conversions. These are computed and saved
|
||||
* when first needed.
|
||||
**********************************************************************/
|
||||
AuxLatitude(real f);
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] a equatorial radius.
|
||||
* @param[in] b polar semi-axis.
|
||||
*
|
||||
* \note the constructor does not precompute the coefficients for the
|
||||
* Fourier series for the series conversions. These are computed and saved
|
||||
* when first needed.
|
||||
**********************************************************************/
|
||||
AuxLatitude(real a, real b);
|
||||
/**
|
||||
* Convert between any two auxiliary latitudes.
|
||||
*
|
||||
* @param[in] auxin an AuxLatitude::aux indicating the type of
|
||||
* auxiliary latitude \e zeta.
|
||||
* @param[in] auxout an AuxLatitude::aux indicating the type of
|
||||
* auxiliary latitude \e eta.
|
||||
* @param[in] zeta the input auxiliary latitude.
|
||||
* @param[in] series if true use the Taylor series instead of the exact
|
||||
* equations [default false].
|
||||
* @return the output auxiliary latitude \e eta.
|
||||
*
|
||||
* With \e series = true, the Fourier coefficients for a specific \e auxin
|
||||
* and \e auxout are computed and saved on the first call; the saved
|
||||
* coefficients are used on subsequent calls. The series method is
|
||||
* accurate for abs(\e f) ≤ 1/150; for other \e f, the exact method
|
||||
* should be used
|
||||
**********************************************************************/
|
||||
angle Convert(int auxin, int auxout, const angle& zeta,
|
||||
bool series = false) const;
|
||||
/**
|
||||
* Convert geographic latitude to an auxiliary latitude \e eta.
|
||||
*
|
||||
* @param[in] auxout an AuxLatitude::aux indicating the auxiliary
|
||||
* latitude returned.
|
||||
* @param[in] phi the geographic latitude.
|
||||
* @param[out] diff optional pointer to the derivative d tan(\e eta) / d
|
||||
* tan(\e phi).
|
||||
* @return the auxiliary latitude \e eta.
|
||||
*
|
||||
* This uses the exact equations.
|
||||
**********************************************************************/
|
||||
angle ToAuxiliary(int auxout, const angle& phi,
|
||||
real* diff = nullptr) const;
|
||||
/**
|
||||
* Convert an auxiliary latitude \e zeta to geographic latitude.
|
||||
*
|
||||
* @param[in] auxin an AuxLatitude::aux indicating the type of
|
||||
* auxiliary latitude \e zeta.
|
||||
* @param[in] zeta the input auxiliary latitude.
|
||||
* @param[out] niter optional pointer to the number of iterations.
|
||||
* @return the geographic latitude \e phi.
|
||||
*
|
||||
* This uses the exact equations.
|
||||
**********************************************************************/
|
||||
angle FromAuxiliary(int auxin, const angle& zeta,
|
||||
int* niter = nullptr) const;
|
||||
/**
|
||||
* @return \e f, the flattening of the ellipsoid.
|
||||
**********************************************************************/
|
||||
real Flattening() const { return _f; }
|
||||
/**
|
||||
* The order of the series expansions. This is set at compile time to
|
||||
* either 4, 6, or 8, by the preprocessor macro
|
||||
* GEOGRAPHICLIB_AUXLATITUDE_ORDER.
|
||||
* @hideinitializer
|
||||
**********************************************************************/
|
||||
static const int Lmax = GEOGRAPHICLIB_AUXLATITUDE_ORDER;
|
||||
private:
|
||||
/**
|
||||
* Convert geographic latitude to parametric latitude
|
||||
*
|
||||
* @param[in] phi geographic latitude.
|
||||
* @param[out] diff optional pointer to the derivative d tan(\e beta) / d
|
||||
* tan(\e phi).
|
||||
* @return \e beta, the parametric latitude
|
||||
**********************************************************************/
|
||||
angle Parametric(const angle& phi, real* diff = nullptr) const;
|
||||
/**
|
||||
* Convert geographic latitude to geocentric latitude
|
||||
*
|
||||
* @param[in] phi geographic latitude.
|
||||
* @param[out] diff optional pointer to the derivative d tan(\e theta) / d
|
||||
* tan(\e phi).
|
||||
* @return \e theta, the geocentric latitude.
|
||||
**********************************************************************/
|
||||
angle Geocentric(const angle& phi, real* diff = nullptr) const;
|
||||
/**
|
||||
* Convert geographic latitude to rectifying latitude
|
||||
*
|
||||
* @param[in] phi geographic latitude.
|
||||
* @param[out] diff optional pointer to the derivative d tan(\e mu) / d
|
||||
* tan(\e phi).
|
||||
* @return \e mu, the rectifying latitude.
|
||||
**********************************************************************/
|
||||
angle Rectifying(const angle& phi, real* diff = nullptr) const;
|
||||
/**
|
||||
* Convert geographic latitude to conformal latitude
|
||||
*
|
||||
* @param[in] phi geographic latitude.
|
||||
* @param[out] diff optional pointer to the derivative d tan(\e chi) / d
|
||||
* tan(\e phi).
|
||||
* @return \e chi, the conformal latitude.
|
||||
**********************************************************************/
|
||||
angle Conformal(const angle& phi, real* diff = nullptr) const;
|
||||
/**
|
||||
* Convert geographic latitude to authalic latitude
|
||||
*
|
||||
* @param[in] phi geographic latitude.
|
||||
* @param[out] diff optional pointer to the derivative d tan(\e xi) / d
|
||||
* tan(\e phi).
|
||||
* @return \e xi, the authalic latitude.
|
||||
**********************************************************************/
|
||||
angle Authalic(const angle& phi, real* diff = nullptr) const;
|
||||
// Maximum number of iterations for Newton's method
|
||||
static const int numit_ = 1000;
|
||||
real tol_, bmin_, bmax_; // Static consts for Newton's method
|
||||
// Ellipsoid parameters
|
||||
real _f, _fm1, _e2, _e2m1, _e12, _e12p1, _n, _e, _e1, _n2, _q;
|
||||
// To hold computed Fourier coefficients
|
||||
mutable real _c[Lmax * AUXNUMBER * AUXNUMBER];
|
||||
// 1d index into AUXNUMBER x AUXNUMBER data
|
||||
static int ind(int auxout, int auxin) {
|
||||
return (auxout >= 0 && auxout < AUXNUMBER &&
|
||||
auxin >= 0 && auxin < AUXNUMBER) ?
|
||||
AUXNUMBER * auxout + auxin : -1;
|
||||
}
|
||||
// the function sqrt(1 + tphi^2), convert tan to sec
|
||||
static real sc(real tphi)
|
||||
{ using std::hypot; return hypot(real(1), tphi); }
|
||||
// the function tphi / sqrt(1 + tphi^2), convert tan to sin
|
||||
static real sn(real tphi) {
|
||||
using std::isfinite; using std::isnan; using std::copysign;
|
||||
return isfinite(tphi) || isnan(tphi) ? tphi / sc(tphi) :
|
||||
copysign(real(1), tphi);
|
||||
}
|
||||
// The symmetric elliptic integral RD
|
||||
static real RD(real x, real y, real z);
|
||||
// The symmetric elliptic integral RF
|
||||
static real RF(real x, real y, real z);
|
||||
// the function atanh(e * sphi)/e; works for e^2 = 0 and e^2 < 0
|
||||
real atanhee(real tphi) const;
|
||||
// the function atanh(e * sphi)/e + sphi / (1 - (e * sphi)^2);
|
||||
real q(real tphi) const;
|
||||
// The divided difference of (q(1) - q(sphi)) / (1 - sphi)
|
||||
real Dq(real tphi) const;
|
||||
// Populate [_c[Lmax * k], _c[Lmax * (k + 1)])
|
||||
void fillcoeff(int auxin, int auxout, int k) const;
|
||||
// Clenshaw applied to sum(c[k] * sin( (2*k+2) * zeta), i, 0, K-1)
|
||||
// if alt, use the Reinsch optimizations
|
||||
static real Clenshaw(real szeta, real czeta, const real c[], int K,
|
||||
bool alt = true);
|
||||
};
|
||||
|
||||
} // namespace GeographicLib
|
||||
|
||||
#endif // AUXLATITUDE_HPP
|
||||
169
libs/geographiclib/examples/CMakeLists.txt
Normal file
169
libs/geographiclib/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,169 @@
|
||||
# This CMakeLists.txt is invoked in two different ways
|
||||
|
||||
# (1) With "add_subdirectory (examples)" from GeographicLib's top-level
|
||||
# CMakeLists.txt. This mode of invocation is flagged by the variable
|
||||
#
|
||||
# CALLED_FROM_TOPLEVEL
|
||||
#
|
||||
# In this case, the only action taken is to install the examples and
|
||||
# this CMakeLists.txt in ${EXAMPLEDIR}.
|
||||
|
||||
# (2) As an independent invocation of
|
||||
#
|
||||
# cmake -S <this-directory> -B <build-directory>
|
||||
#
|
||||
# In this case, find_package (GeographicLib) is called and the examples
|
||||
# are compiled. This mode of invocation is triggered by the
|
||||
# exampleprograms target in the top-level CMakeLists.txt. In this case,
|
||||
# the current version of GeographicLib is found by specifying
|
||||
#
|
||||
# -D GeographicLib_DIR=${PROJECT_BINARY_DIR}
|
||||
|
||||
cmake_minimum_required (VERSION 3.13.0)
|
||||
|
||||
set (EXAMPLES0
|
||||
example-Accumulator.cpp
|
||||
example-AlbersEqualArea.cpp
|
||||
example-AzimuthalEquidistant.cpp
|
||||
example-CassiniSoldner.cpp
|
||||
example-CircularEngine.cpp
|
||||
example-Constants.cpp
|
||||
example-DMS.cpp
|
||||
example-DST.cpp
|
||||
example-Ellipsoid.cpp
|
||||
example-EllipticFunction.cpp
|
||||
example-GARS.cpp
|
||||
example-GeoCoords.cpp
|
||||
example-Geocentric.cpp
|
||||
example-Geodesic.cpp
|
||||
example-Geodesic-small.cpp
|
||||
example-GeodesicExact.cpp
|
||||
example-GeodesicLine.cpp
|
||||
example-GeodesicLineExact.cpp
|
||||
example-GeographicErr.cpp
|
||||
example-Geohash.cpp
|
||||
example-Geoid.cpp
|
||||
example-Georef.cpp
|
||||
example-Gnomonic.cpp
|
||||
example-GravityCircle.cpp
|
||||
example-GravityModel.cpp
|
||||
example-LambertConformalConic.cpp
|
||||
example-LocalCartesian.cpp
|
||||
example-MGRS.cpp
|
||||
example-MagneticCircle.cpp
|
||||
example-MagneticModel.cpp
|
||||
example-Math.cpp
|
||||
example-NearestNeighbor.cpp
|
||||
example-NormalGravity.cpp
|
||||
example-OSGB.cpp
|
||||
example-PolarStereographic.cpp
|
||||
example-PolygonArea.cpp
|
||||
example-Rhumb.cpp
|
||||
example-RhumbLine.cpp
|
||||
example-SphericalEngine.cpp
|
||||
example-SphericalHarmonic.cpp
|
||||
example-SphericalHarmonic1.cpp
|
||||
example-SphericalHarmonic2.cpp
|
||||
example-TransverseMercator.cpp
|
||||
example-TransverseMercatorExact.cpp
|
||||
example-UTMUPS.cpp
|
||||
example-Utility.cpp
|
||||
)
|
||||
set (EXAMPLES1
|
||||
GeoidToGTX.cpp make-egmcof.cpp JacobiConformal.cpp example-AuxLatitude.cpp)
|
||||
set (EXAMPLEHEADERS JacobiConformal.hpp AuxLatitude.cpp AuxLatitude.hpp)
|
||||
|
||||
if (CALLED_FROM_TOPLEVEL)
|
||||
if (EXAMPLEDIR)
|
||||
install (FILES CMakeLists.txt ${EXAMPLES0} ${EXAMPLES1} ${EXAMPLEHEADERS}
|
||||
DESTINATION ${EXAMPLEDIR})
|
||||
endif ()
|
||||
# No more to do in add_subdirectory mode, so exit
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
project (GeographicLib-examples)
|
||||
|
||||
# Set a default build type for single-configuration cmake generators if
|
||||
# no build type is set.
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE Release)
|
||||
endif ()
|
||||
|
||||
if (MSVC OR CMAKE_CONFIGURATION_TYPES)
|
||||
# For multi-config systems and for Visual Studio, the debug version of
|
||||
# the library is called Geographic_d.
|
||||
set (CMAKE_DEBUG_POSTFIX "_d" CACHE STRING "The suffix for debug objects")
|
||||
else ()
|
||||
set (CMAKE_DEBUG_POSTFIX "" CACHE STRING "The suffix for debug objects")
|
||||
endif ()
|
||||
|
||||
find_package (GeographicLib 2.0 REQUIRED)
|
||||
include_directories (${GeographicLib_INCLUDE_DIRS})
|
||||
|
||||
option (USE_BOOST_FOR_EXAMPLES
|
||||
"Look for Boost library when compiling examples" ON)
|
||||
|
||||
if (USE_BOOST_FOR_EXAMPLES)
|
||||
# quad precision numbers appeared in Boost 1.54. Various
|
||||
# workarounds stopped being needed with Boost 1.64.
|
||||
find_package (Boost 1.64 COMPONENTS serialization)
|
||||
elseif (GEOGRAPHICLIB_PRECISION EQUAL 4)
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
find_package (Boost 1.64)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Compile a bunch of tiny example programs. These are built with the
|
||||
# "exampleprograms" target. These are mainly for including as examples
|
||||
# within the doxygen documentation; however, compiling them catches some
|
||||
# obvious blunders.
|
||||
|
||||
if (NOT GEOGRAPHICLIB_PRECISION OR GEOGRAPHICLIB_PRECISION EQUAL 2)
|
||||
# These examples all assume real = double, so check
|
||||
# GEOGRAPHICLIB_PRECISION. Allow GEOGRAPHICLIB_PRECISION to be unset
|
||||
# to accommodate lame FindGeographicLib.cmake.
|
||||
set (EXAMPLE_SOURCES ${EXAMPLES0})
|
||||
if (USE_BOOST_FOR_EXAMPLES AND Boost_FOUND)
|
||||
add_definitions (-DGEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION=1)
|
||||
include_directories ("${Boost_INCLUDE_DIRS}")
|
||||
endif ()
|
||||
else ()
|
||||
set (EXAMPLE_SOURCES)
|
||||
endif ()
|
||||
set (EXAMPLE_SOURCES ${EXAMPLE_SOURCES} ${EXAMPLES1})
|
||||
|
||||
set (EXAMPLES)
|
||||
foreach (EXAMPLE_SOURCE ${EXAMPLE_SOURCES})
|
||||
get_filename_component (EXAMPLE ${EXAMPLE_SOURCE} NAME_WE)
|
||||
set (EXAMPLES ${EXAMPLES} ${EXAMPLE})
|
||||
if (EXAMPLE STREQUAL "JacobiConformal")
|
||||
set (EXAMPLE_SOURCE ${EXAMPLE_SOURCE} JacobiConformal.hpp)
|
||||
endif ()
|
||||
if (EXAMPLE STREQUAL "example-AuxLatitude")
|
||||
set (EXAMPLE_SOURCE ${EXAMPLE_SOURCE} AuxLatitude.cpp AuxLatitude.hpp)
|
||||
endif ()
|
||||
add_executable (${EXAMPLE} ${EXAMPLE_SOURCE})
|
||||
target_link_libraries (${EXAMPLE}
|
||||
${GeographicLib_LIBRARIES} ${GeographicLib_HIGHPREC_LIBRARIES})
|
||||
endforeach ()
|
||||
if (Boost_FOUND AND GEOGRAPHICLIB_PRECISION EQUAL 2)
|
||||
target_link_libraries (example-NearestNeighbor ${Boost_LIBRARIES})
|
||||
endif ()
|
||||
|
||||
find_package (OpenMP QUIET)
|
||||
|
||||
if (OPENMP_FOUND OR OpenMP_FOUND)
|
||||
set_target_properties (GeoidToGTX PROPERTIES
|
||||
COMPILE_FLAGS ${OpenMP_CXX_FLAGS})
|
||||
if (NOT WIN32)
|
||||
set_target_properties (GeoidToGTX PROPERTIES
|
||||
LINK_FLAGS ${OpenMP_CXX_FLAGS})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (MSVC OR CMAKE_CONFIGURATION_TYPES)
|
||||
# Add _d suffix for your debug versions of the tools
|
||||
set_target_properties (${EXAMPLES} PROPERTIES
|
||||
DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
endif ()
|
||||
111
libs/geographiclib/examples/GeoidToGTX.cpp
Normal file
111
libs/geographiclib/examples/GeoidToGTX.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
// Write out a gtx file of geoid heights above the ellipsoid. For egm2008 at
|
||||
// 1' resolution this takes about 10 mins on a 8-processor Intel 3.0 GHz
|
||||
// machine using OpenMP.
|
||||
//
|
||||
// For the format of gtx files, see
|
||||
// https://vdatum.noaa.gov/docs/gtx_info.html#dev_gtx_binary
|
||||
//
|
||||
// data is binary big-endian:
|
||||
// south latitude edge (degrees double)
|
||||
// west longitude edge (degrees double)
|
||||
// delta latitude (degrees double)
|
||||
// delta longitude (degrees double)
|
||||
// nlat = number of latitude rows (integer)
|
||||
// nlong = number of longitude columns (integer)
|
||||
// nlat * nlong geoid heights (meters float)
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(_OPENMP)
|
||||
#define HAVE_OPENMP 1
|
||||
#else
|
||||
#define HAVE_OPENMP 0
|
||||
#endif
|
||||
|
||||
#if HAVE_OPENMP
|
||||
# include <omp.h>
|
||||
#endif
|
||||
|
||||
#include <GeographicLib/GravityModel.hpp>
|
||||
#include <GeographicLib/GravityCircle.hpp>
|
||||
#include <GeographicLib/Utility.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main(int argc, const char* const argv[]) {
|
||||
// Hardwired for 3 args:
|
||||
// 1 = the gravity model (e.g., egm2008)
|
||||
// 2 = intervals per degree
|
||||
// 3 = output GTX file
|
||||
if (argc != 4) {
|
||||
cerr << "Usage: " << argv[0]
|
||||
<< " gravity-model intervals-per-degree output.gtx\n";
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
// Will need to set the precision for each thread, so save return value
|
||||
int ndigits = Utility::set_digits();
|
||||
string model(argv[1]);
|
||||
// Number of intervals per degree
|
||||
int ndeg = Utility::val<int>(string(argv[2]));
|
||||
string filename(argv[3]);
|
||||
GravityModel g(model);
|
||||
int
|
||||
nlat = 180 * ndeg + 1,
|
||||
nlon = 360 * ndeg;
|
||||
Math::real
|
||||
delta = 1 / Math::real(ndeg), // Grid spacing
|
||||
latorg = -90,
|
||||
lonorg = -180;
|
||||
// Write results as floats in binary mode
|
||||
ofstream file(filename.c_str(), ios::binary);
|
||||
|
||||
// Write header
|
||||
{
|
||||
Math::real transform[] = {latorg, lonorg, delta, delta};
|
||||
unsigned sizes[] = {unsigned(nlat), unsigned(nlon)};
|
||||
Utility::writearray<double, Math::real, true>(file, transform, 4);
|
||||
Utility::writearray<unsigned, unsigned, true>(file, sizes, 2);
|
||||
}
|
||||
|
||||
// Compute and store results for nbatch latitudes at a time
|
||||
const int nbatch = 64;
|
||||
vector< vector<float> > N(nbatch, vector<float>(nlon));
|
||||
|
||||
for (int ilat0 = 0; ilat0 < nlat; ilat0 += nbatch) { // Loop over batches
|
||||
int nlat0 = min(nlat, ilat0 + nbatch);
|
||||
|
||||
#if HAVE_OPENMP
|
||||
# pragma omp parallel for
|
||||
#endif
|
||||
for (int ilat = ilat0; ilat < nlat0; ++ilat) { // Loop over latitudes
|
||||
Utility::set_digits(ndigits); // Set the precision
|
||||
Math::real
|
||||
lat = latorg + (ilat / ndeg) + delta * (ilat - ndeg * (ilat / ndeg)),
|
||||
h = 0;
|
||||
GravityCircle c(g.Circle(lat, h, GravityModel::GEOID_HEIGHT));
|
||||
for (int ilon = 0; ilon < nlon; ++ilon) { // Loop over longitudes
|
||||
Math::real lon = lonorg
|
||||
+ (ilon / ndeg) + delta * (ilon - ndeg * (ilon / ndeg));
|
||||
N[ilat - ilat0][ilon] = float(c.GeoidHeight(lon));
|
||||
} // longitude loop
|
||||
} // latitude loop -- end of parallel section
|
||||
|
||||
for (int ilat = ilat0; ilat < nlat0; ++ilat) // write out data
|
||||
Utility::writearray<float, float, true>(file, N[ilat - ilat0]);
|
||||
} // batch loop
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
catch (...) {
|
||||
cerr << "Caught unknown exception\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
43
libs/geographiclib/examples/JacobiConformal.cpp
Normal file
43
libs/geographiclib/examples/JacobiConformal.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// Example of using the GeographicLib::JacobiConformal class.
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Utility.hpp>
|
||||
#include "JacobiConformal.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Utility::set_digits();
|
||||
// These parameters were derived from the EGM2008 geoid; see 2011-07-04
|
||||
// E-mail to PROJ.4 list, "Analyzing the bumps in the EGM2008 geoid". The
|
||||
// longitude of the major axis is -15. These are close to the values given
|
||||
// by Milan Bursa, Vladimira Fialova, "Parameters of the Earth's tri-axial
|
||||
// level ellipsoid", Studia Geophysica et Geodaetica 37(1), 1-13 (1993):
|
||||
//
|
||||
// longitude of major axis = -14.93 +/- 0.05
|
||||
// a = 6378171.36 +/- 0.30
|
||||
// a/(a-c) = 297.7738 +/- 0.0003
|
||||
// a/(a-b) = 91449 +/- 60
|
||||
// which gives: a = 6378171.36, b = 6378101.61, c = 6356751.84
|
||||
Math::real a = 6378137+35, b = 6378137-35, c = 6356752;
|
||||
JacobiConformal jc(a, b, c, a-b, b-c);
|
||||
cout << fixed << setprecision(1)
|
||||
<< "Ellipsoid parameters: a = "
|
||||
<< a << ", b = " << b << ", c = " << c << "\n"
|
||||
<< setprecision(10)
|
||||
<< "Quadrants: x = " << jc.x() << ", y = " << jc.y() << "\n";
|
||||
cout << "Coordinates (angle x y) in degrees:\n";
|
||||
for (int i = 0; i <= 90; i += 5) {
|
||||
Math::real omg = i, bet = i;
|
||||
cout << i << " " << jc.x(omg) << " " << jc.y(bet) << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
176
libs/geographiclib/examples/JacobiConformal.hpp
Normal file
176
libs/geographiclib/examples/JacobiConformal.hpp
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* \file JacobiConformal.hpp
|
||||
* \brief Header for GeographicLib::JacobiConformal class
|
||||
*
|
||||
* \note This is just sample code. It is not part of GeographicLib
|
||||
* itself.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2014-2020) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* https://geographiclib.sourceforge.io/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(GEOGRAPHICLIB_JACOBICONFORMAL_HPP)
|
||||
#define GEOGRAPHICLIB_JACOBICONFORMAL_HPP 1
|
||||
|
||||
#include <GeographicLib/EllipticFunction.hpp>
|
||||
|
||||
namespace GeographicLib {
|
||||
/**
|
||||
* \brief Jacobi's conformal projection of a triaxial ellipsoid
|
||||
*
|
||||
* <b>NOTE:</b> This is just sample code. It is not part of GeographicLib
|
||||
* itself.
|
||||
*
|
||||
* This is a conformal projection of the ellipsoid to a plane in which
|
||||
* the grid lines are straight; see Jacobi,
|
||||
* <a href="https://books.google.com/books?id=ryEOAAAAQAAJ&pg=PA212">
|
||||
* Vorlesungen über Dynamik, §28</a>. The constructor takes the
|
||||
* semi-axes of the ellipsoid (which must be in order). Member functions map
|
||||
* the ellipsoidal coordinates ω and β separately to \e x and \e
|
||||
* y. Jacobi's coordinates have been multiplied by
|
||||
* (<i>a</i><sup>2</sup>−<i>c</i><sup>2</sup>)<sup>1/2</sup> /
|
||||
* (2<i>b</i>) so that the customary results are returned in the cases of
|
||||
* a sphere or an ellipsoid of revolution.
|
||||
*
|
||||
* The ellipsoid is oriented so that the large principal ellipse, \f$Z=0\f$,
|
||||
* is the equator, \f$\beta=0\f$, while the small principal ellipse,
|
||||
* \f$Y=0\f$, is the prime meridian, \f$\omega=0\f$. The four umbilic
|
||||
* points, \f$\left|\omega\right| = \left|\beta\right| = \frac12\pi\f$, lie
|
||||
* on middle principal ellipse in the plane \f$X=0\f$.
|
||||
*
|
||||
* For more information on this projection, see \ref jacobi.
|
||||
**********************************************************************/
|
||||
class JacobiConformal {
|
||||
typedef Math::real real;
|
||||
real _a, _b, _c, _ab2, _bc2, _ac2;
|
||||
EllipticFunction _ex, _ey;
|
||||
static void norm(real& x, real& y) {
|
||||
using std::hypot;
|
||||
real z = hypot(x, y); x /= z; y /= z;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* Constructor for a trixial ellipsoid with semi-axes.
|
||||
*
|
||||
* @param[in] a the largest semi-axis.
|
||||
* @param[in] b the middle semi-axis.
|
||||
* @param[in] c the smallest semi-axis.
|
||||
*
|
||||
* The semi-axes must satisfy \e a ≥ \e b ≥ \e c > 0 and \e a >
|
||||
* \e c. This form of the constructor cannot be used to specify a
|
||||
* sphere (use the next constructor).
|
||||
**********************************************************************/
|
||||
JacobiConformal(real a, real b, real c)
|
||||
: _a(a), _b(b), _c(c)
|
||||
, _ab2((_a - _b) * (_a + _b))
|
||||
, _bc2((_b - _c) * (_b + _c))
|
||||
, _ac2((_a - _c) * (_a + _c))
|
||||
, _ex(_ab2 / _ac2 * Math::sq(_c / _b), -_ab2 / Math::sq(_b),
|
||||
_bc2 / _ac2 * Math::sq(_a / _b), Math::sq(_a / _b))
|
||||
, _ey(_bc2 / _ac2 * Math::sq(_a / _b), +_bc2 / Math::sq(_b),
|
||||
_ab2 / _ac2 * Math::sq(_c / _b), Math::sq(_c / _b))
|
||||
{
|
||||
using std::isfinite;
|
||||
if (!(isfinite(_a) && _a >= _b && _b >= _c && _c > 0))
|
||||
throw GeographicErr("JacobiConformal: axes are not in order");
|
||||
if (!(_a > _c))
|
||||
throw GeographicErr
|
||||
("JacobiConformal: use alternate constructor for sphere");
|
||||
}
|
||||
/**
|
||||
* Alternate constructor for a triaxial ellipsoid.
|
||||
*
|
||||
* @param[in] a the largest semi-axis.
|
||||
* @param[in] b the middle semi-axis.
|
||||
* @param[in] c the smallest semi-axis.
|
||||
* @param[in] ab the relative magnitude of \e a − \e b.
|
||||
* @param[in] bc the relative magnitude of \e b − \e c.
|
||||
*
|
||||
* This form can be used to specify a sphere. The semi-axes must
|
||||
* satisfy \e a ≥ \e b ≥ c > 0. The ratio \e ab : \e bc must equal
|
||||
* (<i>a</i>−<i>b</i>) : (<i>b</i>−<i>c</i>) with \e ab
|
||||
* ≥ 0, \e bc ≥ 0, and \e ab + \e bc > 0.
|
||||
**********************************************************************/
|
||||
JacobiConformal(real a, real b, real c, real ab, real bc)
|
||||
: _a(a), _b(b), _c(c)
|
||||
, _ab2(ab * (_a + _b))
|
||||
, _bc2(bc * (_b + _c))
|
||||
, _ac2(_ab2 + _bc2)
|
||||
, _ex(_ab2 / _ac2 * Math::sq(_c / _b),
|
||||
-(_a - _b) * (_a + _b) / Math::sq(_b),
|
||||
_bc2 / _ac2 * Math::sq(_a / _b), Math::sq(_a / _b))
|
||||
, _ey(_bc2 / _ac2 * Math::sq(_a / _b),
|
||||
+(_b - _c) * (_b + _c) / Math::sq(_b),
|
||||
_ab2 / _ac2 * Math::sq(_c / _b), Math::sq(_c / _b))
|
||||
{
|
||||
using std::isfinite;
|
||||
if (!(isfinite(_a) && _a >= _b && _b >= _c && _c > 0 &&
|
||||
ab >= 0 && bc >= 0))
|
||||
throw GeographicErr("JacobiConformal: axes are not in order");
|
||||
if (!(ab + bc > 0 && isfinite(_ac2)))
|
||||
throw GeographicErr("JacobiConformal: ab + bc must be positive");
|
||||
}
|
||||
/**
|
||||
* @return the quadrant length in the \e x direction.
|
||||
**********************************************************************/
|
||||
Math::real x() const { return Math::sq(_a / _b) * _ex.Pi(); }
|
||||
/**
|
||||
* The \e x projection.
|
||||
*
|
||||
* @param[in] somg sin(ω).
|
||||
* @param[in] comg cos(ω).
|
||||
* @return \e x.
|
||||
**********************************************************************/
|
||||
Math::real x(real somg, real comg) const {
|
||||
real somg1 = _b * somg, comg1 = _a * comg; norm(somg1, comg1);
|
||||
return Math::sq(_a / _b)
|
||||
* _ex.Pi(somg1, comg1, _ex.Delta(somg1, comg1));
|
||||
}
|
||||
/**
|
||||
* The \e x projection.
|
||||
*
|
||||
* @param[in] omg ω (in degrees).
|
||||
* @return \e x (in degrees).
|
||||
*
|
||||
* ω must be in [−180°, 180°].
|
||||
**********************************************************************/
|
||||
Math::real x(real omg) const {
|
||||
real somg, comg;
|
||||
Math::sincosd(omg, somg, comg);
|
||||
return x(somg, comg) / Math::degree();
|
||||
}
|
||||
/**
|
||||
* @return the quadrant length in the \e y direction.
|
||||
**********************************************************************/
|
||||
Math::real y() const { return Math::sq(_c / _b) * _ey.Pi(); }
|
||||
/**
|
||||
* The \e y projection.
|
||||
*
|
||||
* @param[in] sbet sin(β).
|
||||
* @param[in] cbet cos(β).
|
||||
* @return \e y.
|
||||
**********************************************************************/
|
||||
Math::real y(real sbet, real cbet) const {
|
||||
real sbet1 = _b * sbet, cbet1 = _c * cbet; norm(sbet1, cbet1);
|
||||
return Math::sq(_c / _b)
|
||||
* _ey.Pi(sbet1, cbet1, _ey.Delta(sbet1, cbet1));
|
||||
}
|
||||
/**
|
||||
* The \e y projection.
|
||||
*
|
||||
* @param[in] bet β (in degrees).
|
||||
* @return \e y (in degrees).
|
||||
*
|
||||
* β must be in (−180°, 180°].
|
||||
**********************************************************************/
|
||||
Math::real y(real bet) const {
|
||||
real sbet, cbet;
|
||||
Math::sincosd(bet, sbet, cbet);
|
||||
return y(sbet, cbet) / Math::degree();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace GeographicLib
|
||||
|
||||
#endif // GEOGRAPHICLIB_JACOBICONFORMAL_HPP
|
||||
57
libs/geographiclib/examples/Makefile.am
Normal file
57
libs/geographiclib/examples/Makefile.am
Normal file
@@ -0,0 +1,57 @@
|
||||
#
|
||||
# Makefile.am
|
||||
#
|
||||
# Copyright (C) 2011, Charles Karney <charles@karney.com>
|
||||
|
||||
EXAMPLE_FILES = \
|
||||
example-Accumulator.cpp \
|
||||
example-AlbersEqualArea.cpp \
|
||||
example-AzimuthalEquidistant.cpp \
|
||||
example-CassiniSoldner.cpp \
|
||||
example-CircularEngine.cpp \
|
||||
example-Constants.cpp \
|
||||
example-DMS.cpp \
|
||||
example-DST.cpp \
|
||||
example-Ellipsoid.cpp \
|
||||
example-EllipticFunction.cpp \
|
||||
example-GARS.cpp \
|
||||
example-GeoCoords.cpp \
|
||||
example-Geocentric.cpp \
|
||||
example-Geodesic.cpp \
|
||||
example-Geodesic-small.cpp \
|
||||
example-GeodesicExact.cpp \
|
||||
example-GeodesicLine.cpp \
|
||||
example-GeodesicLineExact.cpp \
|
||||
example-GeographicErr.cpp \
|
||||
example-Geohash.cpp \
|
||||
example-Geoid.cpp \
|
||||
example-Georef.cpp \
|
||||
example-Gnomonic.cpp \
|
||||
example-GravityCircle.cpp \
|
||||
example-GravityModel.cpp \
|
||||
example-LambertConformalConic.cpp \
|
||||
example-LocalCartesian.cpp \
|
||||
example-MGRS.cpp \
|
||||
example-MagneticCircle.cpp \
|
||||
example-MagneticModel.cpp \
|
||||
example-Math.cpp \
|
||||
example-NearestNeighbor.cpp \
|
||||
example-NormalGravity.cpp \
|
||||
example-OSGB.cpp \
|
||||
example-PolarStereographic.cpp \
|
||||
example-PolygonArea.cpp \
|
||||
example-Rhumb.cpp \
|
||||
example-RhumbLine.cpp \
|
||||
example-SphericalEngine.cpp \
|
||||
example-SphericalHarmonic.cpp \
|
||||
example-SphericalHarmonic1.cpp \
|
||||
example-SphericalHarmonic2.cpp \
|
||||
example-TransverseMercator.cpp \
|
||||
example-TransverseMercatorExact.cpp \
|
||||
example-UTMUPS.cpp \
|
||||
example-Utility.cpp \
|
||||
GeoidToGTX.cpp \
|
||||
JacobiConformal.cpp JacobiConformal.hpp \
|
||||
make-egmcof.cpp
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt $(EXAMPLE_FILES)
|
||||
24
libs/geographiclib/examples/example-Accumulator.cpp
Normal file
24
libs/geographiclib/examples/example-Accumulator.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
// Example of using the GeographicLib::Accumulator class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Accumulator.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Compare using Accumulator and ordinary summation for a sum of large and
|
||||
// small terms.
|
||||
double sum = 0;
|
||||
Accumulator<> acc = 0;
|
||||
sum += 1e20; sum += 1; sum += 2; sum += 100; sum += 5000; sum += -1e20;
|
||||
acc += 1e20; acc += 1; acc += 2; acc += 100; acc += 5000; acc += -1e20;
|
||||
cout << sum << " " << acc() << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
39
libs/geographiclib/examples/example-AlbersEqualArea.cpp
Normal file
39
libs/geographiclib/examples/example-AlbersEqualArea.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// Example of using the GeographicLib::AlbersEqualArea class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/AlbersEqualArea.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
const double
|
||||
a = Constants::WGS84_a(),
|
||||
f = Constants::WGS84_f(),
|
||||
lat1 = 40 + 58/60.0, lat2 = 39 + 56/60.0, // standard parallels
|
||||
k1 = 1, // scale
|
||||
lon0 = -77 - 45/60.0; // Central meridian
|
||||
// Set up basic projection
|
||||
const AlbersEqualArea albers(a, f, lat1, lat2, k1);
|
||||
{
|
||||
// Sample conversion from geodetic to Albers Equal Area
|
||||
double lat = 39.95, lon = -75.17; // Philadelphia
|
||||
double x, y;
|
||||
albers.Forward(lon0, lat, lon, x, y);
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample conversion from Albers Equal Area grid to geodetic
|
||||
double x = 220e3, y = -53e3;
|
||||
double lat, lon;
|
||||
albers.Reverse(lon0, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
37
libs/geographiclib/examples/example-AuxLatitude.cpp
Normal file
37
libs/geographiclib/examples/example-AuxLatitude.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Example of using the GeographicLib::AuxLatitude class. See the paper
|
||||
//
|
||||
// - C. F. F. Karney,
|
||||
// On auxiliary latitudes,
|
||||
// Technical Report, SRI International, December 2022.
|
||||
// https://arxiv.org/abs/2212.05818
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include "AuxLatitude.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
typedef GeographicLib::AuxLatitude<double> latitude;
|
||||
typedef latitude::angle angle;
|
||||
double a = 2, b = 1; // Equatorial radius and polar semi-axis
|
||||
latitude aux(a, b);
|
||||
bool series = false; // Don't use series method
|
||||
int auxin = latitude::GEOGRAPHIC;
|
||||
cout << setprecision(9) << fixed;
|
||||
for (int l = 0; l <= 90; ++l) {
|
||||
angle phi(angle::degrees(l));
|
||||
for (int auxout = 0; auxout < latitude::AUXNUMBER; ++auxout) {
|
||||
angle eta = aux.Convert(auxin, auxout, phi, series);
|
||||
cout << (auxout ? " " : "") << eta.degrees();
|
||||
}
|
||||
cout << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
36
libs/geographiclib/examples/example-AzimuthalEquidistant.cpp
Normal file
36
libs/geographiclib/examples/example-AzimuthalEquidistant.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::AzimuthalEquidistant class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/AzimuthalEquidistant.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
|
||||
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
|
||||
AzimuthalEquidistant proj(geod);
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 50.9, lon = 1.8; // Calais
|
||||
double x, y;
|
||||
proj.Forward(lat0, lon0, lat, lon, x, y);
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = -38e3, y = 230e3;
|
||||
double lat, lon;
|
||||
proj.Reverse(lat0, lon0, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
36
libs/geographiclib/examples/example-CassiniSoldner.cpp
Normal file
36
libs/geographiclib/examples/example-CassiniSoldner.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::CassiniSoldner class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/CassiniSoldner.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
|
||||
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
|
||||
CassiniSoldner proj(lat0, lon0, geod);
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 50.9, lon = 1.8; // Calais
|
||||
double x, y;
|
||||
proj.Forward(lat, lon, x, y);
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = -38e3, y = 230e3;
|
||||
double lat, lon;
|
||||
proj.Reverse(x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
35
libs/geographiclib/examples/example-CircularEngine.cpp
Normal file
35
libs/geographiclib/examples/example-CircularEngine.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Example of using the GeographicLib::CircularEngine class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <GeographicLib/CircularEngine.hpp>
|
||||
#include <GeographicLib/SphericalHarmonic.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
// This computes the same value as example-SphericalHarmonic.cpp using a
|
||||
// CircularEngine (which will be faster if many values on a circle of
|
||||
// latitude are to be found).
|
||||
try {
|
||||
using std::hypot;
|
||||
int N = 3; // The maxium degree
|
||||
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
|
||||
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
|
||||
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
|
||||
vector<double> S(sa, sa + N * (N + 1) / 2);
|
||||
double a = 1;
|
||||
SphericalHarmonic h(C, S, N, a);
|
||||
double x = 2, y = 3, z = 1, p = hypot(x, y);
|
||||
CircularEngine circ = h.Circle(p, z, true);
|
||||
double v, vx, vy, vz;
|
||||
v = circ(x/p, y/p, vx, vy, vz);
|
||||
cout << v << " " << vx << " " << vy << " " << vz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
20
libs/geographiclib/examples/example-Constants.cpp
Normal file
20
libs/geographiclib/examples/example-Constants.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Example of using the GeographicLib::Constants class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
cout << "WGS84 parameters:\n"
|
||||
<< "a = " << Constants::WGS84_a() << " m\n"
|
||||
<< "f = 1/" << 1/Constants::WGS84_f() << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
29
libs/geographiclib/examples/example-DMS.cpp
Normal file
29
libs/geographiclib/examples/example-DMS.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// Example of using the GeographicLib::DMS class
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <GeographicLib/DMS.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
{
|
||||
string dms = "30d14'45.6\"S";
|
||||
DMS::flag type;
|
||||
double ang = DMS::Decode(dms, type);
|
||||
cout << type << " " << ang << "\n";
|
||||
}
|
||||
{
|
||||
double ang = -30.245715;
|
||||
string dms = DMS::Encode(ang, 6, DMS::LATITUDE);
|
||||
cout << dms << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
62
libs/geographiclib/examples/example-DST.cpp
Normal file
62
libs/geographiclib/examples/example-DST.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// Example of using the GeographicLib::DST class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <GeographicLib/Math.hpp>
|
||||
#include <GeographicLib/DST.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
class sawtooth {
|
||||
private:
|
||||
double _a;
|
||||
public:
|
||||
sawtooth(double a) : _a(a) {}
|
||||
// only called for x in (0, pi/2]. DST assumes function is periodic, period
|
||||
// 2*pi, is odd about 0, and is even about pi/2.
|
||||
double operator()(double x) const { return _a * x; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
try {
|
||||
sawtooth f(Math::pi()/4);
|
||||
DST dst;
|
||||
int N = 5, K = 2*N;
|
||||
vector<double> tx(N), txa(2*N);
|
||||
dst.reset(N);
|
||||
dst.transform(f, tx.data());
|
||||
cout << "Transform of sawtooth based on " << N << " points\n"
|
||||
<< "approx 1, -1/9, 1/25, -1/49, ...\n";
|
||||
for (int i = 0; i < min(K,N); ++i) {
|
||||
int j = (2*i+1)*(2*i+1)*(1-((i&1)<<1));
|
||||
cout << i << " " << tx[i] << " " << tx[i]*j << "\n";
|
||||
}
|
||||
tx.resize(2*N);
|
||||
dst.refine(f, tx.data());
|
||||
cout << "Add another " << N << " points\n";
|
||||
for (int i = 0; i < min(K,2*N); ++i) {
|
||||
int j = (2*i+1)*(2*i+1)*(1-((i&1)<<1));
|
||||
cout << i << " " << tx[i] << " " << tx[i]*j << "\n";
|
||||
}
|
||||
dst.reset(2*N);
|
||||
dst.transform(f, txa.data());
|
||||
cout << "Retransform of sawtooth based on " << 2*N << " points\n";
|
||||
for (int i = 0; i < min(K,2*N); ++i) {
|
||||
int j = (2*i+1)*(2*i+1)*(1-((i&1)<<1));
|
||||
cout << i << " " << txa[i] << " " << txa[i]*j << "\n";
|
||||
}
|
||||
cout << "Table of values and integral\n";
|
||||
for (int i = 0; i <= K; ++i) {
|
||||
double x = i*Math::pi()/(2*K), sinx = sin(x), cosx = cos(x);
|
||||
cout << x << " " << f(x) << " "
|
||||
<< DST::eval(sinx, cosx, txa.data(), 2*N) << " "
|
||||
<< DST::integral(sinx, cosx, txa.data(), 2*N) << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
42
libs/geographiclib/examples/example-Ellipsoid.cpp
Normal file
42
libs/geographiclib/examples/example-Ellipsoid.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Example of using the GeographicLib::Ellipsoid class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Ellipsoid.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Ellipsoid wgs84(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Ellipsoid& wgs84 = Ellipsoid::WGS84();
|
||||
cout << "The latitude half way between the equator and the pole is "
|
||||
<< wgs84.InverseRectifyingLatitude(45) << "\n";
|
||||
cout << "Half the area of the ellipsoid lies between latitudes +/- "
|
||||
<< wgs84.InverseAuthalicLatitude(30) << "\n";
|
||||
cout << "The northernmost edge of a square Mercator map is at latitude "
|
||||
<< wgs84.InverseIsometricLatitude(180) << "\n";
|
||||
cout << "Table phi(deg) beta-phi xi-phi mu-phi chi-phi theta-phi (mins)\n"
|
||||
<< fixed << setprecision(2);
|
||||
for (int i = 0; i <= 90; i += 15) {
|
||||
double phi = i,
|
||||
bet = wgs84.ParametricLatitude(phi),
|
||||
xi = wgs84.AuthalicLatitude(phi),
|
||||
mu = wgs84.RectifyingLatitude(phi),
|
||||
chi = wgs84.ConformalLatitude(phi),
|
||||
theta = wgs84.GeocentricLatitude(phi);
|
||||
cout << i << " "
|
||||
<< (bet-phi)*60 << " "
|
||||
<< (xi-phi)*60 << " "
|
||||
<< (mu-phi)*60 << " "
|
||||
<< (chi-phi)*60 << " "
|
||||
<< (theta-phi)*60 << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
43
libs/geographiclib/examples/example-EllipticFunction.cpp
Normal file
43
libs/geographiclib/examples/example-EllipticFunction.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// Example of using the GeographicLib::EllipticFunction class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <cmath>
|
||||
#include <GeographicLib/Math.hpp>
|
||||
#include <GeographicLib/EllipticFunction.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
EllipticFunction ell(0.1); // parameter m = 0.1
|
||||
// See Abramowitz and Stegun, table 17.1
|
||||
cout << ell.K() << " " << ell.E() << "\n";
|
||||
double phi = 20, sn, cn;
|
||||
Math::sincosd(phi, sn ,cn);
|
||||
// See Abramowitz and Stegun, table 17.6 with
|
||||
// alpha = asin(sqrt(m)) = 18.43 deg and phi = 20 deg
|
||||
cout << ell.E(phi * Math::degree()) << " "
|
||||
<< ell.E(sn, cn, ell.Delta(sn, cn))
|
||||
<< "\n";
|
||||
// See Carlson 1995, Sec 3.
|
||||
cout << fixed << setprecision(16)
|
||||
<< "RF(1,2,0) = " << EllipticFunction::RF(1,2) << "\n"
|
||||
<< "RF(2,3,4) = " << EllipticFunction::RF(2,3,4) << "\n"
|
||||
<< "RC(0,1/4) = " << EllipticFunction::RC(0,0.25) << "\n"
|
||||
<< "RC(9/4,2) = " << EllipticFunction::RC(2.25,2) << "\n"
|
||||
<< "RC(1/4,-2) = " << EllipticFunction::RC(0.25,-2) << "\n"
|
||||
<< "RJ(0,1,2,3) = " << EllipticFunction::RJ(0,1,2,3) << "\n"
|
||||
<< "RJ(2,3,4,5) = " << EllipticFunction::RJ(2,3,4,5) << "\n"
|
||||
<< "RD(0,2,1) = " << EllipticFunction::RD(0,2,1) << "\n"
|
||||
<< "RD(2,3,4) = " << EllipticFunction::RD(2,3,4) << "\n"
|
||||
<< "RG(0,16,16) = " << EllipticFunction::RG(16,16) << "\n"
|
||||
<< "RG(2,3,4) = " << EllipticFunction::RG(2,3,4) << "\n"
|
||||
<< "RG(0,0.0796,4) = " << EllipticFunction::RG(0.0796,4) << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cout << "Caught exception: " << e.what() << "\n";
|
||||
}
|
||||
}
|
||||
39
libs/geographiclib/examples/example-GARS.cpp
Normal file
39
libs/geographiclib/examples/example-GARS.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
// Example of using the GeographicLib::GARS class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <GeographicLib/GARS.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 57.64911, lon = 10.40744; // Jutland
|
||||
string gars;
|
||||
for (int prec = 0; prec <= 2; ++prec) {
|
||||
GARS::Forward(lat, lon, prec, gars);
|
||||
cout << prec << " " << gars << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
string gars = "381NH45";
|
||||
double lat, lon;
|
||||
cout << fixed;
|
||||
for (int len = 5; len <= int(gars.size()); ++len) {
|
||||
int prec;
|
||||
GARS::Reverse(gars.substr(0, len), lat, lon, prec);
|
||||
cout << prec << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
26
libs/geographiclib/examples/example-GeoCoords.cpp
Normal file
26
libs/geographiclib/examples/example-GeoCoords.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// Example of using the GeographicLib::GeoCoords class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/GeoCoords.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Miscellaneous conversions
|
||||
double lat = 33.3, lon = 44.4;
|
||||
GeoCoords c(lat, lon);
|
||||
cout << c.MGRSRepresentation(-3) << "\n";
|
||||
c.Reset("18TWN0050");
|
||||
cout << c.DMSRepresentation() << "\n";
|
||||
cout << c.Latitude() << " " << c.Longitude() << "\n";
|
||||
c.Reset("1d38'W 55d30'N");
|
||||
cout << c.GeoRepresentation() << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
36
libs/geographiclib/examples/example-Geocentric.cpp
Normal file
36
libs/geographiclib/examples/example-Geocentric.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::Geocentric class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <cmath>
|
||||
#include <GeographicLib/Geocentric.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geocentric earth(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geocentric& earth = Geocentric::WGS84();
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 27.99, lon = 86.93, h = 8820; // Mt Everest
|
||||
double X, Y, Z;
|
||||
earth.Forward(lat, lon, h, X, Y, Z);
|
||||
cout << floor(X / 1000 + 0.5) << " "
|
||||
<< floor(Y / 1000 + 0.5) << " "
|
||||
<< floor(Z / 1000 + 0.5) << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double X = 302e3, Y = 5636e3, Z = 2980e3;
|
||||
double lat, lon, h;
|
||||
earth.Reverse(X, Y, Z, lat, lon, h);
|
||||
cout << lat << " " << lon << " " << h << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
18
libs/geographiclib/examples/example-Geodesic-small.cpp
Normal file
18
libs/geographiclib/examples/example-Geodesic-small.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
// Small example of using the GeographicLib::Geodesic class
|
||||
|
||||
#include <iostream>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
const Geodesic& geod = Geodesic::WGS84();
|
||||
// Distance from JFK to LHR
|
||||
double
|
||||
lat1 = 40.6, lon1 = -73.8, // JFK Airport
|
||||
lat2 = 51.6, lon2 = -0.5; // LHR Airport
|
||||
double s12;
|
||||
geod.Inverse(lat1, lon1, lat2, lon2, s12);
|
||||
cout << s12 / 1000 << " km\n";
|
||||
}
|
||||
36
libs/geographiclib/examples/example-Geodesic.cpp
Normal file
36
libs/geographiclib/examples/example-Geodesic.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::Geodesic class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
|
||||
{
|
||||
// Sample direct calculation, travelling about NE from JFK
|
||||
double lat1 = 40.6, lon1 = -73.8, s12 = 5.5e6, azi1 = 51;
|
||||
double lat2, lon2;
|
||||
geod.Direct(lat1, lon1, azi1, s12, lat2, lon2);
|
||||
cout << lat2 << " " << lon2 << "\n";
|
||||
}
|
||||
{
|
||||
// Sample inverse calculation, JFK to LHR
|
||||
double
|
||||
lat1 = 40.6, lon1 = -73.8, // JFK Airport
|
||||
lat2 = 51.6, lon2 = -0.5; // LHR Airport
|
||||
double s12;
|
||||
geod.Inverse(lat1, lon1, lat2, lon2, s12);
|
||||
cout << s12 << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
36
libs/geographiclib/examples/example-GeodesicExact.cpp
Normal file
36
libs/geographiclib/examples/example-GeodesicExact.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::GeodesicExact class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/GeodesicExact.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
GeodesicExact geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const GeodesicExact& geod = GeodesicExact::WGS84();
|
||||
{
|
||||
// Sample direct calculation, travelling about NE from JFK
|
||||
double lat1 = 40.6, lon1 = -73.8, s12 = 5.5e6, azi1 = 51;
|
||||
double lat2, lon2;
|
||||
geod.Direct(lat1, lon1, azi1, s12, lat2, lon2);
|
||||
cout << lat2 << " " << lon2 << "\n";
|
||||
}
|
||||
{
|
||||
// Sample inverse calculation, JFK to LHR
|
||||
double
|
||||
lat1 = 40.6, lon1 = -73.8, // JFK Airport
|
||||
lat2 = 51.6, lon2 = -0.5; // LHR Airport
|
||||
double s12;
|
||||
geod.Inverse(lat1, lon1, lat2, lon2, s12);
|
||||
cout << s12 << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
49
libs/geographiclib/examples/example-GeodesicLine.cpp
Normal file
49
libs/geographiclib/examples/example-GeodesicLine.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Example of using the GeographicLib::GeodesicLine class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <cmath>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/GeodesicLine.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Print waypoints between JFK and SIN
|
||||
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
|
||||
double
|
||||
lat1 = 40.640, lon1 = -73.779, // JFK
|
||||
lat2 = 1.359, lon2 = 103.989; // SIN
|
||||
GeodesicLine line = geod.InverseLine(lat1, lon1, lat2, lon2);
|
||||
double ds0 = 500e3; // Nominal distance between points = 500 km
|
||||
int num = int(ceil(line.Distance() / ds0)); // The number of intervals
|
||||
cout << fixed << setprecision(3);
|
||||
{
|
||||
// Use intervals of equal length
|
||||
double ds = line.Distance() / num;
|
||||
for (int i = 0; i <= num; ++i) {
|
||||
double lat, lon;
|
||||
line.Position(i * ds, lat, lon);
|
||||
cout << i << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Slightly faster, use intervals of equal arc length
|
||||
double da = line.Arc() / num;
|
||||
for (int i = 0; i <= num; ++i) {
|
||||
double lat, lon;
|
||||
line.ArcPosition(i * da, lat, lon);
|
||||
cout << i << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
49
libs/geographiclib/examples/example-GeodesicLineExact.cpp
Normal file
49
libs/geographiclib/examples/example-GeodesicLineExact.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Example of using the GeographicLib::GeodesicLineExact class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <cmath>
|
||||
#include <GeographicLib/GeodesicExact.hpp>
|
||||
#include <GeographicLib/GeodesicLineExact.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Print waypoints between JFK and SIN
|
||||
GeodesicExact geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const GeodesicExact& geod = GeodesicExact::WGS84();
|
||||
double
|
||||
lat1 = 40.640, lon1 = -73.779, // JFK
|
||||
lat2 = 1.359, lon2 = 103.989; // SIN
|
||||
GeodesicLineExact line = geod.InverseLine(lat1, lon1, lat2, lon2);
|
||||
double ds0 = 500e3; // Nominal distance between points = 500 km
|
||||
int num = int(ceil(line.Distance() / ds0)); // The number of intervals
|
||||
cout << fixed << setprecision(3);
|
||||
{
|
||||
// Use intervals of equal length
|
||||
double ds = line.Distance() / num;
|
||||
for (int i = 0; i <= num; ++i) {
|
||||
double lat, lon;
|
||||
line.Position(i * ds, lat, lon);
|
||||
cout << i << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Slightly faster, use intervals of equal arc length
|
||||
double da = line.Arc() / num;
|
||||
for (int i = 0; i <= num; ++i) {
|
||||
double lat, lon;
|
||||
line.ArcPosition(i * da, lat, lon);
|
||||
cout << i << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
16
libs/geographiclib/examples/example-GeographicErr.cpp
Normal file
16
libs/geographiclib/examples/example-GeographicErr.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Example of using the GeographicLib::GeographicErr class
|
||||
|
||||
#include <iostream>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
throw GeographicErr("Test throwing an exception");
|
||||
}
|
||||
catch (const GeographicErr& e) {
|
||||
cout << "Caught exception: " << e.what() << "\n";
|
||||
}
|
||||
}
|
||||
45
libs/geographiclib/examples/example-Geohash.cpp
Normal file
45
libs/geographiclib/examples/example-Geohash.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Example of using the GeographicLib::Geohash class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <GeographicLib/Geohash.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 57.64911, lon = 10.40744; // Jutland (the wikipedia example)
|
||||
string geohash;
|
||||
int maxlen = Geohash::GeohashLength(1.0e-5);
|
||||
for (int len = 0; len <= maxlen; ++len) {
|
||||
Geohash::Forward(lat, lon, len, geohash);
|
||||
cout << len << " " << geohash << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
string geohash = "u4pruydqqvj";
|
||||
double lat, lon, latres, lonres;
|
||||
cout << fixed;
|
||||
for (unsigned i = 0; i <= geohash.length(); ++i) {
|
||||
int len;
|
||||
Geohash::Reverse(geohash.substr(0, i), lat, lon, len);
|
||||
latres = Geohash::LatitudeResolution(len);
|
||||
lonres = Geohash::LongitudeResolution(len);
|
||||
cout << setprecision(max(0, Geohash::DecimalPrecision(len)))
|
||||
<< len << " "
|
||||
<< lat << "+/-" << latres/2 << " "
|
||||
<< lon << "+/-" << lonres/2 << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
27
libs/geographiclib/examples/example-Geoid.cpp
Normal file
27
libs/geographiclib/examples/example-Geoid.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// Example of using the GeographicLib::Geoid class
|
||||
// This requires that the egm96-5 geoid model be installed; see
|
||||
// https://geographiclib.sourceforge.io/C++/doc/geoid.html#geoidinst
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Geoid.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geoid egm96("egm96-5");
|
||||
// Convert height above egm96 to height above the ellipsoid
|
||||
double lat = 42, lon = -75, height_above_geoid = 20;
|
||||
double
|
||||
geoid_height = egm96(lat, lon),
|
||||
height_above_ellipsoid = (height_above_geoid +
|
||||
Geoid::GEOIDTOELLIPSOID * geoid_height);
|
||||
cout << height_above_ellipsoid << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
41
libs/geographiclib/examples/example-Georef.cpp
Normal file
41
libs/geographiclib/examples/example-Georef.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// Example of using the GeographicLib::GARS class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <GeographicLib/Georef.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 57.64911, lon = 10.40744; // Jutland
|
||||
string georef;
|
||||
for (int prec = -1; prec <= 11; ++prec) {
|
||||
Georef::Forward(lat, lon, prec, georef);
|
||||
cout << prec << " " << georef << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
string georef = "NKLN2444638946";
|
||||
double lat, lon;
|
||||
int prec;
|
||||
cout << fixed;
|
||||
Georef::Reverse(georef.substr(0, 2), lat, lon, prec);
|
||||
cout << prec << " " << lat << " " << lon << "\n";
|
||||
Georef::Reverse(georef.substr(0, 4), lat, lon, prec);
|
||||
cout << prec << " " << lat << " " << lon << "\n";
|
||||
Georef::Reverse(georef, lat, lon, prec);
|
||||
cout << prec << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
36
libs/geographiclib/examples/example-Gnomonic.cpp
Normal file
36
libs/geographiclib/examples/example-Gnomonic.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::Gnomonic class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/Gnomonic.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
|
||||
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
|
||||
Gnomonic proj(geod);
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 50.9, lon = 1.8; // Calais
|
||||
double x, y;
|
||||
proj.Forward(lat0, lon0, lat, lon, x, y);
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = -38e3, y = 230e3;
|
||||
double lat, lon;
|
||||
proj.Reverse(lat0, lon0, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
43
libs/geographiclib/examples/example-GravityCircle.cpp
Normal file
43
libs/geographiclib/examples/example-GravityCircle.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// Example of using the GeographicLib::GravityCircle class
|
||||
// This requires that the egm96 gravity model be installed; see
|
||||
// https://geographiclib.sourceforge.io/C++/doc/gravity.html#gravityinst
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/GravityModel.hpp>
|
||||
#include <GeographicLib/GravityCircle.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
GravityModel grav("egm96");
|
||||
double lat = 27.99, lon0 = 86.93, h = 8820; // Mt Everest
|
||||
{
|
||||
// Slow method of evaluating the values at several points on a circle of
|
||||
// latitude.
|
||||
for (int i = -5; i <= 5; ++i) {
|
||||
double lon = lon0 + i * 0.2;
|
||||
double gx, gy, gz;
|
||||
grav.Gravity(lat, lon, h, gx, gy, gz);
|
||||
cout << lon << " " << gx << " " << gy << " " << gz << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Fast method of evaluating the values at several points on a circle of
|
||||
// latitude using GravityCircle.
|
||||
GravityCircle circ = grav.Circle(lat, h);
|
||||
for (int i = -5; i <= 5; ++i) {
|
||||
double lon = lon0 + i * 0.2;
|
||||
double gx, gy, gz;
|
||||
circ.Gravity(lon, gx, gy, gz);
|
||||
cout << lon << " " << gx << " " << gy << " " << gz << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
24
libs/geographiclib/examples/example-GravityModel.cpp
Normal file
24
libs/geographiclib/examples/example-GravityModel.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
// Example of using the GeographicLib::GravityModel class
|
||||
// This requires that the egm96 gravity model be installed; see
|
||||
// https://geographiclib.sourceforge.io/C++/doc/gravity.html#gravityinst
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/GravityModel.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
GravityModel grav("egm96");
|
||||
double lat = 27.99, lon = 86.93, h = 8820; // Mt Everest
|
||||
double gx, gy, gz;
|
||||
grav.Gravity(lat,lon, h, gx, gy, gz);
|
||||
cout << gx << " " << gy << " " << gz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Example of using the GeographicLib::LambertConformalConic class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/LambertConformalConic.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Define the Pennsylvania South state coordinate system EPSG:3364
|
||||
// https://www.spatialreference.org/ref/epsg/3364/
|
||||
const double
|
||||
a = Constants::WGS84_a(),
|
||||
f = 1/298.257222101, // GRS80
|
||||
lat1 = 40 + 58/60.0, lat2 = 39 + 56/60.0, // standard parallels
|
||||
k1 = 1, // scale
|
||||
lat0 = 39 + 20/60.0, lon0 =-77 - 45/60.0, // origin
|
||||
fe = 600000, fn = 0; // false easting and northing
|
||||
// Set up basic projection
|
||||
const LambertConformalConic PASouth(a, f, lat1, lat2, k1);
|
||||
double x0, y0;
|
||||
// Transform origin point
|
||||
PASouth.Forward(lon0, lat0, lon0, x0, y0);
|
||||
x0 -= fe; y0 -= fn;
|
||||
{
|
||||
// Sample conversion from geodetic to PASouth grid
|
||||
double lat = 39.95, lon = -75.17; // Philadelphia
|
||||
double x, y;
|
||||
PASouth.Forward(lon0, lat, lon, x, y);
|
||||
x -= x0; y -= y0;
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample conversion from PASouth grid to geodetic
|
||||
double x = 820e3, y = 72e3;
|
||||
double lat, lon;
|
||||
x += x0; y += y0;
|
||||
PASouth.Reverse(lon0, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
37
libs/geographiclib/examples/example-LocalCartesian.cpp
Normal file
37
libs/geographiclib/examples/example-LocalCartesian.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Example of using the GeographicLib::LocalCartesian class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <cmath>
|
||||
#include <GeographicLib/Geocentric.hpp>
|
||||
#include <GeographicLib/LocalCartesian.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geocentric earth(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geocentric& earth = Geocentric::WGS84();
|
||||
const double lat0 = 48 + 50/60.0, lon0 = 2 + 20/60.0; // Paris
|
||||
LocalCartesian proj(lat0, lon0, 0, earth);
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 50.9, lon = 1.8, h = 0; // Calais
|
||||
double x, y, z;
|
||||
proj.Forward(lat, lon, h, x, y, z);
|
||||
cout << x << " " << y << " " << z << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = -38e3, y = 230e3, z = -4e3;
|
||||
double lat, lon, h;
|
||||
proj.Reverse(x, y, z, lat, lon, h);
|
||||
cout << lat << " " << lon << " " << h << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
42
libs/geographiclib/examples/example-MGRS.cpp
Normal file
42
libs/geographiclib/examples/example-MGRS.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Example of using the GeographicLib::MGRS class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <GeographicLib/UTMUPS.hpp>
|
||||
#include <GeographicLib/MGRS.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// See also example-GeoCoords.cpp
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 33.3, lon = 44.4; // Baghdad
|
||||
int zone;
|
||||
bool northp;
|
||||
double x, y;
|
||||
UTMUPS::Forward(lat, lon, zone, northp, x, y);
|
||||
string mgrs;
|
||||
MGRS::Forward(zone, northp, x, y, lat, 5, mgrs);
|
||||
cout << mgrs << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
string mgrs = "38SMB4488";
|
||||
int zone, prec;
|
||||
bool northp;
|
||||
double x, y;
|
||||
MGRS::Reverse(mgrs, zone, northp, x, y, prec);
|
||||
double lat, lon;
|
||||
UTMUPS::Reverse(zone, northp, x, y, lat, lon);
|
||||
cout << prec << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
43
libs/geographiclib/examples/example-MagneticCircle.cpp
Normal file
43
libs/geographiclib/examples/example-MagneticCircle.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// Example of using the GeographicLib::MagneticCircle class
|
||||
// This requires that the wmm2010 magnetic model be installed; see
|
||||
// https://geographiclib.sourceforge.io/C++/doc/magnetic.html#magneticinst
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/MagneticModel.hpp>
|
||||
#include <GeographicLib/MagneticCircle.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
MagneticModel mag("wmm2010");
|
||||
double lat = 27.99, lon0 = 86.93, h = 8820, t = 2012; // Mt Everest
|
||||
{
|
||||
// Slow method of evaluating the values at several points on a circle of
|
||||
// latitude.
|
||||
for (int i = -5; i <= 5; ++i) {
|
||||
double lon = lon0 + i * 0.2;
|
||||
double Bx, By, Bz;
|
||||
mag(t, lat, lon, h, Bx, By, Bz);
|
||||
cout << lon << " " << Bx << " " << By << " " << Bz << "\n";
|
||||
}
|
||||
}
|
||||
{
|
||||
// Fast method of evaluating the values at several points on a circle of
|
||||
// latitude using MagneticCircle.
|
||||
MagneticCircle circ = mag.Circle(t, lat, h);
|
||||
for (int i = -5; i <= 5; ++i) {
|
||||
double lon = lon0 + i * 0.2;
|
||||
double Bx, By, Bz;
|
||||
circ(lon, Bx, By, Bz);
|
||||
cout << lon << " " << Bx << " " << By << " " << Bz << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
26
libs/geographiclib/examples/example-MagneticModel.cpp
Normal file
26
libs/geographiclib/examples/example-MagneticModel.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// Example of using the GeographicLib::MagneticModel class
|
||||
// This requires that the wmm2010 magnetic model be installed; see
|
||||
// https://geographiclib.sourceforge.io/C++/doc/magnetic.html#magneticinst
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/MagneticModel.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
MagneticModel mag("wmm2010");
|
||||
double lat = 27.99, lon = 86.93, h = 8820, t = 2012; // Mt Everest
|
||||
double Bx, By, Bz;
|
||||
mag(t, lat,lon, h, Bx, By, Bz);
|
||||
double H, F, D, I;
|
||||
MagneticModel::FieldComponents(Bx, By, Bz, H, F, D, I);
|
||||
cout << H << " " << F << " " << D << " " << I << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
18
libs/geographiclib/examples/example-Math.cpp
Normal file
18
libs/geographiclib/examples/example-Math.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
// Example of using the GeographicLib::Math class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Math.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
cout << Math::pi() << " " << Math::sq(Math::pi()) << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
140
libs/geographiclib/examples/example-NearestNeighbor.cpp
Normal file
140
libs/geographiclib/examples/example-NearestNeighbor.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
// Example of using the GeographicLib::NearestNeighbor class. WARNING: this
|
||||
// creates a file, pointset.xml or pointset.txt, in the current directory.
|
||||
// Read lat/lon locations from locations.txt and lat/lon queries from
|
||||
// queries.txt. For each query print to standard output: the index for the
|
||||
// closest location and the distance to it. Print statistics to standard error
|
||||
// at the end.
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#if !defined(GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION)
|
||||
#define GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION 0
|
||||
#endif
|
||||
|
||||
#if GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION
|
||||
// If Boost serialization is available, use it.
|
||||
#include <boost/archive/xml_iarchive.hpp>
|
||||
#include <boost/archive/xml_oarchive.hpp>
|
||||
#endif
|
||||
|
||||
#include <GeographicLib/NearestNeighbor.hpp>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/DMS.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
// A structure to hold a geographic coordinate.
|
||||
struct pos {
|
||||
double _lat, _lon;
|
||||
pos(double lat = 0, double lon = 0) : _lat(lat), _lon(lon) {}
|
||||
};
|
||||
|
||||
// A class to compute the distance between 2 positions.
|
||||
class DistanceCalculator {
|
||||
private:
|
||||
Geodesic _geod;
|
||||
public:
|
||||
explicit DistanceCalculator(const Geodesic& geod) : _geod(geod) {}
|
||||
double operator() (const pos& a, const pos& b) const {
|
||||
double d;
|
||||
_geod.Inverse(a._lat, a._lon, b._lat, b._lon, d);
|
||||
if ( !(d >= 0) )
|
||||
// Catch illegal positions which result in d = NaN
|
||||
throw GeographicErr("distance doesn't satisfy d >= 0");
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Read in locations
|
||||
vector<pos> locs;
|
||||
double lat, lon;
|
||||
string sa, sb;
|
||||
{
|
||||
ifstream is("locations.txt");
|
||||
if (!is.good())
|
||||
throw GeographicErr("locations.txt not readable");
|
||||
while (is >> sa >> sb) {
|
||||
DMS::DecodeLatLon(sa, sb, lat, lon);
|
||||
locs.push_back(pos(lat, lon));
|
||||
}
|
||||
if (locs.size() == 0)
|
||||
throw GeographicErr("need at least one location");
|
||||
}
|
||||
|
||||
// Define a distance function object
|
||||
DistanceCalculator distance(Geodesic::WGS84());
|
||||
|
||||
// Create NearestNeighbor object
|
||||
NearestNeighbor<double, pos, DistanceCalculator> pointset;
|
||||
|
||||
{
|
||||
// Used saved object if it is available
|
||||
#if GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION
|
||||
ifstream is("pointset.xml");
|
||||
if (is.good()) {
|
||||
boost::archive::xml_iarchive ia(is);
|
||||
ia >> BOOST_SERIALIZATION_NVP(pointset);
|
||||
}
|
||||
#else
|
||||
ifstream is("pointset.txt");
|
||||
if (is.good())
|
||||
is >> pointset;
|
||||
#endif
|
||||
}
|
||||
// Is the saved pointset up-to-date?
|
||||
if (pointset.NumPoints() != int(locs.size())) {
|
||||
// else initialize it
|
||||
pointset.Initialize(locs, distance);
|
||||
// and save it
|
||||
#if GEOGRAPHICLIB_HAVE_BOOST_SERIALIZATION
|
||||
ofstream os("pointset.xml");
|
||||
if (!os.good())
|
||||
throw GeographicErr("cannot write to pointset.xml");
|
||||
boost::archive::xml_oarchive oa(os);
|
||||
oa << BOOST_SERIALIZATION_NVP(pointset);
|
||||
#else
|
||||
ofstream os("pointset.txt");
|
||||
if (!os.good())
|
||||
throw GeographicErr("cannot write to pointset.txt");
|
||||
os << pointset << "\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
ifstream is("queries.txt");
|
||||
double d;
|
||||
int count = 0;
|
||||
vector<int> k;
|
||||
while (is >> sa >> sb) {
|
||||
++count;
|
||||
DMS::DecodeLatLon(sa, sb, lat, lon);
|
||||
d = pointset.Search(locs, distance, pos(lat, lon), k);
|
||||
if (k.size() != 1)
|
||||
throw GeographicErr("unexpected number of results");
|
||||
cout << k[0] << " " << d << "\n";
|
||||
}
|
||||
int setupcost, numsearches, searchcost, mincost, maxcost;
|
||||
double mean, sd;
|
||||
pointset.Statistics(setupcost, numsearches, searchcost,
|
||||
mincost, maxcost, mean, sd);
|
||||
int
|
||||
totcost = setupcost + searchcost,
|
||||
exhaustivecost = count * pointset.NumPoints();
|
||||
cerr
|
||||
<< "Number of distance calculations = " << totcost << "\n"
|
||||
<< "With an exhaustive search = " << exhaustivecost << "\n"
|
||||
<< "Ratio = " << double(totcost) / exhaustivecost << "\n"
|
||||
<< "Efficiency improvement = "
|
||||
<< 100 * (1 - double(totcost) / exhaustivecost) << "%\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
25
libs/geographiclib/examples/example-NormalGravity.cpp
Normal file
25
libs/geographiclib/examples/example-NormalGravity.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// Example of using the GeographicLib::NormalGravity class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/NormalGravity.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
NormalGravity grav(Constants::WGS84_a(), Constants::WGS84_GM(),
|
||||
Constants::WGS84_omega(), Constants::WGS84_f());
|
||||
// Alternatively: const NormalGravity& grav = NormalGravity::WGS84();
|
||||
double lat = 27.99, h = 8820; // Mt Everest
|
||||
double gammay, gammaz;
|
||||
grav.Gravity(lat, h, gammay, gammaz);
|
||||
cout << gammay << " " << gammaz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
44
libs/geographiclib/examples/example-OSGB.cpp
Normal file
44
libs/geographiclib/examples/example-OSGB.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Example of using the GeographicLib::OSGB class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <GeographicLib/OSGB.hpp>
|
||||
#include <GeographicLib/DMS.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
{
|
||||
// Sample forward calculation from
|
||||
// A guide to coordinate systems in Great Britain
|
||||
double
|
||||
lat = DMS::Decode(52,39,27.2531),
|
||||
lon = DMS::Decode( 1,43, 4.5177);
|
||||
double x, y;
|
||||
OSGB::Forward(lat, lon, x, y);
|
||||
string gridref;
|
||||
OSGB::GridReference(x, y, 2, gridref);
|
||||
cout << fixed << setprecision(3)
|
||||
<< x << " " << y << " " << gridref << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
string gridref = "TG5113";
|
||||
double x, y;
|
||||
int prec;
|
||||
OSGB::GridReference(gridref, x, y, prec);
|
||||
double lat, lon;
|
||||
OSGB::Reverse(x, y, lat, lon);
|
||||
cout << fixed << setprecision(8)
|
||||
<< prec << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
37
libs/geographiclib/examples/example-PolarStereographic.cpp
Normal file
37
libs/geographiclib/examples/example-PolarStereographic.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Example of using the GeographicLib::PolarStereographic class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <GeographicLib/PolarStereographic.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
PolarStereographic proj(Constants::WGS84_a(), Constants::WGS84_f(),
|
||||
Constants::UPS_k0());
|
||||
// Alternatively:
|
||||
// const PolarStereographic& proj = PolarStereographic::UPS();
|
||||
bool northp = true;
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 61.2, lon = -149.9; // Anchorage
|
||||
double x, y;
|
||||
proj.Forward(northp, lat, lon, x, y);
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = -1637e3, y = 2824e3;
|
||||
double lat, lon;
|
||||
proj.Reverse(northp, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
40
libs/geographiclib/examples/example-PolygonArea.cpp
Normal file
40
libs/geographiclib/examples/example-PolygonArea.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Example of using the GeographicLib::PolygonArea class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/PolygonArea.hpp>
|
||||
#include <GeographicLib/Geodesic.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Geodesic geod(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Geodesic& geod = Geodesic::WGS84();
|
||||
PolygonArea poly(geod);
|
||||
poly.AddPoint( 52, 0); // London
|
||||
poly.AddPoint( 41,-74); // New York
|
||||
poly.AddPoint(-23,-43); // Rio de Janeiro
|
||||
poly.AddPoint(-26, 28); // Johannesburg
|
||||
double perimeter, area;
|
||||
unsigned n = poly.Compute(false, true, perimeter, area);
|
||||
cout << n << " " << perimeter << " " << area << "\n";
|
||||
// This adds a test for a bug fix for AddEdge. (Implements the
|
||||
// Planimeter29 test in geodtest.c.)
|
||||
PolygonArea poly1(geod);
|
||||
poly1.AddPoint(0,0);
|
||||
poly1.AddEdge(90,1000);
|
||||
poly1.AddEdge(0,1000);
|
||||
poly1.AddEdge(-90,1000);
|
||||
n = poly1.Compute(false, true, perimeter, area);
|
||||
// The area should be 1e6. Prior to the fix it was 1e6 - A/2, where
|
||||
// A = ellipsoid area.
|
||||
cout << n << " " << perimeter << " " << area << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
36
libs/geographiclib/examples/example-Rhumb.cpp
Normal file
36
libs/geographiclib/examples/example-Rhumb.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// Example of using the GeographicLib::Rhumb class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Rhumb.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Rhumb rhumb(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Rhumb& rhumb = Rhumb::WGS84();
|
||||
{
|
||||
// Sample direct calculation, travelling about NE from JFK
|
||||
double lat1 = 40.6, lon1 = -73.8, s12 = 5.5e6, azi12 = 51;
|
||||
double lat2, lon2;
|
||||
rhumb.Direct(lat1, lon1, azi12, s12, lat2, lon2);
|
||||
cout << lat2 << " " << lon2 << "\n";
|
||||
}
|
||||
{
|
||||
// Sample inverse calculation, JFK to LHR
|
||||
double
|
||||
lat1 = 40.6, lon1 = -73.8, // JFK Airport
|
||||
lat2 = 51.6, lon2 = -0.5; // LHR Airport
|
||||
double s12, azi12;
|
||||
rhumb.Inverse(lat1, lon1, lat2, lon2, s12, azi12);
|
||||
cout << s12 << " " << azi12 << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
41
libs/geographiclib/examples/example-RhumbLine.cpp
Normal file
41
libs/geographiclib/examples/example-RhumbLine.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// Example of using the GeographicLib::RhumbLine class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <cmath>
|
||||
#include <GeographicLib/Rhumb.hpp>
|
||||
#include <GeographicLib/Constants.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// Print waypoints between JFK and SIN
|
||||
Rhumb rhumb(Constants::WGS84_a(), Constants::WGS84_f());
|
||||
// Alternatively: const Rhumb& rhumb = Rhumb::WGS84();
|
||||
double
|
||||
lat1 = 40.640, lon1 = -73.779, // JFK
|
||||
lat2 = 1.359, lon2 = 103.989; // SIN
|
||||
double s12, azi12;
|
||||
rhumb.Inverse(lat1, lon1, lat2, lon2, s12, azi12);
|
||||
RhumbLine line = rhumb.Line(lat1, lon1, azi12);
|
||||
double ds0 = 500e3; // Nominal distance between points = 500 km
|
||||
int num = int(ceil(s12 / ds0)); // The number of intervals
|
||||
cout << fixed << setprecision(3);
|
||||
{
|
||||
// Use intervals of equal length
|
||||
double ds = s12 / num;
|
||||
for (int i = 0; i <= num; ++i) {
|
||||
double lat, lon;
|
||||
line.Position(i * ds, lat, lon);
|
||||
cout << i << " " << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
32
libs/geographiclib/examples/example-SphericalEngine.cpp
Normal file
32
libs/geographiclib/examples/example-SphericalEngine.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// Example of using the GeographicLib::SphericalEngine class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <GeographicLib/SphericalEngine.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
// See also example-SphericHarmonic.cpp
|
||||
try {
|
||||
int N = 3; // The maxium degree
|
||||
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
|
||||
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
|
||||
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
|
||||
vector<double> S(sa, sa + N * (N + 1) / 2);
|
||||
SphericalEngine::coeff c[1];
|
||||
c[0] = SphericalEngine::coeff(C, S, N);
|
||||
double f[] = {1};
|
||||
double x = 2, y = 3, z = 1, a = 1;
|
||||
double v, vx, vy, vz;
|
||||
v = SphericalEngine::Value<true, SphericalEngine::FULL, 1>
|
||||
(c, f, x, y, z, a, vx, vy, vz);
|
||||
cout << v << " " << vx << " " << vy << " " << vz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
29
libs/geographiclib/examples/example-SphericalHarmonic.cpp
Normal file
29
libs/geographiclib/examples/example-SphericalHarmonic.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
// Example of using the GeographicLib::SphericalHarmonic class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <GeographicLib/SphericalHarmonic.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
int N = 3; // The maxium degree
|
||||
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
|
||||
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
|
||||
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
|
||||
vector<double> S(sa, sa + N * (N + 1) / 2);
|
||||
double a = 1;
|
||||
SphericalHarmonic h(C, S, N, a);
|
||||
double x = 2, y = 3, z = 1;
|
||||
double v, vx, vy, vz;
|
||||
v = h(x, y, z, vx, vy, vz);
|
||||
cout << v << " " << vx << " " << vy << " " << vz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
33
libs/geographiclib/examples/example-SphericalHarmonic1.cpp
Normal file
33
libs/geographiclib/examples/example-SphericalHarmonic1.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Example of using the GeographicLib::SphericalHarmonic1 class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <GeographicLib/SphericalHarmonic1.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
int N = 3, N1 = 2; // The maxium degrees
|
||||
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
|
||||
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
|
||||
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
|
||||
vector<double> S(sa, sa + N * (N + 1) / 2);
|
||||
double cb[] = {1, 2, 3, 4, 5, 6};
|
||||
vector<double> C1(cb, cb + (N1 + 1) * (N1 + 2) / 2);
|
||||
double sb[] = {3, 2, 1};
|
||||
vector<double> S1(sb, sb + N1 * (N1 + 1) / 2);
|
||||
double a = 1;
|
||||
SphericalHarmonic1 h(C, S, N, C1, S1, N1, a);
|
||||
double tau = 0.1, x = 2, y = 3, z = 1;
|
||||
double v, vx, vy, vz;
|
||||
v = h(tau, x, y, z, vx, vy, vz);
|
||||
cout << v << " " << vx << " " << vy << " " << vz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
37
libs/geographiclib/examples/example-SphericalHarmonic2.cpp
Normal file
37
libs/geographiclib/examples/example-SphericalHarmonic2.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Example of using the GeographicLib::SphericalHarmonic2 class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
#include <GeographicLib/SphericalHarmonic2.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
int N = 3, N1 = 2, N2 = 1; // The maxium degrees
|
||||
double ca[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; // cosine coefficients
|
||||
vector<double> C(ca, ca + (N + 1) * (N + 2) / 2);
|
||||
double sa[] = {6, 5, 4, 3, 2, 1}; // sine coefficients
|
||||
vector<double> S(sa, sa + N * (N + 1) / 2);
|
||||
double cb[] = {1, 2, 3, 4, 5, 6};
|
||||
vector<double> C1(cb, cb + (N1 + 1) * (N1 + 2) / 2);
|
||||
double sb[] = {3, 2, 1};
|
||||
vector<double> S1(sb, sb + N1 * (N1 + 1) / 2);
|
||||
double cc[] = {2, 1};
|
||||
vector<double> C2(cc, cc + (N2 + 1));
|
||||
vector<double> S2;
|
||||
double a = 1;
|
||||
SphericalHarmonic2 h(C, S, N, N, N, C1, S1, N1, N1, N1,
|
||||
C2, S2, N2, N2, 0, a);
|
||||
double tau1 = 0.1, tau2 = 0.05, x = 2, y = 3, z = 1;
|
||||
double v, vx, vy, vz;
|
||||
v = h(tau1, tau2, x, y, z, vx, vy, vz);
|
||||
cout << v << " " << vx << " " << vy << " " << vz << "\n";
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
63
libs/geographiclib/examples/example-TransverseMercator.cpp
Normal file
63
libs/geographiclib/examples/example-TransverseMercator.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// Example of using the GeographicLib::TransverseMercator class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <GeographicLib/TransverseMercator.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
// Define a UTM projection for an arbitrary ellipsoid
|
||||
class UTMalt {
|
||||
private:
|
||||
TransverseMercator _tm; // The projection
|
||||
double _lon0; // Central longitude
|
||||
double _falseeasting, _falsenorthing;
|
||||
public:
|
||||
UTMalt(double a, // equatorial radius
|
||||
double f, // flattening
|
||||
int zone, // the UTM zone + hemisphere
|
||||
bool northp)
|
||||
: _tm(a, f, Constants::UTM_k0())
|
||||
, _lon0(6 * zone - 183)
|
||||
, _falseeasting(5e5)
|
||||
, _falsenorthing(northp ? 0 : 100e5) {
|
||||
if (!(zone >= 1 && zone <= 60))
|
||||
throw GeographicErr("zone not in [1,60]");
|
||||
}
|
||||
void Forward(double lat, double lon, double& x, double& y) {
|
||||
_tm.Forward(_lon0, lat, lon, x, y);
|
||||
x += _falseeasting;
|
||||
y += _falsenorthing;
|
||||
}
|
||||
void Reverse(double x, double y, double& lat, double& lon) {
|
||||
x -= _falseeasting;
|
||||
y -= _falsenorthing;
|
||||
_tm.Reverse(_lon0, x, y, lat, lon);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
try {
|
||||
UTMalt tm(6378388, 1/297.0, 30, true); // International ellipsoid, zone 30n
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 40.4, lon = -3.7; // Madrid
|
||||
double x, y;
|
||||
tm.Forward(lat, lon, x, y);
|
||||
cout << fixed << setprecision(0) << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = 441e3, y = 4472e3;
|
||||
double lat, lon;
|
||||
tm.Reverse(x, y, lat, lon);
|
||||
cout << fixed << setprecision(5) << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Example of using the GeographicLib::TransverseMercatorExact class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <GeographicLib/TransverseMercatorExact.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
TransverseMercatorExact proj(Constants::WGS84_a(), Constants::WGS84_f(),
|
||||
Constants::UTM_k0());
|
||||
// Alternatively:
|
||||
// const TransverseMercatorExact& proj = TransverseMercatorExact::UTM();
|
||||
double lon0 = -75; // Central meridian for UTM zone 18
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 40.3, lon = -74.7; // Princeton, NJ
|
||||
double x, y;
|
||||
proj.Forward(lon0, lat, lon, x, y);
|
||||
cout << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
double x = 25e3, y = 4461e3;
|
||||
double lat, lon;
|
||||
proj.Reverse(lon0, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
42
libs/geographiclib/examples/example-UTMUPS.cpp
Normal file
42
libs/geographiclib/examples/example-UTMUPS.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Example of using the GeographicLib::UTMUPS class
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <GeographicLib/UTMUPS.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
// See also example-GeoCoords.cpp
|
||||
{
|
||||
// Sample forward calculation
|
||||
double lat = 33.3, lon = 44.4; // Baghdad
|
||||
int zone;
|
||||
bool northp;
|
||||
double x, y;
|
||||
UTMUPS::Forward(lat, lon, zone, northp, x, y);
|
||||
string zonestr = UTMUPS::EncodeZone(zone, northp);
|
||||
cout << fixed << setprecision(2)
|
||||
<< zonestr << " " << x << " " << y << "\n";
|
||||
}
|
||||
{
|
||||
// Sample reverse calculation
|
||||
string zonestr = "38n";
|
||||
int zone;
|
||||
bool northp;
|
||||
UTMUPS::DecodeZone(zonestr, zone, northp);
|
||||
double x = 444e3, y = 3688e3;
|
||||
double lat, lon;
|
||||
UTMUPS::Reverse(zone, northp, x, y, lat, lon);
|
||||
cout << lat << " " << lon << "\n";
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
21
libs/geographiclib/examples/example-Utility.cpp
Normal file
21
libs/geographiclib/examples/example-Utility.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
// Example of using the GeographicLib::Utility class
|
||||
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <GeographicLib/Utility.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
int
|
||||
d1 = Utility::day(1939, 9, 3), // Britain declares war on Germany
|
||||
d2 = Utility::day(1945, 8, 15); // Japan surrenders
|
||||
cout << d2 - d1 << "\n"; // Length of Second World War for Britain
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
45
libs/geographiclib/examples/make-egmcof.cpp
Normal file
45
libs/geographiclib/examples/make-egmcof.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Write the coefficient files needed for approximating the normal gravity
|
||||
// field with a GravityModel. WARNING: this creates files, wgs84.egm.cof and
|
||||
// grs80.egm.cof, in the current directory.
|
||||
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <GeographicLib/NormalGravity.hpp>
|
||||
#include <GeographicLib/Utility.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace GeographicLib;
|
||||
|
||||
int main() {
|
||||
try {
|
||||
Utility::set_digits();
|
||||
const char* filenames[] = {"wgs84.egm.cof", "grs80.egm.cof"};
|
||||
const char* ids[] = {"WGS1984A", "GRS1980A"};
|
||||
for (int grs80 = 0; grs80 < 2; ++grs80) {
|
||||
ofstream file(filenames[grs80], ios::binary);
|
||||
Utility::writearray<char, char, false>(file, ids[grs80], 8);
|
||||
const int N = 20, M = 0,
|
||||
cnum = (M + 1) * (2 * N - M + 2) / 2; // cnum = N + 1
|
||||
vector<int> num(2);
|
||||
num[0] = N; num[1] = M;
|
||||
Utility::writearray<int, int, false>(file, num);
|
||||
vector<Math::real> c(cnum, 0);
|
||||
const NormalGravity& earth(grs80 ? NormalGravity::GRS80() :
|
||||
NormalGravity::WGS84());
|
||||
for (int n = 2; n <= N; n += 2)
|
||||
c[n] = - earth.DynamicalFormFactor(n) / sqrt(Math::real(2*n + 1));
|
||||
Utility::writearray<double, Math::real, false>(file, c);
|
||||
num[0] = num[1] = -1;
|
||||
Utility::writearray<int, int, false>(file, num);
|
||||
}
|
||||
}
|
||||
catch (const exception& e) {
|
||||
cerr << "Caught exception: " << e.what() << "\n";
|
||||
return 1;
|
||||
}
|
||||
catch (...) {
|
||||
cerr << "Caught unknown exception\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user