53 , _es((f < 0 ? -1 : 1) * sqrt(abs(_e2)))
57 , _c( sqrt(_e2m) * exp(
Math::eatanhe(real(1), _es)) )
68 #if GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER/2 == 2
69 static const real b1coeff[] = {
73 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER/2 == 3
74 static const real b1coeff[] = {
78 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER/2 == 4
79 static const real b1coeff[] = {
81 25, 64, 256, 4096, 16384, 16384,
84 #error "Bad value for GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER"
87 #if GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 4
88 static const real alpcoeff[] = {
90 164, 225, -480, 360, 720,
98 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 5
99 static const real alpcoeff[] = {
101 -635, 328, 450, -960, 720, 1440,
103 4496, 3899, -6048, 2730, 10080,
105 15061, -19776, 6832, 26880,
107 -171840, 49561, 161280,
111 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 6
112 static const real alpcoeff[] = {
114 31564, -66675, 34440, 47250, -100800, 75600, 151200,
116 -1983433, 863232, 748608, -1161216, 524160, 1935360,
118 670412, 406647, -533952, 184464, 725760,
120 6601661, -7732800, 2230245, 7257600,
122 -13675556, 3438171, 7983360,
124 212378941, 319334400,
126 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 7
127 static const real alpcoeff[] = {
129 1804025, 2020096, -4267200, 2204160, 3024000, -6451200, 4838400, 9676800,
131 4626384, -9917165, 4316160, 3743040, -5806080, 2620800, 9676800,
133 -67102379, 26816480, 16265880, -21358080, 7378560, 29030400,
135 155912000, 72618271, -85060800, 24532695, 79833600,
137 102508609, -109404448, 27505368, 63866880,
139 -12282192400LL, 2760926233LL, 4151347200LL,
141 1522256789, 1383782400,
143 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 8
144 static const real alpcoeff[] = {
146 -75900428, 37884525, 42422016, -89611200, 46287360, 63504000, -135475200,
147 101606400, 203212800,
149 148003883, 83274912, -178508970, 77690880, 67374720, -104509440,
152 318729724, -738126169, 294981280, 178924680, -234938880, 81164160,
155 -40176129013LL, 14967552000LL, 6971354016LL, -8165836800LL, 2355138720LL,
158 10421654396LL, 3997835751LL, -4266773472LL, 1072709352, 2490808320LL,
160 175214326799LL, -171950693600LL, 38652967262LL, 58118860800LL,
162 -67039739596LL, 13700311101LL, 12454041600LL,
164 1424729850961LL, 743921418240LL,
167 #error "Bad value for GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER"
170 #if GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 4
171 static const real betcoeff[] = {
173 -4, 555, -960, 720, 1440,
181 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 5
182 static const real betcoeff[] = {
184 -3645, -64, 8880, -15360, 11520, 23040,
186 4416, -3059, 672, 210, 10080,
188 -627, -592, 476, 13440,
194 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 6
195 static const real betcoeff[] = {
197 384796, -382725, -6720, 932400, -1612800, 1209600, 2419200,
199 -1118711, 1695744, -1174656, 258048, 80640, 3870720,
201 22276, -16929, -15984, 12852, 362880,
203 -830251, -158400, 197865, 7257600,
205 -435388, 453717, 15966720,
209 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 7
210 static const real betcoeff[] = {
212 -5406467, 6156736, -6123600, -107520, 14918400, -25804800, 19353600,
215 829456, -5593555, 8478720, -5873280, 1290240, 403200, 19353600,
217 9261899, 3564160, -2708640, -2557440, 2056320, 58060800,
219 14928352, -9132761, -1742400, 2176515, 79833600,
221 -8005831, -1741552, 1814868, 63866880,
223 -261810608, 268433009, 8302694400LL,
225 219941297, 5535129600LL,
227 #elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 8
228 static const real betcoeff[] = {
230 31777436, -37845269, 43097152, -42865200, -752640, 104428800, -180633600,
231 135475200, 270950400,
233 24749483, 14930208, -100683990, 152616960, -105719040, 23224320, 7257600,
236 -232468668, 101880889, 39205760, -29795040, -28131840, 22619520,
239 324154477, 1433121792, -876745056, -167270400, 208945440, 7664025600LL,
241 457888660, -312227409, -67920528, 70779852, 2490808320LL,
243 -19841813847LL, -3665348512LL, 3758062126LL, 116237721600LL,
245 -1989295244, 1979471673, 49816166400LL,
247 191773887257LL, 3719607091200LL,
250 #error "Bad value for GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER"
253 GEOGRAPHICLIB_STATIC_ASSERT(
sizeof(b1coeff) /
sizeof(real) ==
255 "Coefficient array size mismatch for b1");
256 GEOGRAPHICLIB_STATIC_ASSERT(
sizeof(alpcoeff) /
sizeof(real) ==
257 (maxpow_ * (maxpow_ + 3))/2,
258 "Coefficient array size mismatch for alp");
259 GEOGRAPHICLIB_STATIC_ASSERT(
sizeof(betcoeff) /
sizeof(real) ==
260 (maxpow_ * (maxpow_ + 3))/2,
261 "Coefficient array size mismatch for bet");
269 for (
int l = 1; l <= maxpow_; ++l) {
271 _alp[l] = d *
Math::polyval(m, alpcoeff + o, _n) / alpcoeff[o + m + 1];
272 _bet[l] = d *
Math::polyval(m, betcoeff + o, _n) / betcoeff[o + m + 1];
354 real& x, real& y, real& gamma, real& k)
360 latsign = lat < 0 ? -1 : 1,
361 lonsign = lon < 0 ? -1 : 1;
364 bool backside = lon > 90;
370 real sphi, cphi, slam, clam;
395 xip = atan2(taup, clam);
473 c0 = cos(2 * xip), ch0 = cosh(2 * etap),
474 s0 = sin(2 * xip), sh0 = sinh(2 * etap),
475 ar = 2 * c0 * ch0, ai = -2 * s0 * sh0;
478 xi0 = (n & 1 ? _alp[n] : 0), eta0 = 0,
481 yr0 = (n & 1 ? 2 * maxpow_ * _alp[n--] : 0), yi0 = 0,
484 xi1 = ar * xi0 - ai * eta0 - xi1 + _alp[n];
485 eta1 = ai * xi0 + ar * eta0 - eta1;
486 yr1 = ar * yr0 - ai * yi0 - yr1 + 2 * n * _alp[n];
487 yi1 = ai * yr0 + ar * yi0 - yi1;
489 xi0 = ar * xi1 - ai * eta1 - xi0 + _alp[n];
490 eta0 = ai * xi1 + ar * eta1 - eta0;
491 yr0 = ar * yr1 - ai * yi1 - yr0 + 2 * n * _alp[n];
492 yi0 = ai * yr1 + ar * yi1 - yi0;
496 yr1 = 1 - yr1 + ar * yr0 - ai * yi0;
497 yi1 = - yi1 + ai * yr0 + ar * yi0;
498 ar = s0 * ch0; ai = c0 * sh0;
500 xi = xip + ar * xi0 - ai * eta0,
501 eta = etap + ai * xi0 + ar * eta0;
506 y = _a1 * _k0 * (backside ?
Math::pi() - xi : xi) * latsign;
507 x = _a1 * _k0 * eta * lonsign;
510 gamma *= latsign * lonsign;
516 real& lat, real& lon, real& gamma, real& k)
522 xi = y / (_a1 * _k0),
523 eta = x / (_a1 * _k0);
526 xisign = xi < 0 ? -1 : 1,
527 etasign = eta < 0 ? -1 : 1;
534 c0 = cos(2 * xi), ch0 = cosh(2 * eta),
535 s0 = sin(2 * xi), sh0 = sinh(2 * eta),
536 ar = 2 * c0 * ch0, ai = -2 * s0 * sh0;
539 xip0 = (n & 1 ? -_bet[n] : 0), etap0 = 0,
542 yr0 = (n & 1 ? - 2 * maxpow_ * _bet[n--] : 0), yi0 = 0,
545 xip1 = ar * xip0 - ai * etap0 - xip1 - _bet[n];
546 etap1 = ai * xip0 + ar * etap0 - etap1;
547 yr1 = ar * yr0 - ai * yi0 - yr1 - 2 * n * _bet[n];
548 yi1 = ai * yr0 + ar * yi0 - yi1;
550 xip0 = ar * xip1 - ai * etap1 - xip0 - _bet[n];
551 etap0 = ai * xip1 + ar * etap1 - etap0;
552 yr0 = ar * yr1 - ai * yi1 - yr0 - 2 * n * _bet[n];
553 yi0 = ai * yr1 + ar * yi1 - yi0;
557 yr1 = 1 - yr1 + ar * yr0 - ai * yi0;
558 yi1 = - yi1 + ai * yr0 + ar * yi0;
559 ar = s0 * ch0; ai = c0 * sh0;
561 xip = xi + ar * xip0 - ai * etap0,
562 etap = eta + ai * xip0 + ar * etap0;
573 c = max(real(0), cos(xip)),
584 k *= sqrt(_e2m + _e2 / (1 +
Math::sq(tau))) *
598 gamma *= xisign * etasign;
static T AngNormalize(T x)
static bool isfinite(T x)
Mathematical functions needed by GeographicLib.
static void sincosd(T x, T &sinx, T &cosx)
void Forward(real lon0, real lat, real lon, real &x, real &y, real &gamma, real &k) const
static T AngDiff(T x, T y, T &e)
Transverse Mercator projection.
static const TransverseMercator & UTM()
Header for GeographicLib::TransverseMercator class.
TransverseMercator(real a, real f, real k0)
static T atan2d(T y, T x)
static T polyval(int N, const T p[], T x)
Namespace for GeographicLib.
void Reverse(real lon0, real x, real y, real &lat, real &lon, real &gamma, real &k) const
Exception handling for GeographicLib.
static T tauf(T taup, T es)
static T taupf(T tau, T es)