Coverage Report

Created: 2025-06-13 06:29

/src/proj/src/projections/comill.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
The Compact Miller projection was designed by Tom Patterson, US National
3
Park Service, in 2014. The polynomial equation was developed by Bojan
4
Savric and Bernhard Jenny, College of Earth, Ocean, and Atmospheric
5
Sciences, Oregon State University.
6
Port to PROJ.4 by Bojan Savric, 4 April 2016
7
*/
8
9
#include <math.h>
10
11
#include "proj.h"
12
#include "proj_internal.h"
13
14
PROJ_HEAD(comill, "Compact Miller") "\n\tCyl, Sph";
15
16
0
#define K1 0.9902
17
0
#define K2 0.1604
18
0
#define K3 -0.03054
19
0
#define C1 K1
20
0
#define C2 (3 * K2)
21
0
#define C3 (5 * K3)
22
0
#define EPS 1e-11
23
0
#define MAX_Y (0.6000207669862655 * M_PI)
24
/* Not sure at all of the appropriate number for MAX_ITER... */
25
0
#define MAX_ITER 100
26
27
0
static PJ_XY comill_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
28
0
    PJ_XY xy = {0.0, 0.0};
29
0
    double lat_sq;
30
31
0
    (void)P; /* silence unused parameter warnings */
32
33
0
    lat_sq = lp.phi * lp.phi;
34
0
    xy.x = lp.lam;
35
0
    xy.y = lp.phi * (K1 + lat_sq * (K2 + K3 * lat_sq));
36
0
    return xy;
37
0
}
38
39
0
static PJ_LP comill_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */
40
0
    PJ_LP lp = {0.0, 0.0};
41
0
    double yc, tol, y2, f, fder;
42
0
    int i;
43
44
0
    (void)P; /* silence unused parameter warnings */
45
46
    /* make sure y is inside valid range */
47
0
    if (xy.y > MAX_Y) {
48
0
        xy.y = MAX_Y;
49
0
    } else if (xy.y < -MAX_Y) {
50
0
        xy.y = -MAX_Y;
51
0
    }
52
53
    /* latitude */
54
0
    yc = xy.y;
55
0
    for (i = MAX_ITER; i; --i) { /* Newton-Raphson */
56
0
        y2 = yc * yc;
57
0
        f = (yc * (K1 + y2 * (K2 + K3 * y2))) - xy.y;
58
0
        fder = C1 + y2 * (C2 + C3 * y2);
59
0
        tol = f / fder;
60
0
        yc -= tol;
61
0
        if (fabs(tol) < EPS) {
62
0
            break;
63
0
        }
64
0
    }
65
0
    if (i == 0)
66
0
        proj_context_errno_set(
67
0
            P->ctx, PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN);
68
0
    lp.phi = yc;
69
70
    /* longitude */
71
0
    lp.lam = xy.x;
72
73
0
    return lp;
74
0
}
75
76
201
PJ *PJ_PROJECTION(comill) {
77
201
    P->es = 0;
78
79
201
    P->inv = comill_s_inverse;
80
201
    P->fwd = comill_s_forward;
81
82
201
    return P;
83
201
}
84
85
#undef K1
86
#undef K2
87
#undef K3
88
#undef C1
89
#undef C2
90
#undef C3
91
#undef EPS
92
#undef MAX_Y
93
#undef MAX_ITER