Coverage Report

Created: 2025-08-28 06:57

/src/proj/src/projections/merc.cpp
Line
Count
Source (jump to first uncovered line)
1
2
3
#include <float.h>
4
#include <math.h>
5
6
#include "proj.h"
7
#include "proj_internal.h"
8
#include <math.h>
9
10
PROJ_HEAD(merc, "Mercator") "\n\tCyl, Sph&Ell\n\tlat_ts=";
11
PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Ell\n\t";
12
13
0
static PJ_XY merc_e_forward(PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */
14
0
    PJ_XY xy = {0.0, 0.0};
15
0
    xy.x = P->k0 * lp.lam;
16
    // Instead of calling tan and sin, call sin and cos which the compiler
17
    // optimizes to a single call to sincos.
18
0
    double sphi = sin(lp.phi);
19
0
    double cphi = cos(lp.phi);
20
0
    xy.y = P->k0 * (asinh(sphi / cphi) - P->e * atanh(P->e * sphi));
21
0
    return xy;
22
0
}
23
24
0
static PJ_XY merc_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
25
0
    PJ_XY xy = {0.0, 0.0};
26
0
    xy.x = P->k0 * lp.lam;
27
0
    xy.y = P->k0 * asinh(tan(lp.phi));
28
0
    return xy;
29
0
}
30
31
0
static PJ_LP merc_e_inverse(PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */
32
0
    PJ_LP lp = {0.0, 0.0};
33
0
    lp.phi = atan(pj_sinhpsi2tanphi(P->ctx, sinh(xy.y / P->k0), P->e));
34
0
    lp.lam = xy.x / P->k0;
35
0
    return lp;
36
0
}
37
38
0
static PJ_LP merc_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */
39
0
    PJ_LP lp = {0.0, 0.0};
40
0
    lp.phi = atan(sinh(xy.y / P->k0));
41
0
    lp.lam = xy.x / P->k0;
42
0
    return lp;
43
0
}
44
45
1.59k
PJ *PJ_PROJECTION(merc) {
46
1.59k
    double phits = 0.0;
47
1.59k
    int is_phits;
48
49
1.59k
    if ((is_phits = pj_param(P->ctx, P->params, "tlat_ts").i)) {
50
685
        phits = fabs(pj_param(P->ctx, P->params, "rlat_ts").f);
51
685
        if (phits >= M_HALFPI) {
52
1
            proj_log_error(
53
1
                P, _("Invalid value for lat_ts: |lat_ts| should be <= 90°"));
54
1
            return pj_default_destructor(P,
55
1
                                         PROJ_ERR_INVALID_OP_ILLEGAL_ARG_VALUE);
56
1
        }
57
685
    }
58
59
1.58k
    if (P->es != 0.0) { /* ellipsoid */
60
415
        if (is_phits)
61
90
            P->k0 = pj_msfn(sin(phits), cos(phits), P->es);
62
415
        P->inv = merc_e_inverse;
63
415
        P->fwd = merc_e_forward;
64
415
    }
65
66
1.17k
    else { /* sphere */
67
1.17k
        if (is_phits)
68
594
            P->k0 = cos(phits);
69
1.17k
        P->inv = merc_s_inverse;
70
1.17k
        P->fwd = merc_s_forward;
71
1.17k
    }
72
73
1.58k
    return P;
74
1.59k
}
75
76
862
PJ *PJ_PROJECTION(webmerc) {
77
78
    /* Overriding k_0 with fixed parameter */
79
862
    P->k0 = 1.0;
80
81
862
    P->inv = merc_s_inverse;
82
862
    P->fwd = merc_s_forward;
83
862
    return P;
84
862
}