Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ** libproj -- library of cartographic projections |
3 | | ** |
4 | | ** Copyright (c) 2003 Gerald I. Evenden |
5 | | */ |
6 | | /* |
7 | | ** Permission is hereby granted, free of charge, to any person obtaining |
8 | | ** a copy of this software and associated documentation files (the |
9 | | ** "Software"), to deal in the Software without restriction, including |
10 | | ** without limitation the rights to use, copy, modify, merge, publish, |
11 | | ** distribute, sublicense, and/or sell copies of the Software, and to |
12 | | ** permit persons to whom the Software is furnished to do so, subject to |
13 | | ** the following conditions: |
14 | | ** |
15 | | ** The above copyright notice and this permission notice shall be |
16 | | ** included in all copies or substantial portions of the Software. |
17 | | ** |
18 | | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
19 | | ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
20 | | ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
21 | | ** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
22 | | ** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
23 | | ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
24 | | ** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
25 | | */ |
26 | | |
27 | | #include <math.h> |
28 | | #include <stdlib.h> |
29 | | |
30 | | #include "proj.h" |
31 | | #include "proj_internal.h" |
32 | | |
33 | 0 | #define MAX_ITER 20 |
34 | | |
35 | | namespace { // anonymous namespace |
36 | | struct GAUSS { |
37 | | double C; |
38 | | double K; |
39 | | double e; |
40 | | double ratexp; |
41 | | }; |
42 | | } // anonymous namespace |
43 | 0 | #define DEL_TOL 1e-14 |
44 | | |
45 | 53 | static double srat(double esinp, double ratexp) { |
46 | 53 | return (pow((1. - esinp) / (1. + esinp), ratexp)); |
47 | 53 | } |
48 | | |
49 | 53 | void *pj_gauss_ini(double e, double phi0, double *chi, double *rc) { |
50 | 53 | double sphi, cphi, es; |
51 | 53 | struct GAUSS *en; |
52 | | |
53 | 53 | if ((en = (struct GAUSS *)malloc(sizeof(struct GAUSS))) == nullptr) |
54 | 0 | return (nullptr); |
55 | 53 | es = e * e; |
56 | 53 | en->e = e; |
57 | 53 | sphi = sin(phi0); |
58 | 53 | cphi = cos(phi0); |
59 | 53 | cphi *= cphi; |
60 | 53 | *rc = sqrt(1. - es) / (1. - es * sphi * sphi); |
61 | 53 | en->C = sqrt(1. + es * cphi * cphi / (1. - es)); |
62 | 53 | if (en->C == 0.0) { |
63 | 0 | free(en); |
64 | 0 | return nullptr; |
65 | 0 | } |
66 | 53 | *chi = asin(sphi / en->C); |
67 | 53 | en->ratexp = 0.5 * en->C * e; |
68 | 53 | double srat_val = srat(en->e * sphi, en->ratexp); |
69 | 53 | if (srat_val == 0.0) { |
70 | 0 | free(en); |
71 | 0 | return nullptr; |
72 | 0 | } |
73 | 53 | if (.5 * phi0 + M_FORTPI < 1e-10) { |
74 | 0 | en->K = 1.0 / srat_val; |
75 | 53 | } else { |
76 | 53 | en->K = tan(.5 * *chi + M_FORTPI) / |
77 | 53 | (pow(tan(.5 * phi0 + M_FORTPI), en->C) * srat_val); |
78 | 53 | } |
79 | 53 | return ((void *)en); |
80 | 53 | } |
81 | | |
82 | 0 | PJ_LP pj_gauss(PJ_CONTEXT *ctx, PJ_LP elp, const void *data) { |
83 | 0 | const struct GAUSS *en = (const struct GAUSS *)data; |
84 | 0 | PJ_LP slp; |
85 | 0 | (void)ctx; |
86 | |
|
87 | 0 | slp.phi = 2. * atan(en->K * pow(tan(.5 * elp.phi + M_FORTPI), en->C) * |
88 | 0 | srat(en->e * sin(elp.phi), en->ratexp)) - |
89 | 0 | M_HALFPI; |
90 | 0 | slp.lam = en->C * (elp.lam); |
91 | 0 | return (slp); |
92 | 0 | } |
93 | | |
94 | 0 | PJ_LP pj_inv_gauss(PJ_CONTEXT *ctx, PJ_LP slp, const void *data) { |
95 | 0 | const struct GAUSS *en = (const struct GAUSS *)data; |
96 | 0 | PJ_LP elp; |
97 | 0 | double num; |
98 | 0 | int i; |
99 | |
|
100 | 0 | elp.lam = slp.lam / en->C; |
101 | 0 | num = pow(tan(.5 * slp.phi + M_FORTPI) / en->K, 1. / en->C); |
102 | 0 | for (i = MAX_ITER; i; --i) { |
103 | 0 | elp.phi = |
104 | 0 | 2. * atan(num * srat(en->e * sin(slp.phi), -.5 * en->e)) - M_HALFPI; |
105 | 0 | if (fabs(elp.phi - slp.phi) < DEL_TOL) |
106 | 0 | break; |
107 | 0 | slp.phi = elp.phi; |
108 | 0 | } |
109 | | /* convergence failed */ |
110 | 0 | if (!i) |
111 | 0 | proj_context_errno_set( |
112 | 0 | ctx, PROJ_ERR_COORD_TRANSFM_OUTSIDE_PROJECTION_DOMAIN); |
113 | 0 | return (elp); |
114 | 0 | } |