GeographicLib
2.7
Toggle main menu visibility
Loading...
Searching...
No Matches
PolarStereographic.cpp
Go to the documentation of this file.
1
/**
2
* \file PolarStereographic.cpp
3
* \brief Implementation for GeographicLib::PolarStereographic class
4
*
5
* Copyright (c) Charles Karney (2008-2022) <karney@alum.mit.edu> and licensed
6
* under the MIT/X11 License. For more information, see
7
* https://geographiclib.sourceforge.io/
8
**********************************************************************/
9
10
#include <
GeographicLib/PolarStereographic.hpp
>
11
12
namespace
GeographicLib
{
13
14
using namespace
std;
15
16
PolarStereographic::PolarStereographic
(real a, real f, real k0)
17
: _a(a)
18
, _f(f)
19
, _e2(_f * (2 - _f))
20
, _es((_f < 0 ? -1 : 1) * sqrt(fabs(_e2)))
21
, _e2m(1 - _e2)
22
, _c( (1 - _f) * exp(
Math
::eatanhe(real(1), _es)) )
23
, _k0(k0)
24
{
25
if
(!(isfinite(_a) && _a > 0))
26
throw
GeographicErr
(
"Equatorial radius is not positive"
);
27
if
(!(isfinite(_f) && _f < 1))
28
throw
GeographicErr
(
"Polar semiaxis is not positive"
);
29
if
(!(isfinite(_k0) && _k0 > 0))
30
throw
GeographicErr
(
"Scale is not positive"
);
31
}
32
33
const
PolarStereographic
&
PolarStereographic::UPS
() {
34
static
const
PolarStereographic
ups(
Constants::WGS84_a
(),
35
Constants::WGS84_f
(),
36
Constants::UPS_k0
());
37
return
ups;
38
}
39
40
// This formulation converts to conformal coordinates by tau = tan(phi) and
41
// tau' = tan(phi') where phi' is the conformal latitude. The formulas are:
42
// tau = tan(phi)
43
// secphi = hypot(1, tau)
44
// sig = sinh(e * atanh(e * tau / secphi))
45
// taup = tan(phip) = tau * hypot(1, sig) - sig * hypot(1, tau)
46
// c = (1 - f) * exp(e * atanh(e))
47
//
48
// Forward:
49
// rho = (2*k0*a/c) / (hypot(1, taup) + taup) (taup >= 0)
50
// = (2*k0*a/c) * (hypot(1, taup) - taup) (taup < 0)
51
//
52
// Reverse:
53
// taup = ((2*k0*a/c) / rho - rho / (2*k0*a/c))/2
54
//
55
// Scale:
56
// k = (rho/a) * secphi * sqrt((1-e2) + e2 / secphi^2)
57
//
58
// In limit rho -> 0, tau -> inf, taup -> inf, secphi -> inf, secphip -> inf
59
// secphip = taup = exp(-e * atanh(e)) * tau = exp(-e * atanh(e)) * secphi
60
61
void
PolarStereographic::Forward
(
bool
northp, real lat, real lon,
62
real& x, real& y,
63
real& gamma, real& k)
const
{
64
lat =
Math::LatFix
(lat);
65
lat *= northp ? 1 : -1;
66
real
67
tau =
Math::tand
(lat),
68
secphi = hypot(
real
(1), tau),
69
taup =
Math::taupf
(tau, _es),
70
rho = hypot(
real
(1), taup) + fabs(taup);
71
rho = taup >= 0 ? (lat !=
Math::qd
? 1/rho : 0) : rho;
72
rho *= 2 * _k0 * _a / _c;
73
k = lat !=
Math::qd
?
74
(rho / _a) * secphi * sqrt(_e2m + _e2 /
Math::sq
(secphi)) : _k0;
75
Math::sincosd
(lon, x, y);
76
x *= rho;
77
y *= (northp ? -rho : rho);
78
gamma =
Math::AngNormalize
(northp ? lon : -lon);
79
}
80
81
void
PolarStereographic::Reverse
(
bool
northp, real x, real y,
82
real& lat, real& lon,
83
real& gamma, real& k)
const
{
84
real
85
rho = hypot(x, y),
86
t = rho != 0 ? rho / (2 * _k0 * _a / _c) :
87
Math::sq
(numeric_limits<real>::epsilon()),
88
taup = (1 / t - t) / 2,
89
tau =
Math::tauf
(taup, _es),
90
secphi = hypot(
real
(1), tau);
91
k = rho != 0 ? (rho / _a) * secphi * sqrt(_e2m + _e2 /
Math::sq
(secphi)) :
92
_k0;
93
lat = (northp ? 1 : -1) *
Math::atand
(tau);
94
lon =
Math::atan2d
(x, northp ? -y : y );
95
gamma =
Math::AngNormalize
(northp ? lon : -lon);
96
}
97
98
void
PolarStereographic::SetScale
(real lat, real k) {
99
if
(!(isfinite(k) && k > 0))
100
throw
GeographicErr
(
"Scale is not positive"
);
101
if
(!(-
Math::qd
< lat && lat <=
Math::qd
))
102
throw
GeographicErr
(
"Latitude must be in (-"
+ to_string(
Math::qd
)
103
+
"d, "
+ to_string(
Math::qd
) +
"d]"
);
104
real x, y, gamma, kold;
105
_k0 = 1;
106
Forward
(
true
, lat, 0, x, y, gamma, kold);
107
_k0 *= k/kold;
108
}
109
110
}
// namespace GeographicLib
real
GeographicLib::Math::real real
Definition
Geod3Solve.cpp:25
PolarStereographic.hpp
Header for GeographicLib::PolarStereographic class.
GeographicLib::Constants::UPS_k0
static T UPS_k0()
Definition
Constants.hpp:182
GeographicLib::Constants::WGS84_f
static T WGS84_f()
Definition
Constants.hpp:118
GeographicLib::Constants::WGS84_a
static T WGS84_a()
Definition
Constants.hpp:112
GeographicLib::GeographicErr
Exception handling for GeographicLib.
Definition
Constants.hpp:344
GeographicLib::Math
Mathematical functions needed by GeographicLib.
Definition
Math.hpp:82
GeographicLib::Math::tand
static T tand(T x)
Definition
Math.cpp:203
GeographicLib::Math::LatFix
static T LatFix(T x)
Definition
Math.hpp:303
GeographicLib::Math::sincosd
static void sincosd(T x, T &sinx, T &cosx)
Definition
Math.cpp:104
GeographicLib::Math::atan2d
static T atan2d(T y, T x)
Definition
Math.cpp:212
GeographicLib::Math::sq
static T sq(T x)
Definition
Math.hpp:209
GeographicLib::Math::qd
static constexpr int qd
degrees per quarter turn
Definition
Math.hpp:142
GeographicLib::Math::tauf
static T tauf(T taup, T es)
Definition
Math.cpp:251
GeographicLib::Math::AngNormalize
static T AngNormalize(T x)
Definition
Math.cpp:69
GeographicLib::Math::atand
static T atand(T x)
Definition
Math.cpp:234
GeographicLib::Math::taupf
static T taupf(T tau, T es)
Definition
Math.cpp:241
GeographicLib::PolarStereographic::Reverse
void Reverse(bool northp, real x, real y, real &lat, real &lon, real &gamma, real &k) const
Definition
PolarStereographic.cpp:81
GeographicLib::PolarStereographic::PolarStereographic
PolarStereographic(real a, real f, real k0)
Definition
PolarStereographic.cpp:16
GeographicLib::PolarStereographic::SetScale
void SetScale(real lat, real k=real(1))
Definition
PolarStereographic.cpp:98
GeographicLib::PolarStereographic::UPS
static const PolarStereographic & UPS()
Definition
PolarStereographic.cpp:33
GeographicLib::PolarStereographic::Forward
void Forward(bool northp, real lat, real lon, real &x, real &y, real &gamma, real &k) const
Definition
PolarStereographic.cpp:61
GeographicLib
Namespace for GeographicLib.
Definition
Accumulator.cpp:12
src
PolarStereographic.cpp
Generated by
1.17.0