Coverage Report

Created: 2025-07-23 09:13

/src/gdal/proj/src/projections/gstmerc.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(gstmerc,
10
          "Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion)")
11
"\n\tCyl, Sph&Ell\n\tlat_0= lon_0= k_0=";
12
13
namespace { // anonymous namespace
14
struct pj_gstmerc_data {
15
    double lamc;
16
    double phic;
17
    double c;
18
    double n1;
19
    double n2;
20
    double XS;
21
    double YS;
22
};
23
} // anonymous namespace
24
25
0
static PJ_XY gstmerc_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
26
0
    PJ_XY xy = {0.0, 0.0};
27
0
    struct pj_gstmerc_data *Q =
28
0
        static_cast<struct pj_gstmerc_data *>(P->opaque);
29
0
    double L, Ls, sinLs1, Ls1;
30
31
0
    L = Q->n1 * lp.lam;
32
0
    Ls = Q->c + Q->n1 * log(pj_tsfn(-lp.phi, -sin(lp.phi), P->e));
33
0
    sinLs1 = sin(L) / cosh(Ls);
34
0
    Ls1 = log(pj_tsfn(-asin(sinLs1), -sinLs1, 0.0));
35
0
    xy.x = (Q->XS + Q->n2 * Ls1) * P->ra;
36
0
    xy.y = (Q->YS + Q->n2 * atan(sinh(Ls) / cos(L))) * P->ra;
37
38
0
    return xy;
39
0
}
40
41
0
static PJ_LP gstmerc_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */
42
0
    PJ_LP lp = {0.0, 0.0};
43
0
    struct pj_gstmerc_data *Q =
44
0
        static_cast<struct pj_gstmerc_data *>(P->opaque);
45
0
    double L, LC, sinC;
46
47
0
    L = atan(sinh((xy.x * P->a - Q->XS) / Q->n2) /
48
0
             cos((xy.y * P->a - Q->YS) / Q->n2));
49
0
    sinC = sin((xy.y * P->a - Q->YS) / Q->n2) /
50
0
           cosh((xy.x * P->a - Q->XS) / Q->n2);
51
0
    LC = log(pj_tsfn(-asin(sinC), -sinC, 0.0));
52
0
    lp.lam = L / Q->n1;
53
0
    lp.phi = -pj_phi2(P->ctx, exp((LC - Q->c) / Q->n1), P->e);
54
55
0
    return lp;
56
0
}
57
58
2.64k
PJ *PJ_PROJECTION(gstmerc) {
59
2.64k
    struct pj_gstmerc_data *Q = static_cast<struct pj_gstmerc_data *>(
60
2.64k
        calloc(1, sizeof(struct pj_gstmerc_data)));
61
2.64k
    if (nullptr == Q)
62
0
        return pj_default_destructor(P, PROJ_ERR_OTHER /*ENOMEM*/);
63
2.64k
    P->opaque = Q;
64
65
2.64k
    Q->lamc = P->lam0;
66
2.64k
    Q->n1 = sqrt(1 + P->es * pow(cos(P->phi0), 4.0) / (1 - P->es));
67
2.64k
    Q->phic = asin(sin(P->phi0) / Q->n1);
68
2.64k
    Q->c = log(pj_tsfn(-Q->phic, -sin(P->phi0) / Q->n1, 0.0)) -
69
2.64k
           Q->n1 * log(pj_tsfn(-P->phi0, -sin(P->phi0), P->e));
70
2.64k
    Q->n2 = P->k0 * P->a * sqrt(1 - P->es) /
71
2.64k
            (1 - P->es * sin(P->phi0) * sin(P->phi0));
72
2.64k
    Q->XS = 0;
73
2.64k
    Q->YS = -Q->n2 * Q->phic;
74
75
2.64k
    P->inv = gstmerc_s_inverse;
76
2.64k
    P->fwd = gstmerc_s_forward;
77
78
2.64k
    return P;
79
2.64k
}