]>
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 | ||
92f5a8d4 TL |
5 | // This file was modified by Oracle on 2017, 2018, 2019. |
6 | // Modifications copyright (c) 2017-2019, 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 | ||
11fdf7f2 | 47 | #include <boost/config.hpp> |
11fdf7f2 | 48 | |
92f5a8d4 TL |
49 | #include <boost/geometry/formulas/vincenty_direct.hpp> |
50 | #include <boost/geometry/formulas/vincenty_inverse.hpp> | |
51 | ||
52 | #include <boost/geometry/srs/projections/impl/aasincos.hpp> | |
11fdf7f2 TL |
53 | #include <boost/geometry/srs/projections/impl/base_static.hpp> |
54 | #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> | |
11fdf7f2 | 55 | #include <boost/geometry/srs/projections/impl/factory_entry.hpp> |
11fdf7f2 | 56 | #include <boost/geometry/srs/projections/impl/pj_mlfn.hpp> |
92f5a8d4 TL |
57 | #include <boost/geometry/srs/projections/impl/pj_param.hpp> |
58 | #include <boost/geometry/srs/projections/impl/projects.hpp> | |
59 | ||
60 | #include <boost/geometry/util/math.hpp> | |
11fdf7f2 | 61 | |
92f5a8d4 | 62 | #include <boost/math/special_functions/hypot.hpp> |
11fdf7f2 TL |
63 | |
64 | #include <boost/type_traits/is_same.hpp> | |
65 | ||
66 | namespace boost { namespace geometry | |
67 | { | |
68 | ||
11fdf7f2 TL |
69 | namespace projections |
70 | { | |
71 | #ifndef DOXYGEN_NO_DETAIL | |
72 | namespace detail { namespace aeqd | |
73 | { | |
74 | ||
92f5a8d4 TL |
75 | static const double epsilon10 = 1.e-10; |
76 | static const double tolerance = 1.e-14; | |
77 | enum mode_type { | |
78 | n_pole = 0, | |
79 | s_pole = 1, | |
80 | equit = 2, | |
81 | obliq = 3 | |
82 | }; | |
11fdf7f2 TL |
83 | |
84 | template <typename T> | |
85 | struct par_aeqd | |
86 | { | |
87 | T sinph0; | |
88 | T cosph0; | |
92f5a8d4 | 89 | detail::en<T> en; |
11fdf7f2 | 90 | T M1; |
92f5a8d4 | 91 | //T N1; |
11fdf7f2 | 92 | T Mp; |
92f5a8d4 TL |
93 | //T He; |
94 | //T G; | |
95 | T b; | |
96 | mode_type mode; | |
11fdf7f2 TL |
97 | }; |
98 | ||
99 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 100 | 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 | 101 | { |
92f5a8d4 TL |
102 | T coslam, cosphi, sinphi, rho; |
103 | //T azi1, s12; | |
104 | //T lam1, phi1, lam2, phi2; | |
11fdf7f2 TL |
105 | |
106 | coslam = cos(lp_lon); | |
107 | cosphi = cos(lp_lat); | |
108 | sinphi = sin(lp_lat); | |
109 | switch (proj_parm.mode) { | |
92f5a8d4 | 110 | case n_pole: |
11fdf7f2 TL |
111 | coslam = - coslam; |
112 | BOOST_FALLTHROUGH; | |
92f5a8d4 | 113 | case s_pole: |
11fdf7f2 TL |
114 | xy_x = (rho = fabs(proj_parm.Mp - pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en))) * |
115 | sin(lp_lon); | |
116 | xy_y = rho * coslam; | |
117 | break; | |
92f5a8d4 TL |
118 | case equit: |
119 | case obliq: | |
120 | if (fabs(lp_lon) < epsilon10 && fabs(lp_lat - par.phi0) < epsilon10) { | |
11fdf7f2 TL |
121 | xy_x = xy_y = 0.; |
122 | break; | |
123 | } | |
92f5a8d4 TL |
124 | |
125 | //phi1 = par.phi0; lam1 = par.lam0; | |
126 | //phi2 = lp_lat; lam2 = lp_lon + par.lam0; | |
127 | ||
128 | formula::result_inverse<T> const inv = | |
129 | formula::vincenty_inverse | |
130 | < | |
131 | T, true, true | |
132 | >::apply(par.lam0, par.phi0, lp_lon + par.lam0, lp_lat, srs::spheroid<T>(par.a, proj_parm.b)); | |
133 | //azi1 = inv.azimuth; s12 = inv.distance; | |
134 | xy_x = inv.distance * sin(inv.azimuth) / par.a; | |
135 | xy_y = inv.distance * cos(inv.azimuth) / par.a; | |
11fdf7f2 TL |
136 | break; |
137 | } | |
138 | } | |
139 | ||
140 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 141 | 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 | 142 | { |
92f5a8d4 | 143 | T c; |
11fdf7f2 | 144 | |
92f5a8d4 | 145 | if ((c = boost::math::hypot(xy_x, xy_y)) < epsilon10) { |
11fdf7f2 TL |
146 | lp_lat = par.phi0; |
147 | lp_lon = 0.; | |
148 | return; | |
149 | } | |
92f5a8d4 TL |
150 | if (proj_parm.mode == obliq || proj_parm.mode == equit) { |
151 | T const x2 = xy_x * par.a; | |
152 | T const y2 = xy_y * par.a; | |
153 | //T const lat1 = par.phi0; | |
154 | //T const lon1 = par.lam0; | |
155 | T const azi1 = atan2(x2, y2); | |
156 | T const s12 = sqrt(x2 * x2 + y2 * y2); | |
157 | formula::result_direct<T> const dir = | |
158 | formula::vincenty_direct | |
159 | < | |
160 | T, true | |
161 | >::apply(par.lam0, par.phi0, s12, azi1, srs::spheroid<T>(par.a, proj_parm.b)); | |
162 | lp_lat = dir.lat2; | |
163 | lp_lon = dir.lon2; | |
164 | lp_lon -= par.lam0; | |
11fdf7f2 | 165 | } else { /* Polar */ |
92f5a8d4 | 166 | lp_lat = pj_inv_mlfn(proj_parm.mode == n_pole ? proj_parm.Mp - c : proj_parm.Mp + c, |
11fdf7f2 | 167 | par.es, proj_parm.en); |
92f5a8d4 | 168 | lp_lon = atan2(xy_x, proj_parm.mode == n_pole ? -xy_y : xy_y); |
11fdf7f2 TL |
169 | } |
170 | } | |
171 | ||
172 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 173 | 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 |
174 | { |
175 | T cosphi, sinphi, t; | |
176 | ||
177 | cosphi = cos(lp_lat); | |
178 | sinphi = sin(lp_lat); | |
179 | t = 1. / sqrt(1. - par.es * sinphi * sinphi); | |
180 | xy_x = lp_lon * cosphi * t; | |
181 | xy_y = pj_mlfn(lp_lat, sinphi, cosphi, proj_parm.en) - proj_parm.M1 + | |
182 | .5 * lp_lon * lp_lon * cosphi * sinphi * t; | |
183 | } | |
184 | ||
185 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 186 | 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 | 187 | { |
92f5a8d4 | 188 | T x2, t = 0.0; |
11fdf7f2 TL |
189 | int i; |
190 | ||
191 | x2 = 0.5 * xy_x * xy_x; | |
192 | lp_lat = par.phi0; | |
193 | for (i = 0; i < 3; ++i) { | |
194 | t = par.e * sin(lp_lat); | |
195 | lp_lat = pj_inv_mlfn(proj_parm.M1 + xy_y - | |
196 | x2 * tan(lp_lat) * (t = sqrt(1. - t * t)), par.es, proj_parm.en); | |
197 | } | |
198 | lp_lon = xy_x * t / cos(lp_lat); | |
199 | } | |
200 | ||
201 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 202 | 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 | 203 | { |
92f5a8d4 | 204 | static const T half_pi = detail::half_pi<T>(); |
11fdf7f2 TL |
205 | |
206 | T coslam, cosphi, sinphi; | |
207 | ||
208 | sinphi = sin(lp_lat); | |
209 | cosphi = cos(lp_lat); | |
210 | coslam = cos(lp_lon); | |
211 | switch (proj_parm.mode) { | |
92f5a8d4 | 212 | case equit: |
11fdf7f2 TL |
213 | xy_y = cosphi * coslam; |
214 | goto oblcon; | |
92f5a8d4 | 215 | case obliq: |
11fdf7f2 TL |
216 | xy_y = proj_parm.sinph0 * sinphi + proj_parm.cosph0 * cosphi * coslam; |
217 | oblcon: | |
92f5a8d4 | 218 | if (fabs(fabs(xy_y) - 1.) < tolerance) |
11fdf7f2 | 219 | if (xy_y < 0.) |
92f5a8d4 | 220 | BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); |
11fdf7f2 TL |
221 | else |
222 | xy_x = xy_y = 0.; | |
223 | else { | |
224 | xy_y = acos(xy_y); | |
225 | xy_y /= sin(xy_y); | |
226 | xy_x = xy_y * cosphi * sin(lp_lon); | |
92f5a8d4 | 227 | xy_y *= (proj_parm.mode == equit) ? sinphi : |
11fdf7f2 TL |
228 | proj_parm.cosph0 * sinphi - proj_parm.sinph0 * cosphi * coslam; |
229 | } | |
230 | break; | |
92f5a8d4 | 231 | case n_pole: |
11fdf7f2 TL |
232 | lp_lat = -lp_lat; |
233 | coslam = -coslam; | |
234 | BOOST_FALLTHROUGH; | |
92f5a8d4 TL |
235 | case s_pole: |
236 | if (fabs(lp_lat - half_pi) < epsilon10) | |
237 | BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); | |
238 | xy_x = (xy_y = (half_pi + lp_lat)) * sin(lp_lon); | |
11fdf7f2 TL |
239 | xy_y *= coslam; |
240 | break; | |
241 | } | |
242 | } | |
243 | ||
244 | template <typename T, typename Par, typename ProjParm> | |
92f5a8d4 | 245 | inline void s_inverse(T xy_x, T xy_y, T& lp_lon, T& lp_lat, Par const& par, ProjParm const& proj_parm) |
11fdf7f2 | 246 | { |
92f5a8d4 TL |
247 | static const T pi = detail::pi<T>(); |
248 | static const T half_pi = detail::half_pi<T>(); | |
11fdf7f2 TL |
249 | |
250 | T cosc, c_rh, sinc; | |
251 | ||
92f5a8d4 TL |
252 | if ((c_rh = boost::math::hypot(xy_x, xy_y)) > pi) { |
253 | if (c_rh - epsilon10 > pi) | |
254 | BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); | |
255 | c_rh = pi; | |
256 | } else if (c_rh < epsilon10) { | |
11fdf7f2 TL |
257 | lp_lat = par.phi0; |
258 | lp_lon = 0.; | |
259 | return; | |
260 | } | |
92f5a8d4 | 261 | if (proj_parm.mode == obliq || proj_parm.mode == equit) { |
11fdf7f2 TL |
262 | sinc = sin(c_rh); |
263 | cosc = cos(c_rh); | |
92f5a8d4 | 264 | if (proj_parm.mode == equit) { |
11fdf7f2 TL |
265 | lp_lat = aasin(xy_y * sinc / c_rh); |
266 | xy_x *= sinc; | |
267 | xy_y = cosc * c_rh; | |
268 | } else { | |
269 | lp_lat = aasin(cosc * proj_parm.sinph0 + xy_y * sinc * proj_parm.cosph0 / | |
270 | c_rh); | |
271 | xy_y = (cosc - proj_parm.sinph0 * sin(lp_lat)) * c_rh; | |
272 | xy_x *= sinc * proj_parm.cosph0; | |
273 | } | |
92f5a8d4 TL |
274 | lp_lon = xy_y == 0. ? 0. : atan2(xy_x, xy_y); |
275 | } else if (proj_parm.mode == n_pole) { | |
276 | lp_lat = half_pi - c_rh; | |
11fdf7f2 TL |
277 | lp_lon = atan2(xy_x, -xy_y); |
278 | } else { | |
92f5a8d4 | 279 | lp_lat = c_rh - half_pi; |
11fdf7f2 TL |
280 | lp_lon = atan2(xy_x, xy_y); |
281 | } | |
282 | } | |
283 | ||
284 | // Azimuthal Equidistant | |
92f5a8d4 TL |
285 | template <typename Params, typename Parameters, typename T> |
286 | inline void setup_aeqd(Params const& params, Parameters& par, par_aeqd<T>& proj_parm, bool is_sphere, bool is_guam) | |
11fdf7f2 | 287 | { |
92f5a8d4 | 288 | static const T half_pi = detail::half_pi<T>(); |
11fdf7f2 | 289 | |
92f5a8d4 TL |
290 | par.phi0 = pj_get_param_r<T, srs::spar::lat_0>(params, "lat_0", srs::dpar::lat_0); |
291 | if (fabs(fabs(par.phi0) - half_pi) < epsilon10) { | |
292 | proj_parm.mode = par.phi0 < 0. ? s_pole : n_pole; | |
11fdf7f2 TL |
293 | proj_parm.sinph0 = par.phi0 < 0. ? -1. : 1.; |
294 | proj_parm.cosph0 = 0.; | |
92f5a8d4 TL |
295 | } else if (fabs(par.phi0) < epsilon10) { |
296 | proj_parm.mode = equit; | |
11fdf7f2 TL |
297 | proj_parm.sinph0 = 0.; |
298 | proj_parm.cosph0 = 1.; | |
299 | } else { | |
92f5a8d4 | 300 | proj_parm.mode = obliq; |
11fdf7f2 TL |
301 | proj_parm.sinph0 = sin(par.phi0); |
302 | proj_parm.cosph0 = cos(par.phi0); | |
303 | } | |
304 | if (is_sphere) { | |
92f5a8d4 | 305 | /* empty */ |
11fdf7f2 | 306 | } else { |
92f5a8d4 | 307 | proj_parm.en = pj_enfn<T>(par.es); |
11fdf7f2 TL |
308 | if (is_guam) { |
309 | proj_parm.M1 = pj_mlfn(par.phi0, proj_parm.sinph0, proj_parm.cosph0, proj_parm.en); | |
310 | } else { | |
311 | switch (proj_parm.mode) { | |
92f5a8d4 TL |
312 | case n_pole: |
313 | proj_parm.Mp = pj_mlfn<T>(half_pi, 1., 0., proj_parm.en); | |
11fdf7f2 | 314 | break; |
92f5a8d4 TL |
315 | case s_pole: |
316 | proj_parm.Mp = pj_mlfn<T>(-half_pi, -1., 0., proj_parm.en); | |
11fdf7f2 | 317 | break; |
92f5a8d4 TL |
318 | case equit: |
319 | case obliq: | |
320 | //proj_parm.N1 = 1. / sqrt(1. - par.es * proj_parm.sinph0 * proj_parm.sinph0); | |
321 | //proj_parm.G = proj_parm.sinph0 * (proj_parm.He = par.e / sqrt(par.one_es)); | |
322 | //proj_parm.He *= proj_parm.cosph0; | |
11fdf7f2 TL |
323 | break; |
324 | } | |
92f5a8d4 TL |
325 | // Boost.Geometry specific, in proj4 geodesic is initialized at the beginning |
326 | proj_parm.b = math::sqrt(math::sqr(par.a) * (1. - par.es)); | |
11fdf7f2 TL |
327 | } |
328 | } | |
329 | } | |
330 | ||
92f5a8d4 TL |
331 | template <typename T, typename Parameters> |
332 | struct base_aeqd_e | |
11fdf7f2 | 333 | { |
92f5a8d4 | 334 | par_aeqd<T> m_proj_parm; |
11fdf7f2 TL |
335 | |
336 | // FORWARD(e_forward) elliptical | |
337 | // Project coordinates from geographic (lon, lat) to cartesian (x, y) | |
92f5a8d4 | 338 | inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const |
11fdf7f2 | 339 | { |
92f5a8d4 | 340 | e_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); |
11fdf7f2 TL |
341 | } |
342 | ||
343 | // INVERSE(e_inverse) elliptical | |
344 | // Project coordinates from cartesian (x, y) to geographic (lon, lat) | |
92f5a8d4 | 345 | inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const |
11fdf7f2 | 346 | { |
92f5a8d4 | 347 | e_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); |
11fdf7f2 TL |
348 | } |
349 | ||
350 | static inline std::string get_name() | |
351 | { | |
352 | return "aeqd_e"; | |
353 | } | |
354 | ||
355 | }; | |
356 | ||
92f5a8d4 TL |
357 | template <typename T, typename Parameters> |
358 | struct base_aeqd_e_guam | |
11fdf7f2 | 359 | { |
92f5a8d4 | 360 | par_aeqd<T> m_proj_parm; |
11fdf7f2 TL |
361 | |
362 | // FORWARD(e_guam_fwd) Guam elliptical | |
363 | // Project coordinates from geographic (lon, lat) to cartesian (x, y) | |
92f5a8d4 | 364 | inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const |
11fdf7f2 | 365 | { |
92f5a8d4 | 366 | e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); |
11fdf7f2 TL |
367 | } |
368 | ||
369 | // INVERSE(e_guam_inv) Guam elliptical | |
370 | // Project coordinates from cartesian (x, y) to geographic (lon, lat) | |
92f5a8d4 | 371 | inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const |
11fdf7f2 | 372 | { |
92f5a8d4 | 373 | e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); |
11fdf7f2 TL |
374 | } |
375 | ||
376 | static inline std::string get_name() | |
377 | { | |
378 | return "aeqd_e_guam"; | |
379 | } | |
380 | ||
381 | }; | |
382 | ||
92f5a8d4 TL |
383 | template <typename T, typename Parameters> |
384 | struct base_aeqd_s | |
11fdf7f2 | 385 | { |
92f5a8d4 | 386 | par_aeqd<T> m_proj_parm; |
11fdf7f2 TL |
387 | |
388 | // FORWARD(s_forward) spherical | |
389 | // Project coordinates from geographic (lon, lat) to cartesian (x, y) | |
92f5a8d4 | 390 | inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const |
11fdf7f2 | 391 | { |
92f5a8d4 | 392 | s_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); |
11fdf7f2 TL |
393 | } |
394 | ||
395 | // INVERSE(s_inverse) spherical | |
396 | // Project coordinates from cartesian (x, y) to geographic (lon, lat) | |
92f5a8d4 | 397 | inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const |
11fdf7f2 | 398 | { |
92f5a8d4 | 399 | s_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); |
11fdf7f2 TL |
400 | } |
401 | ||
402 | static inline std::string get_name() | |
403 | { | |
404 | return "aeqd_s"; | |
405 | } | |
406 | ||
407 | }; | |
408 | ||
409 | }} // namespace detail::aeqd | |
410 | #endif // doxygen | |
411 | ||
412 | /*! | |
413 | \brief Azimuthal Equidistant projection | |
414 | \ingroup projections | |
415 | \tparam Geographic latlong point type | |
416 | \tparam Cartesian xy point type | |
417 | \tparam Parameters parameter type | |
418 | \par Projection characteristics | |
419 | - Azimuthal | |
420 | - Spheroid | |
421 | - Ellipsoid | |
422 | \par Projection parameters | |
423 | - lat_0: Latitude of origin (degrees) | |
424 | - guam (boolean) | |
425 | \par Example | |
426 | \image html ex_aeqd.gif | |
427 | */ | |
92f5a8d4 TL |
428 | template <typename T, typename Parameters> |
429 | struct aeqd_e : public detail::aeqd::base_aeqd_e<T, Parameters> | |
11fdf7f2 | 430 | { |
92f5a8d4 TL |
431 | template <typename Params> |
432 | inline aeqd_e(Params const& params, Parameters & par) | |
11fdf7f2 | 433 | { |
92f5a8d4 | 434 | detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, false, false); |
11fdf7f2 TL |
435 | } |
436 | }; | |
437 | ||
438 | /*! | |
439 | \brief Azimuthal Equidistant projection | |
440 | \ingroup projections | |
441 | \tparam Geographic latlong point type | |
442 | \tparam Cartesian xy point type | |
443 | \tparam Parameters parameter type | |
444 | \par Projection characteristics | |
445 | - Azimuthal | |
446 | - Spheroid | |
447 | - Ellipsoid | |
448 | \par Projection parameters | |
449 | - lat_0: Latitude of origin (degrees) | |
450 | - guam (boolean) | |
451 | \par Example | |
452 | \image html ex_aeqd.gif | |
453 | */ | |
92f5a8d4 TL |
454 | template <typename T, typename Parameters> |
455 | struct aeqd_e_guam : public detail::aeqd::base_aeqd_e_guam<T, Parameters> | |
11fdf7f2 | 456 | { |
92f5a8d4 TL |
457 | template <typename Params> |
458 | inline aeqd_e_guam(Params const& params, Parameters & par) | |
11fdf7f2 | 459 | { |
92f5a8d4 | 460 | detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, false, true); |
11fdf7f2 TL |
461 | } |
462 | }; | |
463 | ||
464 | /*! | |
465 | \brief Azimuthal Equidistant projection | |
466 | \ingroup projections | |
467 | \tparam Geographic latlong point type | |
468 | \tparam Cartesian xy point type | |
469 | \tparam Parameters parameter type | |
470 | \par Projection characteristics | |
471 | - Azimuthal | |
472 | - Spheroid | |
473 | - Ellipsoid | |
474 | \par Projection parameters | |
475 | - lat_0: Latitude of origin (degrees) | |
476 | - guam (boolean) | |
477 | \par Example | |
478 | \image html ex_aeqd.gif | |
479 | */ | |
92f5a8d4 TL |
480 | template <typename T, typename Parameters> |
481 | struct aeqd_s : public detail::aeqd::base_aeqd_s<T, Parameters> | |
11fdf7f2 | 482 | { |
92f5a8d4 TL |
483 | template <typename Params> |
484 | inline aeqd_s(Params const& params, Parameters & par) | |
11fdf7f2 | 485 | { |
92f5a8d4 | 486 | detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, true, false); |
11fdf7f2 TL |
487 | } |
488 | }; | |
489 | ||
490 | #ifndef DOXYGEN_NO_DETAIL | |
491 | namespace detail | |
492 | { | |
493 | ||
494 | // Static projection | |
495 | template <typename BGP, typename CT, typename P> | |
92f5a8d4 | 496 | struct static_projection_type<srs::spar::proj_aeqd, srs_sphere_tag, BGP, CT, P> |
11fdf7f2 | 497 | { |
92f5a8d4 | 498 | typedef static_wrapper_fi<aeqd_s<CT, P>, P> type; |
11fdf7f2 TL |
499 | }; |
500 | template <typename BGP, typename CT, typename P> | |
92f5a8d4 | 501 | struct static_projection_type<srs::spar::proj_aeqd, srs_spheroid_tag, BGP, CT, P> |
11fdf7f2 | 502 | { |
92f5a8d4 TL |
503 | typedef static_wrapper_fi |
504 | < | |
505 | typename boost::mpl::if_c | |
506 | < | |
507 | boost::is_same | |
508 | < | |
509 | typename srs::spar::detail::tuples_find_if | |
510 | < | |
511 | BGP, | |
512 | //srs::par4::detail::is_guam | |
513 | srs::spar::detail::is_param<srs::spar::guam>::pred | |
514 | >::type, | |
515 | void | |
516 | >::value, | |
517 | aeqd_e<CT, P>, | |
518 | aeqd_e_guam<CT, P> | |
519 | >::type | |
520 | , P | |
521 | > type; | |
11fdf7f2 | 522 | }; |
11fdf7f2 | 523 | |
92f5a8d4 | 524 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(aeqd_entry) |
11fdf7f2 | 525 | { |
92f5a8d4 TL |
526 | bool const guam = pj_get_param_b<srs::spar::guam>(params, "guam", srs::dpar::guam); |
527 | ||
528 | if (parameters.es && ! guam) | |
529 | return new dynamic_wrapper_fi<aeqd_e<T, Parameters>, T, Parameters>(params, parameters); | |
530 | else if (parameters.es && guam) | |
531 | return new dynamic_wrapper_fi<aeqd_e_guam<T, Parameters>, T, Parameters>(params, parameters); | |
532 | else | |
533 | return new dynamic_wrapper_fi<aeqd_s<T, Parameters>, T, Parameters>(params, parameters); | |
534 | } | |
535 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END | |
11fdf7f2 | 536 | |
92f5a8d4 | 537 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(aeqd_init) |
11fdf7f2 | 538 | { |
92f5a8d4 | 539 | BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(aeqd, aeqd_entry) |
11fdf7f2 TL |
540 | } |
541 | ||
542 | } // namespace detail | |
543 | #endif // doxygen | |
544 | ||
545 | } // namespace projections | |
546 | ||
547 | }} // namespace boost::geometry | |
548 | ||
549 | #endif // BOOST_GEOMETRY_PROJECTIONS_AEQD_HPP | |
550 |