]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | // Boost.Geometry - gis-projections (based on PROJ4) |
11fdf7f2 TL |
2 | |
3 | // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | ||
20effc67 TL |
5 | // This file was modified by Oracle on 2017-2020. |
6 | // Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. | |
11fdf7f2 TL |
7 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle. |
8 | ||
9 | // Use, modification and distribution is subject to the Boost Software License, | |
10 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
11 | // http://www.boost.org/LICENSE_1_0.txt) | |
12 | ||
13 | // This file is converted from PROJ4, http://trac.osgeo.org/proj | |
14 | // PROJ4 is originally written by Gerald Evenden (then of the USGS) | |
15 | // PROJ4 is maintained by Frank Warmerdam | |
16 | // PROJ4 is converted to Boost.Geometry by Barend Gehrels | |
17 | ||
92f5a8d4 | 18 | // Last updated version of proj: 5.0.0 |
11fdf7f2 TL |
19 | |
20 | // Original copyright notice: | |
21 | ||
22 | // Purpose: Implementation of the aeqd (Azimuthal Equidistant) projection. | |
23 | // Author: Gerald Evenden | |
24 | // Copyright (c) 1995, Gerald Evenden | |
25 | ||
26 | // Permission is hereby granted, free of charge, to any person obtaining a | |
27 | // copy of this software and associated documentation files (the "Software"), | |
28 | // to deal in the Software without restriction, including without limitation | |
29 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
30 | // and/or sell copies of the Software, and to permit persons to whom the | |
31 | // Software is furnished to do so, subject to the following conditions: | |
32 | ||
33 | // The above copyright notice and this permission notice shall be included | |
34 | // in all copies or substantial portions of the Software. | |
35 | ||
36 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
37 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
38 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
39 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
40 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
41 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
42 | // DEALINGS IN THE SOFTWARE. | |
43 | ||
92f5a8d4 TL |
44 | #ifndef BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP |
45 | #define BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP | |
46 | ||
20effc67 TL |
47 | |
48 | #include <type_traits> | |
49 | ||
11fdf7f2 | 50 | #include <boost/config.hpp> |
11fdf7f2 | 51 | |
92f5a8d4 TL |
52 | #include <boost/geometry/formulas/vincenty_direct.hpp> |
53 | #include <boost/geometry/formulas/vincenty_inverse.hpp> | |
54 | ||
55 | #include <boost/geometry/srs/projections/impl/aasincos.hpp> | |
11fdf7f2 TL |
56 | #include <boost/geometry/srs/projections/impl/base_static.hpp> |
57 | #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> | |
11fdf7f2 | 58 | #include <boost/geometry/srs/projections/impl/factory_entry.hpp> |
11fdf7f2 | 59 | #include <boost/geometry/srs/projections/impl/pj_mlfn.hpp> |
92f5a8d4 TL |
60 | #include <boost/geometry/srs/projections/impl/pj_param.hpp> |
61 | #include <boost/geometry/srs/projections/impl/projects.hpp> | |
62 | ||
63 | #include <boost/geometry/util/math.hpp> | |
11fdf7f2 | 64 | |
92f5a8d4 | 65 | #include <boost/math/special_functions/hypot.hpp> |
11fdf7f2 | 66 | |
11fdf7f2 TL |
67 | |
68 | namespace boost { namespace geometry | |
69 | { | |
70 | ||
11fdf7f2 TL |
71 | namespace projections |
72 | { | |
73 | #ifndef DOXYGEN_NO_DETAIL | |
74 | namespace detail { namespace aeqd | |
75 | { | |
76 | ||
92f5a8d4 TL |
77 | static const double epsilon10 = 1.e-10; |
78 | static const double tolerance = 1.e-14; | |
79 | enum mode_type { | |
80 | n_pole = 0, | |
81 | s_pole = 1, | |
82 | equit = 2, | |
83 | obliq = 3 | |
84 | }; | |
11fdf7f2 TL |
85 | |
86 | template <typename T> | |
87 | struct par_aeqd | |
88 | { | |
89 | T sinph0; | |
90 | T cosph0; | |
92f5a8d4 | 91 | detail::en<T> en; |
11fdf7f2 | 92 | T M1; |
92f5a8d4 | 93 | //T N1; |
11fdf7f2 | 94 | T Mp; |
92f5a8d4 TL |
95 | //T He; |
96 | //T G; | |
97 | T b; | |
98 | mode_type mode; | |
11fdf7f2 TL |
99 | }; |
100 | ||
101 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 102 | inline void e_forward(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y, Par const& par, ProjParm const& proj_parm) |
11fdf7f2 | 103 | { |
92f5a8d4 TL |
104 | T coslam, cosphi, sinphi, rho; |
105 | //T azi1, s12; | |
106 | //T lam1, phi1, lam2, phi2; | |
11fdf7f2 TL |
107 | |
108 | coslam = cos(lp_lon); | |
109 | cosphi = cos(lp_lat); | |
110 | sinphi = sin(lp_lat); | |
111 | switch (proj_parm.mode) { | |
92f5a8d4 | 112 | case n_pole: |
11fdf7f2 TL |
113 | coslam = - coslam; |
114 | BOOST_FALLTHROUGH; | |
92f5a8d4 | 115 | case s_pole: |
11fdf7f2 TL |
116 | xy_x = (rho = fabs(proj_parm.Mp - pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en))) * |
117 | sin(lp_lon); | |
118 | xy_y = rho * coslam; | |
119 | break; | |
92f5a8d4 TL |
120 | case equit: |
121 | case obliq: | |
122 | if (fabs(lp_lon) < epsilon10 && fabs(lp_lat - par.phi0) < epsilon10) { | |
11fdf7f2 TL |
123 | xy_x = xy_y = 0.; |
124 | break; | |
125 | } | |
92f5a8d4 TL |
126 | |
127 | //phi1 = par.phi0; lam1 = par.lam0; | |
128 | //phi2 = lp_lat; lam2 = lp_lon + par.lam0; | |
129 | ||
130 | formula::result_inverse<T> const inv = | |
131 | formula::vincenty_inverse | |
132 | < | |
133 | T, true, true | |
134 | >::apply(par.lam0, par.phi0, lp_lon + par.lam0, lp_lat, srs::spheroid<T>(par.a, proj_parm.b)); | |
135 | //azi1 = inv.azimuth; s12 = inv.distance; | |
136 | xy_x = inv.distance * sin(inv.azimuth) / par.a; | |
137 | xy_y = inv.distance * cos(inv.azimuth) / par.a; | |
11fdf7f2 TL |
138 | break; |
139 | } | |
140 | } | |
141 | ||
142 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 143 | inline void e_inverse(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) |
11fdf7f2 | 144 | { |
92f5a8d4 | 145 | T c; |
11fdf7f2 | 146 | |
92f5a8d4 | 147 | if ((c = boost::math::hypot(xy_x, xy_y)) < epsilon10) { |
11fdf7f2 TL |
148 | lp_lat = par.phi0; |
149 | lp_lon = 0.; | |
150 | return; | |
151 | } | |
92f5a8d4 TL |
152 | if (proj_parm.mode == obliq || proj_parm.mode == equit) { |
153 | T const x2 = xy_x * par.a; | |
154 | T const y2 = xy_y * par.a; | |
155 | //T const lat1 = par.phi0; | |
156 | //T const lon1 = par.lam0; | |
157 | T const azi1 = atan2(x2, y2); | |
158 | T const s12 = sqrt(x2 * x2 + y2 * y2); | |
159 | formula::result_direct<T> const dir = | |
160 | formula::vincenty_direct | |
161 | < | |
162 | T, true | |
163 | >::apply(par.lam0, par.phi0, s12, azi1, srs::spheroid<T>(par.a, proj_parm.b)); | |
164 | lp_lat = dir.lat2; | |
165 | lp_lon = dir.lon2; | |
166 | lp_lon -= par.lam0; | |
11fdf7f2 | 167 | } else { /* Polar */ |
92f5a8d4 | 168 | lp_lat = pj_inv_mlfn(proj_parm.mode == n_pole ? proj_parm.Mp - c : proj_parm.Mp + c, |
11fdf7f2 | 169 | par.es, proj_parm.en); |
92f5a8d4 | 170 | lp_lon = atan2(xy_x, proj_parm.mode == n_pole ? -xy_y : xy_y); |
11fdf7f2 TL |
171 | } |
172 | } | |
173 | ||
174 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 175 | inline void e_guam_fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y, Par const& par, ProjParm const& proj_parm) |
11fdf7f2 TL |
176 | { |
177 | T cosphi, sinphi, t; | |
178 | ||
179 | cosphi = cos(lp_lat); | |
180 | sinphi = sin(lp_lat); | |
181 | t = 1. / sqrt(1. - par.es * sinphi * sinphi); | |
182 | xy_x = lp_lon * cosphi * t; | |
183 | xy_y = pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en) - proj_parm.M1 + | |
184 | .5 * lp_lon * lp_lon * cosphi * sinphi * t; | |
185 | } | |
186 | ||
187 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 188 | inline void e_guam_inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) |
11fdf7f2 | 189 | { |
92f5a8d4 | 190 | T x2, t = 0.0; |
11fdf7f2 TL |
191 | int i; |
192 | ||
193 | x2 = 0.5 * xy_x * xy_x; | |
194 | lp_lat = par.phi0; | |
195 | for (i = 0; i < 3; ++i) { | |
196 | t = par.e * sin(lp_lat); | |
197 | lp_lat = pj_inv_mlfn(proj_parm.M1 + xy_y - | |
198 | x2 * tan(lp_lat) * (t = sqrt(1. - t * t)), par.es, proj_parm.en); | |
199 | } | |
200 | lp_lon = xy_x * t / cos(lp_lat); | |
201 | } | |
202 | ||
203 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 204 | inline void s_forward(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y, Par const& /*par*/, ProjParm const& proj_parm) |
11fdf7f2 | 205 | { |
92f5a8d4 | 206 | static const T half_pi = detail::half_pi<T>(); |
11fdf7f2 TL |
207 | |
208 | T coslam, cosphi, sinphi; | |
209 | ||
210 | sinphi = sin(lp_lat); | |
211 | cosphi = cos(lp_lat); | |
212 | coslam = cos(lp_lon); | |
213 | switch (proj_parm.mode) { | |
92f5a8d4 | 214 | case equit: |
11fdf7f2 TL |
215 | xy_y = cosphi * coslam; |
216 | goto oblcon; | |
92f5a8d4 | 217 | case obliq: |
11fdf7f2 TL |
218 | xy_y = proj_parm.sinph0 * sinphi + proj_parm.cosph0 * cosphi * coslam; |
219 | oblcon: | |
92f5a8d4 | 220 | if (fabs(fabs(xy_y) - 1.) < tolerance) |
11fdf7f2 | 221 | if (xy_y < 0.) |
92f5a8d4 | 222 | BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); |
11fdf7f2 TL |
223 | else |
224 | xy_x = xy_y = 0.; | |
225 | else { | |
226 | xy_y = acos(xy_y); | |
227 | xy_y /= sin(xy_y); | |
228 | xy_x = xy_y * cosphi * sin(lp_lon); | |
92f5a8d4 | 229 | xy_y *= (proj_parm.mode == equit) ? sinphi : |
11fdf7f2 TL |
230 | proj_parm.cosph0 * sinphi - proj_parm.sinph0 * cosphi * coslam; |
231 | } | |
232 | break; | |
92f5a8d4 | 233 | case n_pole: |
11fdf7f2 TL |
234 | lp_lat = -lp_lat; |
235 | coslam = -coslam; | |
236 | BOOST_FALLTHROUGH; | |
92f5a8d4 TL |
237 | case s_pole: |
238 | if (fabs(lp_lat - half_pi) < epsilon10) | |
239 | BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); | |
240 | xy_x = (xy_y = (half_pi + lp_lat)) * sin(lp_lon); | |
11fdf7f2 TL |
241 | xy_y *= coslam; |
242 | break; | |
243 | } | |
244 | } | |
245 | ||
246 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 247 | inline void s_inverse(T xy_x, T xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) |
11fdf7f2 | 248 | { |
92f5a8d4 TL |
249 | static const T pi = detail::pi<T>(); |
250 | static const T half_pi = detail::half_pi<T>(); | |
11fdf7f2 TL |
251 | |
252 | T cosc, c_rh, sinc; | |
253 | ||
92f5a8d4 TL |
254 | if ((c_rh = boost::math::hypot(xy_x, xy_y)) > pi) { |
255 | if (c_rh - epsilon10 > pi) | |
256 | BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); | |
257 | c_rh = pi; | |
258 | } else if (c_rh < epsilon10) { | |
11fdf7f2 TL |
259 | lp_lat = par.phi0; |
260 | lp_lon = 0.; | |
261 | return; | |
262 | } | |
92f5a8d4 | 263 | if (proj_parm.mode == obliq || proj_parm.mode == equit) { |
11fdf7f2 TL |
264 | sinc = sin(c_rh); |
265 | cosc = cos(c_rh); | |
92f5a8d4 | 266 | if (proj_parm.mode == equit) { |
11fdf7f2 TL |
267 | lp_lat = aasin(xy_y * sinc / c_rh); |
268 | xy_x *= sinc; | |
269 | xy_y = cosc * c_rh; | |
270 | } else { | |
271 | lp_lat = aasin(cosc * proj_parm.sinph0 + xy_y * sinc * proj_parm.cosph0 / | |
272 | c_rh); | |
273 | xy_y = (cosc - proj_parm.sinph0 * sin(lp_lat)) * c_rh; | |
274 | xy_x *= sinc * proj_parm.cosph0; | |
275 | } | |
92f5a8d4 TL |
276 | lp_lon = xy_y == 0. ? 0. : atan2(xy_x, xy_y); |
277 | } else if (proj_parm.mode == n_pole) { | |
278 | lp_lat = half_pi - c_rh; | |
11fdf7f2 TL |
279 | lp_lon = atan2(xy_x, -xy_y); |
280 | } else { | |
92f5a8d4 | 281 | lp_lat = c_rh - half_pi; |
11fdf7f2 TL |
282 | lp_lon = atan2(xy_x, xy_y); |
283 | } | |
284 | } | |
285 | ||
286 | // Azimuthal Equidistant | |
92f5a8d4 TL |
287 | template <typename Params, typename Parameters, typename T> |
288 | inline void setup_aeqd(Params const& params, Parameters& par, par_aeqd<T>& proj_parm, bool is_sphere, bool is_guam) | |
11fdf7f2 | 289 | { |
92f5a8d4 | 290 | static const T half_pi = detail::half_pi<T>(); |
11fdf7f2 | 291 | |
92f5a8d4 TL |
292 | par.phi0 = pj_get_param_r<T, srs::spar::lat_0>(params, "lat_0", srs::dpar::lat_0); |
293 | if (fabs(fabs(par.phi0) - half_pi) < epsilon10) { | |
294 | proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; | |
11fdf7f2 TL |
295 | proj_parm.sinph0 = par.phi0 < 0. ? -1. : 1.; |
296 | proj_parm.cosph0 = 0.; | |
92f5a8d4 TL |
297 | } else if (fabs(par.phi0) < epsilon10) { |
298 | proj_parm.mode = equit; | |
11fdf7f2 TL |
299 | proj_parm.sinph0 = 0.; |
300 | proj_parm.cosph0 = 1.; | |
301 | } else { | |
92f5a8d4 | 302 | proj_parm.mode = obliq; |
11fdf7f2 TL |
303 | proj_parm.sinph0 = sin(par.phi0); |
304 | proj_parm.cosph0 = cos(par.phi0); | |
305 | } | |
306 | if (is_sphere) { | |
92f5a8d4 | 307 | /* empty */ |
11fdf7f2 | 308 | } else { |
92f5a8d4 | 309 | proj_parm.en = pj_enfn<T>(par.es); |
11fdf7f2 TL |
310 | if (is_guam) { |
311 | proj_parm.M1 = pj_mlfn(par.phi0, proj_parm.sinph0, proj_parm.cosph0, proj_parm.en); | |
312 | } else { | |
313 | switch (proj_parm.mode) { | |
92f5a8d4 TL |
314 | case n_pole: |
315 | proj_parm.Mp = pj_mlfn<T>(half_pi, 1., 0., proj_parm.en); | |
11fdf7f2 | 316 | break; |
92f5a8d4 TL |
317 | case s_pole: |
318 | proj_parm.Mp = pj_mlfn<T>(-half_pi, -1., 0., proj_parm.en); | |
11fdf7f2 | 319 | break; |
92f5a8d4 TL |
320 | case equit: |
321 | case obliq: | |
322 | //proj_parm.N1 = 1. / sqrt(1. - par.es * proj_parm.sinph0 * proj_parm.sinph0); | |
323 | //proj_parm.G = proj_parm.sinph0 * (proj_parm.He = par.e / sqrt(par.one_es)); | |
324 | //proj_parm.He *= proj_parm.cosph0; | |
11fdf7f2 TL |
325 | break; |
326 | } | |
92f5a8d4 TL |
327 | // Boost.Geometry specific, in proj4 geodesic is initialized at the beginning |
328 | proj_parm.b = math::sqrt(math::sqr(par.a) * (1. - par.es)); | |
11fdf7f2 TL |
329 | } |
330 | } | |
331 | } | |
332 | ||
92f5a8d4 TL |
333 | template <typename T, typename Parameters> |
334 | struct base_aeqd_e | |
11fdf7f2 | 335 | { |
92f5a8d4 | 336 | par_aeqd<T> m_proj_parm; |
11fdf7f2 TL |
337 | |
338 | // FORWARD(e_forward) elliptical | |
339 | // Project coordinates from geographic (lon, lat) to cartesian (x, y) | |
92f5a8d4 | 340 | inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const |
11fdf7f2 | 341 | { |
92f5a8d4 | 342 | e_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); |
11fdf7f2 TL |
343 | } |
344 | ||
345 | // INVERSE(e_inverse) elliptical | |
346 | // Project coordinates from cartesian (x, y) to geographic (lon, lat) | |
92f5a8d4 | 347 | inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const |
11fdf7f2 | 348 | { |
92f5a8d4 | 349 | e_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); |
11fdf7f2 TL |
350 | } |
351 | ||
352 | static inline std::string get_name() | |
353 | { | |
354 | return "aeqd_e"; | |
355 | } | |
356 | ||
357 | }; | |
358 | ||
92f5a8d4 TL |
359 | template <typename T, typename Parameters> |
360 | struct base_aeqd_e_guam | |
11fdf7f2 | 361 | { |
92f5a8d4 | 362 | par_aeqd<T> m_proj_parm; |
11fdf7f2 TL |
363 | |
364 | // FORWARD(e_guam_fwd) Guam elliptical | |
365 | // Project coordinates from geographic (lon, lat) to cartesian (x, y) | |
92f5a8d4 | 366 | inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const |
11fdf7f2 | 367 | { |
92f5a8d4 | 368 | e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); |
11fdf7f2 TL |
369 | } |
370 | ||
371 | // INVERSE(e_guam_inv) Guam elliptical | |
372 | // Project coordinates from cartesian (x, y) to geographic (lon, lat) | |
92f5a8d4 | 373 | inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const |
11fdf7f2 | 374 | { |
92f5a8d4 | 375 | e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); |
11fdf7f2 TL |
376 | } |
377 | ||
378 | static inline std::string get_name() | |
379 | { | |
380 | return "aeqd_e_guam"; | |
381 | } | |
382 | ||
383 | }; | |
384 | ||
92f5a8d4 TL |
385 | template <typename T, typename Parameters> |
386 | struct base_aeqd_s | |
11fdf7f2 | 387 | { |
92f5a8d4 | 388 | par_aeqd<T> m_proj_parm; |
11fdf7f2 TL |
389 | |
390 | // FORWARD(s_forward) spherical | |
391 | // Project coordinates from geographic (lon, lat) to cartesian (x, y) | |
92f5a8d4 | 392 | inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const |
11fdf7f2 | 393 | { |
92f5a8d4 | 394 | s_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); |
11fdf7f2 TL |
395 | } |
396 | ||
397 | // INVERSE(s_inverse) spherical | |
398 | // Project coordinates from cartesian (x, y) to geographic (lon, lat) | |
92f5a8d4 | 399 | inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const |
11fdf7f2 | 400 | { |
92f5a8d4 | 401 | s_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); |
11fdf7f2 TL |
402 | } |
403 | ||
404 | static inline std::string get_name() | |
405 | { | |
406 | return "aeqd_s"; | |
407 | } | |
408 | ||
409 | }; | |
410 | ||
411 | }} // namespace detail::aeqd | |
412 | #endif // doxygen | |
413 | ||
414 | /*! | |
415 | \brief Azimuthal Equidistant projection | |
416 | \ingroup projections | |
417 | \tparam Geographic latlong point type | |
418 | \tparam Cartesian xy point type | |
419 | \tparam Parameters parameter type | |
420 | \par Projection characteristics | |
421 | - Azimuthal | |
422 | - Spheroid | |
423 | - Ellipsoid | |
424 | \par Projection parameters | |
425 | - lat_0: Latitude of origin (degrees) | |
426 | - guam (boolean) | |
427 | \par Example | |
428 | \image html ex_aeqd.gif | |
429 | */ | |
92f5a8d4 TL |
430 | template <typename T, typename Parameters> |
431 | struct aeqd_e : public detail::aeqd::base_aeqd_e<T, Parameters> | |
11fdf7f2 | 432 | { |
92f5a8d4 TL |
433 | template <typename Params> |
434 | inline aeqd_e(Params const& params, Parameters & par) | |
11fdf7f2 | 435 | { |
92f5a8d4 | 436 | detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, false, false); |
11fdf7f2 TL |
437 | } |
438 | }; | |
439 | ||
440 | /*! | |
441 | \brief Azimuthal Equidistant projection | |
442 | \ingroup projections | |
443 | \tparam Geographic latlong point type | |
444 | \tparam Cartesian xy point type | |
445 | \tparam Parameters parameter type | |
446 | \par Projection characteristics | |
447 | - Azimuthal | |
448 | - Spheroid | |
449 | - Ellipsoid | |
450 | \par Projection parameters | |
451 | - lat_0: Latitude of origin (degrees) | |
452 | - guam (boolean) | |
453 | \par Example | |
454 | \image html ex_aeqd.gif | |
455 | */ | |
92f5a8d4 TL |
456 | template <typename T, typename Parameters> |
457 | struct aeqd_e_guam : public detail::aeqd::base_aeqd_e_guam<T, Parameters> | |
11fdf7f2 | 458 | { |
92f5a8d4 TL |
459 | template <typename Params> |
460 | inline aeqd_e_guam(Params const& params, Parameters & par) | |
11fdf7f2 | 461 | { |
92f5a8d4 | 462 | detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, false, true); |
11fdf7f2 TL |
463 | } |
464 | }; | |
465 | ||
466 | /*! | |
467 | \brief Azimuthal Equidistant projection | |
468 | \ingroup projections | |
469 | \tparam Geographic latlong point type | |
470 | \tparam Cartesian xy point type | |
471 | \tparam Parameters parameter type | |
472 | \par Projection characteristics | |
473 | - Azimuthal | |
474 | - Spheroid | |
475 | - Ellipsoid | |
476 | \par Projection parameters | |
477 | - lat_0: Latitude of origin (degrees) | |
478 | - guam (boolean) | |
479 | \par Example | |
480 | \image html ex_aeqd.gif | |
481 | */ | |
92f5a8d4 TL |
482 | template <typename T, typename Parameters> |
483 | struct aeqd_s : public detail::aeqd::base_aeqd_s<T, Parameters> | |
11fdf7f2 | 484 | { |
92f5a8d4 TL |
485 | template <typename Params> |
486 | inline aeqd_s(Params const& params, Parameters & par) | |
11fdf7f2 | 487 | { |
92f5a8d4 | 488 | detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, true, false); |
11fdf7f2 TL |
489 | } |
490 | }; | |
491 | ||
492 | #ifndef DOXYGEN_NO_DETAIL | |
493 | namespace detail | |
494 | { | |
495 | ||
496 | // Static projection | |
497 | template <typename BGP, typename CT, typename P> | |
92f5a8d4 | 498 | struct static_projection_type<srs::spar::proj_aeqd, srs_sphere_tag, BGP, CT, P> |
11fdf7f2 | 499 | { |
92f5a8d4 | 500 | typedef static_wrapper_fi<aeqd_s<CT, P>, P> type; |
11fdf7f2 TL |
501 | }; |
502 | template <typename BGP, typename CT, typename P> | |
92f5a8d4 | 503 | struct static_projection_type<srs::spar::proj_aeqd, srs_spheroid_tag, BGP, CT, P> |
11fdf7f2 | 504 | { |
92f5a8d4 TL |
505 | typedef static_wrapper_fi |
506 | < | |
20effc67 | 507 | std::conditional_t |
92f5a8d4 | 508 | < |
20effc67 | 509 | std::is_void |
92f5a8d4 | 510 | < |
f67539c2 | 511 | typename geometry::tuples::find_if |
92f5a8d4 TL |
512 | < |
513 | BGP, | |
514 | //srs::par4::detail::is_guam | |
515 | srs::spar::detail::is_param<srs::spar::guam>::pred | |
20effc67 | 516 | >::type |
92f5a8d4 TL |
517 | >::value, |
518 | aeqd_e<CT, P>, | |
519 | aeqd_e_guam<CT, P> | |
20effc67 | 520 | > |
92f5a8d4 TL |
521 | , P |
522 | > type; | |
11fdf7f2 | 523 | }; |
11fdf7f2 | 524 | |
92f5a8d4 | 525 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(aeqd_entry) |
11fdf7f2 | 526 | { |
92f5a8d4 TL |
527 | bool const guam = pj_get_param_b<srs::spar::guam>(params, "guam", srs::dpar::guam); |
528 | ||
529 | if (parameters.es && ! guam) | |
530 | return new dynamic_wrapper_fi<aeqd_e<T, Parameters>, T, Parameters>(params, parameters); | |
531 | else if (parameters.es && guam) | |
532 | return new dynamic_wrapper_fi<aeqd_e_guam<T, Parameters>, T, Parameters>(params, parameters); | |
533 | else | |
534 | return new dynamic_wrapper_fi<aeqd_s<T, Parameters>, T, Parameters>(params, parameters); | |
535 | } | |
536 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END | |
11fdf7f2 | 537 | |
92f5a8d4 | 538 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(aeqd_init) |
11fdf7f2 | 539 | { |
92f5a8d4 | 540 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(aeqd, aeqd_entry) |
11fdf7f2 TL |
541 | } |
542 | ||
543 | } // namespace detail | |
544 | #endif // doxygen | |
545 | ||
546 | } // namespace projections | |
547 | ||
548 | }} // namespace boost::geometry | |
549 | ||
550 | #endif // BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP | |
551 |