Coverage Report

Created: 2025-07-11 06:33

/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
8
static PJ *goode_destructor(PJ *P, int errlev) { /* Destructor */
50
8
    if (nullptr == P)
51
0
        return nullptr;
52
8
    if (nullptr == P->opaque)
53
0
        return pj_default_destructor(P, errlev);
54
8
    proj_destroy(static_cast<struct pj_goode_data *>(P->opaque)->sinu);
55
8
    proj_destroy(static_cast<struct pj_goode_data *>(P->opaque)->moll);
56
8
    return pj_default_destructor(P, errlev);
57
8
}
58
59
8
PJ *PJ_PROJECTION(goode) {
60
8
    struct pj_goode_data *Q = static_cast<struct pj_goode_data *>(
61
8
        calloc(1, sizeof(struct pj_goode_data)));
62
8
    if (nullptr == Q)
63
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
64
8
    P->opaque = Q;
65
8
    P->destructor = goode_destructor;
66
67
8
    P->es = 0.;
68
8
    Q->sinu = pj_sinu(nullptr);
69
8
    Q->moll = pj_moll(nullptr);
70
8
    if (Q->sinu == nullptr || Q->moll == nullptr)
71
0
        return goode_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
72
8
    Q->sinu->es = 0.;
73
8
    Q->sinu->ctx = P->ctx;
74
8
    Q->moll->ctx = P->ctx;
75
8
    Q->sinu = pj_sinu(Q->sinu);
76
8
    Q->moll = pj_moll(Q->moll);
77
8
    if (Q->sinu == nullptr || Q->moll == nullptr)
78
0
        return goode_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
79
80
8
    P->fwd = goode_s_forward;
81
8
    P->inv = goode_s_inverse;
82
83
8
    return P;
84
8
}
85
86
#undef Y_COR
87
#undef PHI_LIM