/src/proj/src/projections/sts.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | |
3 | | #include <errno.h> |
4 | | #include <math.h> |
5 | | |
6 | | #include "proj.h" |
7 | | #include "proj_internal.h" |
8 | | |
9 | | PROJ_HEAD(kav5, "Kavrayskiy V") "\n\tPCyl, Sph"; |
10 | | PROJ_HEAD(qua_aut, "Quartic Authalic") "\n\tPCyl, Sph"; |
11 | | PROJ_HEAD(fouc, "Foucaut") "\n\tPCyl, Sph"; |
12 | | PROJ_HEAD(mbt_s, "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl, Sph"; |
13 | | |
14 | | namespace { // anonymous namespace |
15 | | struct pj_sts { |
16 | | double C_x, C_y, C_p; |
17 | | int tan_mode; |
18 | | }; |
19 | | } // anonymous namespace |
20 | | |
21 | 0 | static PJ_XY sts_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */ |
22 | 0 | PJ_XY xy = {0.0, 0.0}; |
23 | 0 | struct pj_sts *Q = static_cast<struct pj_sts *>(P->opaque); |
24 | |
|
25 | 0 | xy.x = Q->C_x * lp.lam * cos(lp.phi); |
26 | 0 | xy.y = Q->C_y; |
27 | 0 | lp.phi *= Q->C_p; |
28 | 0 | const double c = cos(lp.phi); |
29 | 0 | if (Q->tan_mode) { |
30 | 0 | xy.x *= c * c; |
31 | 0 | xy.y *= tan(lp.phi); |
32 | 0 | } else { |
33 | 0 | xy.x /= c; |
34 | 0 | xy.y *= sin(lp.phi); |
35 | 0 | } |
36 | 0 | return xy; |
37 | 0 | } |
38 | | |
39 | 0 | static PJ_LP sts_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ |
40 | 0 | PJ_LP lp = {0.0, 0.0}; |
41 | 0 | struct pj_sts *Q = static_cast<struct pj_sts *>(P->opaque); |
42 | |
|
43 | 0 | xy.y /= Q->C_y; |
44 | 0 | lp.phi = Q->tan_mode ? atan(xy.y) : aasin(P->ctx, xy.y); |
45 | 0 | const double c = cos(lp.phi); |
46 | 0 | lp.phi /= Q->C_p; |
47 | 0 | lp.lam = xy.x / (Q->C_x * cos(lp.phi)); |
48 | 0 | if (Q->tan_mode) |
49 | 0 | lp.lam /= c * c; |
50 | 0 | else |
51 | 0 | lp.lam *= c; |
52 | 0 | return lp; |
53 | 0 | } |
54 | | |
55 | 0 | static PJ *setup(PJ *P, double p, double q, int mode) { |
56 | 0 | P->es = 0.; |
57 | 0 | P->inv = sts_s_inverse; |
58 | 0 | P->fwd = sts_s_forward; |
59 | 0 | static_cast<struct pj_sts *>(P->opaque)->C_x = q / p; |
60 | 0 | static_cast<struct pj_sts *>(P->opaque)->C_y = p; |
61 | 0 | static_cast<struct pj_sts *>(P->opaque)->C_p = 1 / q; |
62 | 0 | static_cast<struct pj_sts *>(P->opaque)->tan_mode = mode; |
63 | 0 | return P; |
64 | 0 | } |
65 | | |
66 | 0 | PJ *PJ_PROJECTION(fouc) { |
67 | 0 | struct pj_sts *Q = |
68 | 0 | static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts))); |
69 | 0 | if (nullptr == Q) |
70 | 0 | return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
71 | 0 | P->opaque = Q; |
72 | 0 | return setup(P, 2., 2., 1); |
73 | 0 | } |
74 | | |
75 | 0 | PJ *PJ_PROJECTION(kav5) { |
76 | 0 | struct pj_sts *Q = |
77 | 0 | static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts))); |
78 | 0 | if (nullptr == Q) |
79 | 0 | return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
80 | 0 | P->opaque = Q; |
81 | |
|
82 | 0 | return setup(P, 1.50488, 1.35439, 0); |
83 | 0 | } |
84 | | |
85 | 0 | PJ *PJ_PROJECTION(qua_aut) { |
86 | 0 | struct pj_sts *Q = |
87 | 0 | static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts))); |
88 | 0 | if (nullptr == Q) |
89 | 0 | return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
90 | 0 | P->opaque = Q; |
91 | 0 | return setup(P, 2., 2., 0); |
92 | 0 | } |
93 | | |
94 | 0 | PJ *PJ_PROJECTION(mbt_s) { |
95 | 0 | struct pj_sts *Q = |
96 | 0 | static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts))); |
97 | 0 | if (nullptr == Q) |
98 | 0 | return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
99 | 0 | P->opaque = Q; |
100 | 0 | return setup(P, 1.48875, 1.36509, 0); |
101 | 0 | } |