/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 |