Coverage Report

Created: 2026-01-09 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PROJ/src/projections/goode.cpp
Line
Count
Source
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
1.84k
#define Y_COR 0.05280
12
2.52k
#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
2.52k
static PJ_XY goode_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
24
2.52k
    PJ_XY xy;
25
2.52k
    struct pj_goode_data *Q = static_cast<struct pj_goode_data *>(P->opaque);
26
27
2.52k
    if (fabs(lp.phi) <= PHI_LIM)
28
1.59k
        xy = Q->sinu->fwd(lp, Q->sinu);
29
924
    else {
30
924
        xy = Q->moll->fwd(lp, Q->moll);
31
924
        xy.y -= lp.phi >= 0.0 ? Y_COR : -Y_COR;
32
924
    }
33
2.52k
    return xy;
34
2.52k
}
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
44
static PJ *goode_destructor(PJ *P, int errlev) { /* Destructor */
50
44
    if (nullptr == P)
51
0
        return nullptr;
52
44
    if (nullptr == P->opaque)
53
0
        return pj_default_destructor(P, errlev);
54
44
    proj_destroy(static_cast<struct pj_goode_data *>(P->opaque)->sinu);
55
44
    proj_destroy(static_cast<struct pj_goode_data *>(P->opaque)->moll);
56
44
    return pj_default_destructor(P, errlev);
57
44
}
58
59
44
PJ *PJ_PROJECTION(goode) {
60
44
    struct pj_goode_data *Q = static_cast<struct pj_goode_data *>(
61
44
        calloc(1, sizeof(struct pj_goode_data)));
62
44
    if (nullptr == Q)
63
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
64
44
    P->opaque = Q;
65
44
    P->destructor = goode_destructor;
66
67
44
    P->es = 0.;
68
44
    Q->sinu = pj_sinu(nullptr);
69
44
    Q->moll = pj_moll(nullptr);
70
44
    if (Q->sinu == nullptr || Q->moll == nullptr)
71
0
        return goode_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
72
44
    Q->sinu->es = 0.;
73
44
    Q->sinu->ctx = P->ctx;
74
44
    Q->moll->ctx = P->ctx;
75
44
    Q->sinu = pj_sinu(Q->sinu);
76
44
    Q->moll = pj_moll(Q->moll);
77
44
    if (Q->sinu == nullptr || Q->moll == nullptr)
78
0
        return goode_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
79
80
44
    P->fwd = goode_s_forward;
81
44
    P->inv = goode_s_inverse;
82
83
44
    return P;
84
44
}
85
86
#undef Y_COR
87
#undef PHI_LIM