Coverage Report

Created: 2024-02-25 06:14

/src/PROJ/src/projections/patterson.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2014 Bojan Savric
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
/*
18
 * The Patterson Cylindrical projection was designed by Tom Patterson, US
19
 * National Park Service, in 2014, using Flex Projector. The polynomial
20
 * equations for the projection were developed by Bojan Savric, Oregon State
21
 * University, in collaboration with Tom Patterson and Bernhard Jenny, Oregon
22
 * State University.
23
 *
24
 * Java reference algorithm implemented by Bojan Savric in Java Map Projection
25
 * Library (a Java port of PROJ.4) in the file PattersonProjection.java.
26
 *
27
 * References:
28
 *    Java Map Projection Library
29
 *       https://github.com/OSUCartography/JMapProjLib
30
 *
31
 *    Patterson Cylindrical Projection
32
 *       http://shadedrelief.com/patterson/
33
 *
34
 *    Patterson, T., Savric, B., and Jenny, B. (2015). Cartographic Perspectives
35
 *       (No.78). Describes the projection design and characteristics, and
36
 *       developing the equations.    doi:10.14714/CP78.1270
37
 *       https://doi.org/10.14714/CP78.1270
38
 *
39
 * Port to PROJ.4 by Micah Cochran, 26 March 2016
40
 */
41
42
#include <math.h>
43
44
#include "proj.h"
45
#include "proj_internal.h"
46
47
PROJ_HEAD(patterson, "Patterson Cylindrical") "\n\tCyl";
48
49
0
#define K1 1.0148
50
0
#define K2 0.23185
51
0
#define K3 -0.14499
52
0
#define K4 0.02406
53
0
#define C1 K1
54
0
#define C2 (5.0 * K2)
55
0
#define C3 (7.0 * K3)
56
0
#define C4 (9.0 * K4)
57
0
#define EPS11 1.0e-11
58
0
#define MAX_Y 1.790857183
59
/* Not sure at all of the appropriate number for MAX_ITER... */
60
0
#define MAX_ITER 100
61
62
0
static PJ_XY patterson_s_forward(PJ_LP lp, PJ *P) { /* Spheroidal, forward */
63
0
    PJ_XY xy = {0.0, 0.0};
64
0
    double phi2;
65
0
    (void)P;
66
67
0
    phi2 = lp.phi * lp.phi;
68
0
    xy.x = lp.lam;
69
0
    xy.y = lp.phi * (K1 + phi2 * phi2 * (K2 + phi2 * (K3 + K4 * phi2)));
70
71
0
    return xy;
72
0
}
73
74
0
static PJ_LP patterson_s_inverse(PJ_XY xy, PJ *P) { /* Spheroidal, inverse */
75
0
    PJ_LP lp = {0.0, 0.0};
76
0
    double yc;
77
0
    int i;
78
0
    (void)P;
79
80
0
    yc = xy.y;
81
82
    /* make sure y is inside valid range */
83
0
    if (xy.y > MAX_Y) {
84
0
        xy.y = MAX_Y;
85
0
    } else if (xy.y < -MAX_Y) {
86
0
        xy.y = -MAX_Y;
87
0
    }
88
89
0
    for (i = MAX_ITER; i; --i) { /* Newton-Raphson */
90
0
        const double y2 = yc * yc;
91
0
        const double f =
92
0
            (yc * (K1 + y2 * y2 * (K2 + y2 * (K3 + K4 * y2)))) - xy.y;
93
0
        const double fder = C1 + y2 * y2 * (C2 + y2 * (C3 + C4 * y2));
94
0
        const double tol = f / fder;
95
0
        yc -= tol;
96
0
        if (fabs(tol) < EPS11) {
97
0
            break;
98
0
        }
99
0
    }
100
0
    if (i == 0)
101
0
        proj_context_errno_set(
102
0
            P->ctx, PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN);
103
0
    lp.phi = yc;
104
105
    /* longitude */
106
0
    lp.lam = xy.x;
107
108
0
    return lp;
109
0
}
110
111
37
PJ *PJ_PROJECTION(patterson) {
112
37
    P->es = 0.;
113
37
    P->inv = patterson_s_inverse;
114
37
    P->fwd = patterson_s_forward;
115
116
37
    return P;
117
37
}
118
119
#undef K1
120
#undef K2
121
#undef K3
122
#undef K4
123
#undef C1
124
#undef C2
125
#undef C3
126
#undef C4
127
#undef EPS11
128
#undef MAX_Y
129
#undef MAX_ITER