Coverage Report

Created: 2025-10-30 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PROJ/src/projections/sts.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(kav5, "Kavrayskiy V") "\n\tPCyl, Sph";
10
PROJ_HEAD(qua_aut, "Quartic Authalic") "\n\tPCyl, Sph";
11
PROJ_HEAD(fouc, "Foucaut") "\n\tPCyl, Sph";
12
PROJ_HEAD(mbt_s, "McBryde-Thomas Flat-Polar Sine (No. 1)") "\n\tPCyl, Sph";
13
14
namespace { // anonymous namespace
15
struct pj_sts {
16
    double C_x, C_y, C_p;
17
    int tan_mode;
18
};
19
} // anonymous namespace
20
21
0
static PJ_XY sts_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
22
0
    PJ_XY xy = {0.0, 0.0};
23
0
    struct pj_sts *Q = static_cast<struct pj_sts *>(P->opaque);
24
25
0
    xy.x = Q->C_x * lp.lam * cos(lp.phi);
26
0
    xy.y = Q->C_y;
27
0
    lp.phi *= Q->C_p;
28
0
    const double c = cos(lp.phi);
29
0
    if (Q->tan_mode) {
30
0
        xy.x *= c * c;
31
0
        xy.y *= tan(lp.phi);
32
0
    } else {
33
0
        xy.x /= c;
34
0
        xy.y *= sin(lp.phi);
35
0
    }
36
0
    return xy;
37
0
}
38
39
0
static PJ_LP sts_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */
40
0
    PJ_LP lp = {0.0, 0.0};
41
0
    struct pj_sts *Q = static_cast<struct pj_sts *>(P->opaque);
42
43
0
    xy.y /= Q->C_y;
44
0
    lp.phi = Q->tan_mode ? atan(xy.y) : aasin(P->ctx, xy.y);
45
0
    const double c = cos(lp.phi);
46
0
    lp.phi /= Q->C_p;
47
0
    lp.lam = xy.x / (Q->C_x * cos(lp.phi));
48
0
    if (Q->tan_mode)
49
0
        lp.lam /= c * c;
50
0
    else
51
0
        lp.lam *= c;
52
0
    return lp;
53
0
}
54
55
93
static PJ *setup(PJ *P, double p, double q, int mode) {
56
93
    P->es = 0.;
57
93
    P->inv = sts_s_inverse;
58
93
    P->fwd = sts_s_forward;
59
93
    static_cast<struct pj_sts *>(P->opaque)->C_x = q / p;
60
93
    static_cast<struct pj_sts *>(P->opaque)->C_y = p;
61
93
    static_cast<struct pj_sts *>(P->opaque)->C_p = 1 / q;
62
93
    static_cast<struct pj_sts *>(P->opaque)->tan_mode = mode;
63
93
    return P;
64
93
}
65
66
13
PJ *PJ_PROJECTION(fouc) {
67
13
    struct pj_sts *Q =
68
13
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
69
13
    if (nullptr == Q)
70
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
71
13
    P->opaque = Q;
72
13
    return setup(P, 2., 2., 1);
73
13
}
74
75
5
PJ *PJ_PROJECTION(kav5) {
76
5
    struct pj_sts *Q =
77
5
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
78
5
    if (nullptr == Q)
79
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
80
5
    P->opaque = Q;
81
82
5
    return setup(P, 1.50488, 1.35439, 0);
83
5
}
84
85
69
PJ *PJ_PROJECTION(qua_aut) {
86
69
    struct pj_sts *Q =
87
69
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
88
69
    if (nullptr == Q)
89
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
90
69
    P->opaque = Q;
91
69
    return setup(P, 2., 2., 0);
92
69
}
93
94
6
PJ *PJ_PROJECTION(mbt_s) {
95
6
    struct pj_sts *Q =
96
6
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
97
6
    if (nullptr == Q)
98
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
99
6
    P->opaque = Q;
100
6
    return setup(P, 1.48875, 1.36509, 0);
101
6
}