Coverage Report

Created: 2025-06-22 06:59

/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