44 namespace GeographicLib {
49 real(0.1)*sqrt(numeric_limits<real>::epsilon());
51 const Math::real TransverseMercator::overflow_ =
52 1 /
Math::sq(numeric_limits<real>::epsilon());
56 , _f(f <= 1 ? f : 1/f)
63 , _c( sqrt(_e2m) * exp(eatanhe(real(1))) )
77 _b1 = 1/(1+_n)*(nx*(nx+16)+64)/64;
78 _alp[1] = _n*(_n*(_n*(164*_n+225)-480)+360)/720;
79 _bet[1] = _n*(_n*((555-4*_n)*_n-960)+720)/1440;
80 _alp[2] = nx*(_n*(557*_n-864)+390)/1440;
81 _bet[2] = nx*((96-437*_n)*_n+30)/1440;
83 _alp[3] = (427-1236*_n)*nx/1680;
84 _bet[3] = (119-148*_n)*nx/3360;
86 _alp[4] = 49561*nx/161280;
87 _bet[4] = 4397*nx/161280;
90 _b1 = 1/(1+_n)*(nx*(nx+16)+64)/64;
91 _alp[1] = _n*(_n*(_n*((328-635*_n)*_n+450)-960)+720)/1440;
92 _bet[1] = _n*(_n*(_n*((-3645*_n-64)*_n+8880)-15360)+11520)/23040;
93 _alp[2] = nx*(_n*(_n*(4496*_n+3899)-6048)+2730)/10080;
94 _bet[2] = nx*(_n*(_n*(4416*_n-3059)+672)+210)/10080;
96 _alp[3] = nx*(_n*(15061*_n-19776)+6832)/26880;
97 _bet[3] = nx*((-627*_n-592)*_n+476)/13440;
99 _alp[4] = (49561-171840*_n)*nx/161280;
100 _bet[4] = (4397-3520*_n)*nx/161280;
102 _alp[5] = 34729*nx/80640;
103 _bet[5] = 4583*nx/161280;
106 _b1 = 1/(1+_n)*(nx*(nx*(nx+4)+64)+256)/256;
107 _alp[1] = _n*(_n*(_n*(_n*(_n*(31564*_n-66675)+34440)+47250)-100800)+
109 _bet[1] = _n*(_n*(_n*(_n*(_n*(384796*_n-382725)-6720)+932400)-1612800)+
111 _alp[2] = nx*(_n*(_n*((863232-1983433*_n)*_n+748608)-1161216)+524160)/
113 _bet[2] = nx*(_n*(_n*((1695744-1118711*_n)*_n-1174656)+258048)+80640)/
116 _alp[3] = nx*(_n*(_n*(670412*_n+406647)-533952)+184464)/725760;
117 _bet[3] = nx*(_n*(_n*(22276*_n-16929)-15984)+12852)/362880;
119 _alp[4] = nx*(_n*(6601661*_n-7732800)+2230245)/7257600;
120 _bet[4] = nx*((-830251*_n-158400)*_n+197865)/7257600;
122 _alp[5] = (3438171-13675556*_n)*nx/7983360;
123 _bet[5] = (453717-435388*_n)*nx/15966720;
125 _alp[6] = 212378941*nx/319334400;
126 _bet[6] = 20648693*nx/638668800;
129 _b1 = 1/(1+_n)*(nx*(nx*(nx+4)+64)+256)/256;
130 _alp[1] = _n*(_n*(_n*(_n*(_n*(_n*(1804025*_n+2020096)-4267200)+2204160)+
131 3024000)-6451200)+4838400)/9676800;
132 _bet[1] = _n*(_n*(_n*(_n*(_n*((6156736-5406467*_n)*_n-6123600)-107520)+
133 14918400)-25804800)+19353600)/38707200;
134 _alp[2] = nx*(_n*(_n*(_n*(_n*(4626384*_n-9917165)+4316160)+3743040)-
135 5806080)+2620800)/9676800;
136 _bet[2] = nx*(_n*(_n*(_n*(_n*(829456*_n-5593555)+8478720)-5873280)+
137 1290240)+403200)/19353600;
139 _alp[3] = nx*(_n*(_n*((26816480-67102379*_n)*_n+16265880)-21358080)+
141 _bet[3] = nx*(_n*(_n*(_n*(9261899*_n+3564160)-2708640)-2557440)+
144 _alp[4] = nx*(_n*(_n*(155912000*_n+72618271)-85060800)+24532695)/
146 _bet[4] = nx*(_n*(_n*(14928352*_n-9132761)-1742400)+2176515)/79833600;
148 _alp[5] = nx*(_n*(102508609*_n-109404448)+27505368)/63866880;
149 _bet[5] = nx*((-8005831*_n-1741552)*_n+1814868)/63866880;
151 _alp[6] = (2760926233.0-12282192400.0*_n)*nx/4151347200.0;
152 _bet[6] = (268433009-261810608*_n)*nx/8302694400.0;
154 _alp[7] = 1522256789.0*nx/1383782400.0;
155 _bet[7] = 219941297*nx/5535129600.0;
158 _b1 = 1/(1+_n)*(nx*(nx*(nx*(25*nx+64)+256)+4096)+16384)/16384;
159 _alp[1] = _n*(_n*(_n*(_n*(_n*(_n*((37884525-75900428*_n)*_n+42422016)-
160 89611200)+46287360)+63504000)-135475200)+
161 101606400)/203212800;
162 _bet[1] = _n*(_n*(_n*(_n*(_n*(_n*(_n*(31777436*_n-37845269)+43097152)-
163 42865200)-752640)+104428800)-180633600)+
164 135475200)/270950400;
165 _alp[2] = nx*(_n*(_n*(_n*(_n*(_n*(148003883*_n+83274912)-178508970)+
166 77690880)+67374720)-104509440)+47174400)/
168 _bet[2] = nx*(_n*(_n*(_n*(_n*(_n*(24749483*_n+14930208)-100683990)+
169 152616960)-105719040)+23224320)+7257600)/
172 _alp[3] = nx*(_n*(_n*(_n*(_n*(318729724*_n-738126169)+294981280)+
173 178924680)-234938880)+81164160)/319334400;
174 _bet[3] = nx*(_n*(_n*(_n*((101880889-232468668*_n)*_n+39205760)-
175 29795040)-28131840)+22619520)/638668800;
177 _alp[4] = nx*(_n*(_n*((14967552000.0-40176129013.0*_n)*_n+6971354016.0)-
178 8165836800.0)+2355138720.0)/7664025600.0;
179 _bet[4] = nx*(_n*(_n*(_n*(324154477*_n+1433121792.0)-876745056)-
180 167270400)+208945440)/7664025600.0;
182 _alp[5] = nx*(_n*(_n*(10421654396.0*_n+3997835751.0)-4266773472.0)+
183 1072709352.0)/2490808320.0;
184 _bet[5] = nx*(_n*(_n*(457888660*_n-312227409)-67920528)+70779852)/
187 _alp[6] = nx*(_n*(175214326799.0*_n-171950693600.0)+38652967262.0)/
189 _bet[6] = nx*((-19841813847.0*_n-3665348512.0)*_n+3758062126.0)/
192 _alp[7] = (13700311101.0-67039739596.0*_n)*nx/12454041600.0;
193 _bet[7] = (1979471673.0-1989295244.0*_n)*nx/49816166400.0;
195 _alp[8] = 1424729850961.0*nx/743921418240.0;
196 _bet[8] = 191773887257.0*nx/3719607091200.0;
199 STATIC_ASSERT(maxpow_ >= 4 && maxpow_ <= 8,
"Bad value of maxpow_");
208 Constants::WGS84_f<real>(),
209 Constants::UTM_k0<real>());
274 if (!(abs(tau) < overflow_))
278 sig = sinh( eatanhe(tau / tau1) );
283 if (!(abs(taup) < overflow_))
292 stol = tol_ * max(
real(1), abs(taup));
294 for (
int i = 0; i < numit_; ++i) {
297 sig = sinh( eatanhe( tau / tau1 ) ),
299 dtau = (taup - taupa) * (1 + _e2m *
Math::sq(tau)) /
302 if (!(abs(dtau) >= stol))
309 real& x, real& y, real& gamma, real& k)
314 latsign = lat < 0 ? -1 : 1,
315 lonsign = lon < 0 ? -1 : 1;
318 bool backside = lon > 90;
325 phi = lat * Math::degree<real>(),
326 lam = lon * Math::degree<real>();
347 c = max(
real(0), cos(lam)),
350 xip = atan2(taup, c);
357 gamma = atan(tanx(lam) *
369 xip = Math::pi<real>()/2;
428 c0 = cos(2 * xip), ch0 = cosh(2 * etap),
429 s0 = sin(2 * xip), sh0 = sinh(2 * etap),
430 ar = 2 * c0 * ch0, ai = -2 * s0 * sh0;
433 xi0 = (n & 1 ? _alp[n] : 0), eta0 = 0,
436 yr0 = (n & 1 ? 2 * maxpow_ * _alp[n--] : 0), yi0 = 0,
439 xi1 = ar * xi0 - ai * eta0 - xi1 + _alp[n];
440 eta1 = ai * xi0 + ar * eta0 - eta1;
441 yr1 = ar * yr0 - ai * yi0 - yr1 + 2 * n * _alp[n];
442 yi1 = ai * yr0 + ar * yi0 - yi1;
444 xi0 = ar * xi1 - ai * eta1 - xi0 + _alp[n];
445 eta0 = ai * xi1 + ar * eta1 - eta0;
446 yr0 = ar * yr1 - ai * yi1 - yr0 + 2 * n * _alp[n];
447 yi0 = ai * yr1 + ar * yi1 - yi0;
451 yr1 = 1 - yr1 + ar * yr0 - ai * yi0;
452 yi1 = - yi1 + ai * yr0 + ar * yi0;
453 ar = s0 * ch0; ai = c0 * sh0;
455 xi = xip + ar * xi0 - ai * eta0,
456 eta = etap + ai * xi0 + ar * eta0;
459 gamma -= atan2(yi1, yr1);
461 gamma /= Math::degree<real>();
462 y = _a1 * _k0 * (backside ? Math::pi<real>() - xi : xi) * latsign;
463 x = _a1 * _k0 * eta * lonsign;
466 gamma *= latsign * lonsign;
471 real& lat, real& lon, real& gamma, real& k)
477 xi = y / (_a1 * _k0),
478 eta = x / (_a1 * _k0);
481 xisign = xi < 0 ? -1 : 1,
482 etasign = eta < 0 ? -1 : 1;
485 bool backside = xi > Math::pi<real>()/2;
487 xi = Math::pi<real>() - xi;
489 c0 = cos(2 * xi), ch0 = cosh(2 * eta),
490 s0 = sin(2 * xi), sh0 = sinh(2 * eta),
491 ar = 2 * c0 * ch0, ai = -2 * s0 * sh0;
494 xip0 = (n & 1 ? -_bet[n] : 0), etap0 = 0,
497 yr0 = (n & 1 ? - 2 * maxpow_ * _bet[n--] : 0), yi0 = 0,
500 xip1 = ar * xip0 - ai * etap0 - xip1 - _bet[n];
501 etap1 = ai * xip0 + ar * etap0 - etap1;
502 yr1 = ar * yr0 - ai * yi0 - yr1 - 2 * n * _bet[n];
503 yi1 = ai * yr0 + ar * yi0 - yi1;
505 xip0 = ar * xip1 - ai * etap1 - xip0 - _bet[n];
506 etap0 = ai * xip1 + ar * etap1 - etap0;
507 yr0 = ar * yr1 - ai * yi1 - yr0 - 2 * n * _bet[n];
508 yi0 = ai * yr1 + ar * yi1 - yi0;
512 yr1 = 1 - yr1 + ar * yr0 - ai * yi0;
513 yi1 = - yi1 + ai * yr0 + ar * yi0;
514 ar = s0 * ch0; ai = c0 * sh0;
516 xip = xi + ar * xip0 - ai * etap0,
517 etap = eta + ai * xip0 + ar * etap0;
519 gamma = atan2(yi1, yr1);
529 c = max(
real(0), cos(xip)),
538 gamma += atan(tanx(xip) * tanh(etap));
540 k *= sqrt(_e2m + _e2 *
Math::sq(cos(phi))) *
543 phi = Math::pi<real>()/2;
547 lat = phi / Math::degree<real>() * xisign;
548 lon = lam / Math::degree<real>();
553 gamma /= Math::degree<real>();
556 gamma *= xisign * etasign;
static T AngNormalize(T x)
GeographicLib::Math::real real
static bool isfinite(T x)
void Forward(real lon0, real lat, real lon, real &x, real &y, real &gamma, real &k) const
Transverse Mercator projection.
Header for GeographicLib::TransverseMercator class.
static const TransverseMercator UTM
TransverseMercator(real a, real f, real k0)
static T AngDiff(T x, T y)
void Reverse(real lon0, real x, real y, real &lat, real &lon, real &gamma, real &k) const
#define STATIC_ASSERT(cond, reason)
Exception handling for GeographicLib.