/src/PROJ/src/projections/wink2.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(wink2, "Winkel II") "\n\tPCyl, Sph\n\tlat_1="; |
10 | | |
11 | | namespace { // anonymous namespace |
12 | | struct pj_wink2_data { |
13 | | double cosphi1; |
14 | | }; |
15 | | } // anonymous namespace |
16 | | |
17 | 924 | #define MAX_ITER 10 |
18 | 3.68k | #define LOOP_TOL 1e-7 |
19 | | |
20 | 924 | static PJ_XY wink2_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */ |
21 | 924 | PJ_XY xy = {0.0, 0.0}; |
22 | 924 | int i; |
23 | | |
24 | 924 | xy.y = lp.phi * M_TWO_D_PI; |
25 | 924 | const double k = M_PI * sin(lp.phi); |
26 | 924 | lp.phi *= 1.8; |
27 | 3.68k | for (i = MAX_ITER; i; --i) { |
28 | 3.68k | const double V = (lp.phi + sin(lp.phi) - k) / (1. + cos(lp.phi)); |
29 | 3.68k | lp.phi -= V; |
30 | 3.68k | if (fabs(V) < LOOP_TOL) |
31 | 924 | break; |
32 | 3.68k | } |
33 | 924 | if (!i) |
34 | 0 | lp.phi = (lp.phi < 0.) ? -M_HALFPI : M_HALFPI; |
35 | 924 | else |
36 | 924 | lp.phi *= 0.5; |
37 | 924 | xy.x = |
38 | 924 | 0.5 * lp.lam * |
39 | 924 | (cos(lp.phi) + static_cast<struct pj_wink2_data *>(P->opaque)->cosphi1); |
40 | 924 | xy.y = M_FORTPI * (sin(lp.phi) + xy.y); |
41 | 924 | return xy; |
42 | 924 | } |
43 | | |
44 | 0 | static PJ_LP wink2_s_inverse(PJ_XY xy, PJ *P) { |
45 | 0 | PJ_LP lpInit; |
46 | |
|
47 | 0 | lpInit.phi = xy.y; |
48 | 0 | lpInit.lam = xy.x; |
49 | |
|
50 | 0 | constexpr double deltaXYTolerance = 1e-10; |
51 | 0 | return pj_generic_inverse_2d(xy, P, lpInit, deltaXYTolerance); |
52 | 0 | } |
53 | | |
54 | 18 | PJ *PJ_PROJECTION(wink2) { |
55 | 18 | struct pj_wink2_data *Q = static_cast<struct pj_wink2_data *>( |
56 | 18 | calloc(1, sizeof(struct pj_wink2_data))); |
57 | 18 | if (nullptr == Q) |
58 | 0 | return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
59 | 18 | P->opaque = Q; |
60 | | |
61 | 18 | static_cast<struct pj_wink2_data *>(P->opaque)->cosphi1 = |
62 | 18 | cos(pj_param(P->ctx, P->params, "rlat_1").f); |
63 | 18 | P->es = 0.; |
64 | 18 | P->fwd = wink2_s_forward; |
65 | 18 | P->inv = wink2_s_inverse; |
66 | | |
67 | 18 | return P; |
68 | 18 | } |
69 | | |
70 | | #undef MAX_ITER |
71 | | #undef LOOP_TOL |