Coverage Report

Created: 2025-06-13 06:18

/src/proj/src/projections/sts.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(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
0
static PJ *setup(PJ *P, double p, double q, int mode) {
56
0
    P->es = 0.;
57
0
    P->inv = sts_s_inverse;
58
0
    P->fwd = sts_s_forward;
59
0
    static_cast<struct pj_sts *>(P->opaque)->C_x = q / p;
60
0
    static_cast<struct pj_sts *>(P->opaque)->C_y = p;
61
0
    static_cast<struct pj_sts *>(P->opaque)->C_p = 1 / q;
62
0
    static_cast<struct pj_sts *>(P->opaque)->tan_mode = mode;
63
0
    return P;
64
0
}
65
66
0
PJ *PJ_PROJECTION(fouc) {
67
0
    struct pj_sts *Q =
68
0
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
69
0
    if (nullptr == Q)
70
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
71
0
    P->opaque = Q;
72
0
    return setup(P, 2., 2., 1);
73
0
}
74
75
0
PJ *PJ_PROJECTION(kav5) {
76
0
    struct pj_sts *Q =
77
0
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
78
0
    if (nullptr == Q)
79
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
80
0
    P->opaque = Q;
81
82
0
    return setup(P, 1.50488, 1.35439, 0);
83
0
}
84
85
0
PJ *PJ_PROJECTION(qua_aut) {
86
0
    struct pj_sts *Q =
87
0
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
88
0
    if (nullptr == Q)
89
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
90
0
    P->opaque = Q;
91
0
    return setup(P, 2., 2., 0);
92
0
}
93
94
0
PJ *PJ_PROJECTION(mbt_s) {
95
0
    struct pj_sts *Q =
96
0
        static_cast<struct pj_sts *>(calloc(1, sizeof(struct pj_sts)));
97
0
    if (nullptr == Q)
98
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
99
0
    P->opaque = Q;
100
0
    return setup(P, 1.48875, 1.36509, 0);
101
0
}