/src/proj/src/projections/goode.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(goode, "Goode Homolosine") "\n\tPCyl, Sph"; |
10 | | |
11 | 0 | #define Y_COR 0.05280 |
12 | 0 | #define PHI_LIM 0.71093078197902358062 |
13 | | |
14 | | C_NAMESPACE PJ *pj_sinu(PJ *), *pj_moll(PJ *); |
15 | | |
16 | | namespace { // anonymous namespace |
17 | | struct pj_goode_data { |
18 | | PJ *sinu; |
19 | | PJ *moll; |
20 | | }; |
21 | | } // anonymous namespace |
22 | | |
23 | 0 | static PJ_XY goode_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */ |
24 | 0 | PJ_XY xy; |
25 | 0 | struct pj_goode_data *Q = static_cast<struct pj_goode_data *>(P->opaque); |
26 | |
|
27 | 0 | if (fabs(lp.phi) <= PHI_LIM) |
28 | 0 | xy = Q->sinu->fwd(lp, Q->sinu); |
29 | 0 | else { |
30 | 0 | xy = Q->moll->fwd(lp, Q->moll); |
31 | 0 | xy.y -= lp.phi >= 0.0 ? Y_COR : -Y_COR; |
32 | 0 | } |
33 | 0 | return xy; |
34 | 0 | } |
35 | | |
36 | 0 | static PJ_LP goode_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */ |
37 | 0 | PJ_LP lp; |
38 | 0 | struct pj_goode_data *Q = static_cast<struct pj_goode_data *>(P->opaque); |
39 | |
|
40 | 0 | if (fabs(xy.y) <= PHI_LIM) |
41 | 0 | lp = Q->sinu->inv(xy, Q->sinu); |
42 | 0 | else { |
43 | 0 | xy.y += xy.y >= 0.0 ? Y_COR : -Y_COR; |
44 | 0 | lp = Q->moll->inv(xy, Q->moll); |
45 | 0 | } |
46 | 0 | return lp; |
47 | 0 | } |
48 | | |
49 | 481 | static PJ *goode_destructor(PJ *P, int errlev) { /* Destructor */ |
50 | 481 | if (nullptr == P) |
51 | 0 | return nullptr; |
52 | 481 | if (nullptr == P->opaque) |
53 | 0 | return pj_default_destructor(P, errlev); |
54 | 481 | proj_destroy(static_cast<struct pj_goode_data *>(P->opaque)->sinu); |
55 | 481 | proj_destroy(static_cast<struct pj_goode_data *>(P->opaque)->moll); |
56 | 481 | return pj_default_destructor(P, errlev); |
57 | 481 | } |
58 | | |
59 | 481 | PJ *PJ_PROJECTION(goode) { |
60 | 481 | struct pj_goode_data *Q = static_cast<struct pj_goode_data *>( |
61 | 481 | calloc(1, sizeof(struct pj_goode_data))); |
62 | 481 | if (nullptr == Q) |
63 | 0 | return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
64 | 481 | P->opaque = Q; |
65 | 481 | P->destructor = goode_destructor; |
66 | | |
67 | 481 | P->es = 0.; |
68 | 481 | Q->sinu = pj_sinu(nullptr); |
69 | 481 | Q->moll = pj_moll(nullptr); |
70 | 481 | if (Q->sinu == nullptr || Q->moll == nullptr) |
71 | 0 | return goode_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
72 | 481 | Q->sinu->es = 0.; |
73 | 481 | Q->sinu->ctx = P->ctx; |
74 | 481 | Q->moll->ctx = P->ctx; |
75 | 481 | Q->sinu = pj_sinu(Q->sinu); |
76 | 481 | Q->moll = pj_moll(Q->moll); |
77 | 481 | if (Q->sinu == nullptr || Q->moll == nullptr) |
78 | 0 | return goode_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/); |
79 | | |
80 | 481 | P->fwd = goode_s_forward; |
81 | 481 | P->inv = goode_s_inverse; |
82 | | |
83 | 481 | return P; |
84 | 481 | } |
85 | | |
86 | | #undef Y_COR |
87 | | #undef PHI_LIM |