GeographicLib: TransverseMercator.cpp Source File (original) (raw)
45 bool exact, bool extendp)
46 : _a(a)
47 , _f(f)
48 , _k0(k0)
49 , _exact(exact)
50 , _e2(_f * (2 - _f))
51 , _es((_f < 0 ? -1 : 1) * sqrt(fabs(_e2)))
52 , _e2m(1 - _e2)
53
54
55 , _c( sqrt(_e2m) * exp(Math::eatanhe(real(1), _es)) )
56 , _n(_f / (2 - _f))
59 {
60 if (_exact) return;
61 if (!(isfinite(_a) && _a > 0))
62 throw GeographicErr("Equatorial radius is not positive");
63 if (!(isfinite(_f) && _f < 1))
64 throw GeographicErr("Polar semi-axis is not positive");
65 if (!(isfinite(_k0) && _k0 > 0))
67 if (extendp)
68 throw GeographicErr("TransverseMercator extendp not allowed if !exact");
69
70
71#if GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER/2 == 2
72 static const real b1coeff[] = {
73
74 1, 16, 64, 64,
75 };
76#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER/2 == 3
77 static const real b1coeff[] = {
78
79 1, 4, 64, 256, 256,
80 };
81#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER/2 == 4
82 static const real b1coeff[] = {
83
84 25, 64, 256, 4096, 16384, 16384,
85 };
86#else
87#error "Bad value for GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER"
88#endif
89
90#if GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 4
91 static const real alpcoeff[] = {
92
93 164, 225, -480, 360, 720,
94
95 557, -864, 390, 1440,
96
97 -1236, 427, 1680,
98
99 49561, 161280,
100 };
101#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 5
102 static const real alpcoeff[] = {
103
104 -635, 328, 450, -960, 720, 1440,
105
106 4496, 3899, -6048, 2730, 10080,
107
108 15061, -19776, 6832, 26880,
109
110 -171840, 49561, 161280,
111
112 34729, 80640,
113 };
114#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 6
115 static const real alpcoeff[] = {
116
117 31564, -66675, 34440, 47250, -100800, 75600, 151200,
118
119 -1983433, 863232, 748608, -1161216, 524160, 1935360,
120
121 670412, 406647, -533952, 184464, 725760,
122
123 6601661, -7732800, 2230245, 7257600,
124
125 -13675556, 3438171, 7983360,
126
127 212378941, 319334400,
128 };
129#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 7
130 static const real alpcoeff[] = {
131
132 1804025, 2020096, -4267200, 2204160, 3024000, -6451200, 4838400, 9676800,
133
134 4626384, -9917165, 4316160, 3743040, -5806080, 2620800, 9676800,
135
136 -67102379, 26816480, 16265880, -21358080, 7378560, 29030400,
137
138 155912000, 72618271, -85060800, 24532695, 79833600,
139
140 102508609, -109404448, 27505368, 63866880,
141
142 -12282192400LL, 2760926233LL, 4151347200LL,
143
144 1522256789, 1383782400,
145 };
146#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 8
147 static const real alpcoeff[] = {
148
149 -75900428, 37884525, 42422016, -89611200, 46287360, 63504000, -135475200,
150 101606400, 203212800,
151
152 148003883, 83274912, -178508970, 77690880, 67374720, -104509440,
153 47174400, 174182400,
154
155 318729724, -738126169, 294981280, 178924680, -234938880, 81164160,
156 319334400,
157
158 -40176129013LL, 14967552000LL, 6971354016LL, -8165836800LL, 2355138720LL,
159 7664025600LL,
160
161 10421654396LL, 3997835751LL, -4266773472LL, 1072709352, 2490808320LL,
162
163 175214326799LL, -171950693600LL, 38652967262LL, 58118860800LL,
164
165 -67039739596LL, 13700311101LL, 12454041600LL,
166
167 1424729850961LL, 743921418240LL,
168 };
169#else
170#error "Bad value for GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER"
171#endif
172
173#if GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 4
174 static const real betcoeff[] = {
175
176 -4, 555, -960, 720, 1440,
177
178 -437, 96, 30, 1440,
179
180 -148, 119, 3360,
181
182 4397, 161280,
183 };
184#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 5
185 static const real betcoeff[] = {
186
187 -3645, -64, 8880, -15360, 11520, 23040,
188
189 4416, -3059, 672, 210, 10080,
190
191 -627, -592, 476, 13440,
192
193 -3520, 4397, 161280,
194
195 4583, 161280,
196 };
197#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 6
198 static const real betcoeff[] = {
199
200 384796, -382725, -6720, 932400, -1612800, 1209600, 2419200,
201
202 -1118711, 1695744, -1174656, 258048, 80640, 3870720,
203
204 22276, -16929, -15984, 12852, 362880,
205
206 -830251, -158400, 197865, 7257600,
207
208 -435388, 453717, 15966720,
209
210 20648693, 638668800,
211 };
212#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 7
213 static const real betcoeff[] = {
214
215 -5406467, 6156736, -6123600, -107520, 14918400, -25804800, 19353600,
216 38707200,
217
218 829456, -5593555, 8478720, -5873280, 1290240, 403200, 19353600,
219
220 9261899, 3564160, -2708640, -2557440, 2056320, 58060800,
221
222 14928352, -9132761, -1742400, 2176515, 79833600,
223
224 -8005831, -1741552, 1814868, 63866880,
225
226 -261810608, 268433009, 8302694400LL,
227
228 219941297, 5535129600LL,
229 };
230#elif GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER == 8
231 static const real betcoeff[] = {
232
233 31777436, -37845269, 43097152, -42865200, -752640, 104428800, -180633600,
234 135475200, 270950400,
235
236 24749483, 14930208, -100683990, 152616960, -105719040, 23224320, 7257600,
237 348364800,
238
239 -232468668, 101880889, 39205760, -29795040, -28131840, 22619520,
240 638668800,
241
242 324154477, 1433121792, -876745056, -167270400, 208945440, 7664025600LL,
243
244 457888660, -312227409, -67920528, 70779852, 2490808320LL,
245
246 -19841813847LL, -3665348512LL, 3758062126LL, 116237721600LL,
247
248 -1989295244, 1979471673, 49816166400LL,
249
250 191773887257LL, 3719607091200LL,
251 };
252#else
253#error "Bad value for GEOGRAPHICLIB_TRANSVERSEMERCATOR_ORDER"
254#endif
255
256 static_assert(sizeof(b1coeff) / sizeof(real) == maxpow_/2 + 2,
257 "Coefficient array size mismatch for b1");
258 static_assert(sizeof(alpcoeff) / sizeof(real) ==
259 (maxpow_ * (maxpow_ + 3))/2,
260 "Coefficient array size mismatch for alp");
261 static_assert(sizeof(betcoeff) / sizeof(real) ==
262 (maxpow_ * (maxpow_ + 3))/2,
263 "Coefficient array size mismatch for bet");
264 int m = maxpow_/2;
266
267
268 _a1 = _b1 * _a;
269 int o = 0;
270 real d = _n;
271 for (int l = 1; l <= maxpow_; ++l) {
272 m = maxpow_ - l;
273 _alp[l] = d * Math::polyval(m, alpcoeff + o, _n) / alpcoeff[o + m + 1];
274 _bet[l] = d * Math::polyval(m, betcoeff + o, _n) / betcoeff[o + m + 1];
275 o += m + 2;
276 d *= _n;
277 }
278
279
280 }
356 real& x, real& y,
357 real& gamma, real& k) const {
358 if (_exact)
359 return _tmexact.Forward(lon0, lat, lon, x, y, gamma, k);
362
363 int
364 latsign = signbit(lat) ? -1 : 1,
365 lonsign = signbit(lon) ? -1 : 1;
366 lon *= lonsign;
367 lat *= latsign;
368 bool backside = lon > Math::qd;
369 if (backside) {
370 if (lat == 0)
371 latsign = -1;
373 }
374 real sphi, cphi, slam, clam;
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 real etap, xip;
396 real
397 tau = sphi / cphi,
399 xip = atan2(taup, clam);
400
401
402 etap = asinh(slam / hypot(taup, clam));
403
404
405
406
407 gamma = Math::atan2d(slam * taup, clam * hypot(real(1), taup));
408
409
410
411
412
413
414
415 k = sqrt(_e2m + _e2 * Math::sq(cphi)) * hypot(real(1), tau)
416 / hypot(taup, clam);
417 } else {
419 etap = 0;
420 gamma = lon;
421 k = _c;
422 }
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488 real
489 c0 = cos(2 * xip), ch0 = cosh(2 * etap),
490 s0 = sin(2 * xip), sh0 = sinh(2 * etap);
491 complex a(2 * c0 * ch0, -2 * s0 * sh0);
492 int n = maxpow_;
493 complex
494 y0(n & 1 ? _alp[n] : 0), y1,
495 z0(n & 1 ? 2*n * _alp[n] : 0), z1;
496 if (n & 1) --n;
497 while (n) {
498 y1 = a * y0 - y1 + _alp[n];
499 z1 = a * z0 - z1 + 2*n * _alp[n];
500 --n;
501 y0 = a * y1 - y0 + _alp[n];
502 z0 = a * z1 - z0 + 2*n * _alp[n];
503 --n;
504 }
505 a /= real(2);
506 z1 = real(1) - z1 + a * z0;
507 a = complex(s0 * ch0, c0 * sh0);
508 y1 = complex(xip, etap) + a * y0;
509
510
512 k *= _b1 * abs(z1);
513 real xi = y1.real(), eta = y1.imag();
514 y = _a1 * _k0 * (backside ? Math::pi() - xi : xi) * latsign;
515 x = _a1 * _k0 * eta * lonsign;
516 if (backside)
518 gamma *= latsign * lonsign;
520 k *= _k0;
521 }
524 real& lat, real& lon,
525 real& gamma, real& k) const {
526 if (_exact)
527 return _tmexact.Reverse(lon0, x, y, lat, lon, gamma, k);
528
529
530
531 real
532 xi = y / (_a1 * _k0),
533 eta = x / (_a1 * _k0);
534
535 int
536 xisign = signbit(xi) ? -1 : 1,
537 etasign = signbit(eta) ? -1 : 1;
538 xi *= xisign;
539 eta *= etasign;
540 bool backside = xi > Math::pi()/2;
541 if (backside)
543 real
544 c0 = cos(2 * xi), ch0 = cosh(2 * eta),
545 s0 = sin(2 * xi), sh0 = sinh(2 * eta);
546 complex a(2 * c0 * ch0, -2 * s0 * sh0);
547 int n = maxpow_;
548 complex
549 y0(n & 1 ? -_bet[n] : 0), y1,
550 z0(n & 1 ? -2*n * _bet[n] : 0), z1;
551 if (n & 1) --n;
552 while (n) {
553 y1 = a * y0 - y1 - _bet[n];
554 z1 = a * z0 - z1 - 2*n * _bet[n];
555 --n;
556 y0 = a * y1 - y0 - _bet[n];
557 z0 = a * z1 - z0 - 2*n * _bet[n];
558 --n;
559 }
560 a /= real(2);
561 z1 = real(1) - z1 + a * z0;
562 a = complex(s0 * ch0, c0 * sh0);
563 y1 = complex(xi, eta) + a * y0;
564
566 k = _b1 / abs(z1);
567
568
569
570
571
572 real
573 xip = y1.real(), etap = y1.imag(),
574 s = sinh(etap),
575 c = fmax(real(0), cos(xip)),
576 r = hypot(s, c);
577 if (r != 0) {
578 lon = Math::atan2d(s, c);
579
580 real
581 sxip = sin(xip),
583 gamma += Math::atan2d(sxip * tanh(etap), c);
585
586 k *= sqrt(_e2m + _e2 / (1 + Math::sq(tau))) *
587 hypot(real(1), tau) * r;
588 } else {
590 lon = 0;
591 k *= _c;
592 }
593 lat *= xisign;
594 if (backside)
596 lon *= etasign;
598 if (backside)
600 gamma *= xisign * etasign;
602 k *= _k0;
603 }