/src/PROJ/src/projections/tobmerc.cpp
Line | Count | Source |
1 | | |
2 | | |
3 | | #include <float.h> |
4 | | #include <math.h> |
5 | | |
6 | | #include "proj.h" |
7 | | #include "proj_internal.h" |
8 | | #include <math.h> |
9 | | |
10 | | PROJ_HEAD(tobmerc, "Tobler-Mercator") "\n\tCyl, Sph"; |
11 | | |
12 | 336 | static PJ_XY tobmerc_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */ |
13 | 336 | PJ_XY xy = {0.0, 0.0}; |
14 | 336 | double cosphi; |
15 | | |
16 | 336 | if (fabs(lp.phi) >= M_HALFPI) { |
17 | | // builtins.gie tests "Test expected failure at the poles:". However |
18 | | // given that M_HALFPI is strictly less than pi/2 in double precision, |
19 | | // it's not clear why shouldn't just return a large result for xy.y (and |
20 | | // it's not even that large, merely 38.025...). Even if the logic was |
21 | | // such that phi was strictly equal to pi/2, allowing xy.y = inf would |
22 | | // be a reasonable result. |
23 | 0 | proj_errno_set(P, PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN); |
24 | 0 | return xy; |
25 | 0 | } |
26 | | |
27 | 336 | cosphi = cos(lp.phi); |
28 | 336 | xy.x = P->k0 * lp.lam * cosphi * cosphi; |
29 | 336 | xy.y = P->k0 * asinh(tan(lp.phi)); |
30 | 336 | return xy; |
31 | 336 | } |
32 | | |
33 | 0 | static PJ_LP tobmerc_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ |
34 | 0 | PJ_LP lp = {0.0, 0.0}; |
35 | 0 | double cosphi; |
36 | |
|
37 | 0 | lp.phi = atan(sinh(xy.y / P->k0)); |
38 | 0 | cosphi = cos(lp.phi); |
39 | 0 | lp.lam = xy.x / P->k0 / (cosphi * cosphi); |
40 | 0 | return lp; |
41 | 0 | } |
42 | | |
43 | 26 | PJ *PJ_PROJECTION(tobmerc) { |
44 | 26 | P->inv = tobmerc_s_inverse; |
45 | 26 | P->fwd = tobmerc_s_forward; |
46 | 26 | return P; |
47 | 26 | } |