/src/proj/src/projections/mbt_fps.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | |
3 | | #include <math.h> |
4 | | |
5 | | #include "proj.h" |
6 | | #include "proj_internal.h" |
7 | | |
8 | | PROJ_HEAD(mbt_fps, "McBryde-Thomas Flat-Pole Sine (No. 2)") "\n\tCyl, Sph"; |
9 | | |
10 | 0 | #define MAX_ITER 10 |
11 | 0 | #define LOOP_TOL 1e-7 |
12 | 0 | #define C1 0.45503 |
13 | 0 | #define C2 1.36509 |
14 | 0 | #define C3 1.41546 |
15 | 0 | #define C_x 0.22248 |
16 | 0 | #define C_y 1.44492 |
17 | 0 | #define C1_2 0.33333333333333333333333333 |
18 | | |
19 | 0 | static PJ_XY mbt_fps_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */ |
20 | 0 | PJ_XY xy = {0.0, 0.0}; |
21 | 0 | (void)P; |
22 | |
|
23 | 0 | const double k = C3 * sin(lp.phi); |
24 | 0 | for (int i = MAX_ITER; i; --i) { |
25 | 0 | const double t = lp.phi / C2; |
26 | 0 | const double V = |
27 | 0 | (C1 * sin(t) + sin(lp.phi) - k) / (C1_2 * cos(t) + cos(lp.phi)); |
28 | 0 | lp.phi -= V; |
29 | 0 | if (fabs(V) < LOOP_TOL) |
30 | 0 | break; |
31 | 0 | } |
32 | 0 | const double t = lp.phi / C2; |
33 | 0 | xy.x = C_x * lp.lam * (1. + 3. * cos(lp.phi) / cos(t)); |
34 | 0 | xy.y = C_y * sin(t); |
35 | 0 | return xy; |
36 | 0 | } |
37 | | |
38 | 0 | static PJ_LP mbt_fps_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ |
39 | 0 | PJ_LP lp = {0.0, 0.0}; |
40 | |
|
41 | 0 | const double t = aasin(P->ctx, xy.y / C_y); |
42 | 0 | lp.phi = C2 * t; |
43 | 0 | lp.lam = xy.x / (C_x * (1. + 3. * cos(lp.phi) / cos(t))); |
44 | 0 | lp.phi = aasin(P->ctx, (C1 * sin(t) + sin(lp.phi)) / C3); |
45 | 0 | return (lp); |
46 | 0 | } |
47 | | |
48 | 0 | PJ *PJ_PROJECTION(mbt_fps) { |
49 | |
|
50 | 0 | P->es = 0; |
51 | 0 | P->inv = mbt_fps_s_inverse; |
52 | 0 | P->fwd = mbt_fps_s_forward; |
53 | |
|
54 | 0 | return P; |
55 | 0 | } |
56 | | |
57 | | #undef MAX_ITER |
58 | | #undef LOOP_TOL |
59 | | #undef C1 |
60 | | #undef C2 |
61 | | #undef C3 |
62 | | #undef C_x |
63 | | #undef C_y |
64 | | #undef C1_2 |