]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/srs/projections/proj/ob_tran.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / geometry / srs / projections / proj / ob_tran.hpp
1 #ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
2 #define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
3
4 // Boost.Geometry - extensions-gis-projections (based on PROJ4)
5 // This file is automatically generated. DO NOT EDIT.
6
7 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
8
9 // This file was modified by Oracle on 2017, 2018.
10 // Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
12
13 // Use, modification and distribution is subject to the Boost Software License,
14 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15 // http://www.boost.org/LICENSE_1_0.txt)
16
17 // This file is converted from PROJ4, http://trac.osgeo.org/proj
18 // PROJ4 is originally written by Gerald Evenden (then of the USGS)
19 // PROJ4 is maintained by Frank Warmerdam
20 // PROJ4 is converted to Boost.Geometry by Barend Gehrels
21
22 // Last updated version of proj: 4.9.1
23
24 // Original copyright notice:
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
44 #include <boost/geometry/util/math.hpp>
45 #include <boost/shared_ptr.hpp>
46
47 #include <boost/geometry/srs/projections/impl/base_static.hpp>
48 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
49 #include <boost/geometry/srs/projections/impl/projects.hpp>
50 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
51 #include <boost/geometry/srs/projections/impl/aasincos.hpp>
52
53 namespace boost { namespace geometry
54 {
55
56 namespace srs { namespace par4
57 {
58 //struct ob_tran_oblique {};
59 //struct ob_tran_transverse {};
60 struct ob_tran {};
61
62 }} //namespace srs::par4
63
64 namespace projections
65 {
66 #ifndef DOXYGEN_NO_DETAIL
67 namespace detail {
68
69 // fwd declaration needed below
70 template <typename CalculationType>
71 inline detail::base_v<CalculationType, parameters<CalculationType> >*
72 create_new(parameters<CalculationType> const& parameters);
73
74 } // namespace detail
75
76 namespace detail { namespace ob_tran
77 {
78
79 static const double TOL = 1e-10;
80
81 template <typename Parameters>
82 inline Parameters o_proj_parameters(Parameters const& par)
83 {
84 Parameters pj;
85
86 /* get name of projection to be translated */
87 pj.name = pj_param(par.params, "so_proj").s;
88 /* copy existing header into new */
89 pj.params = par.params;
90 pj.over = par.over;
91 pj.geoc = par.geoc;
92 pj.a = par.a;
93 pj.es = par.es;
94 pj.ra = par.ra;
95 pj.lam0 = par.lam0;
96 pj.phi0 = par.phi0;
97 pj.x0 = par.x0;
98 pj.y0 = par.y0;
99 pj.k0 = par.k0;
100 /* force spherical earth */
101 pj.one_es = pj.rone_es = 1.;
102 pj.es = pj.e = 0.;
103
104 return pj;
105 }
106
107 template <typename CalculationType, typename Parameters>
108 struct par_ob_tran
109 {
110 par_ob_tran(Parameters const& par)
111 : link(projections::detail::create_new(o_proj_parameters(par)))
112 {
113 if (! link.get())
114 BOOST_THROW_EXCEPTION( projection_exception(-26) );
115 }
116
117 template <typename T>
118 inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const
119 {
120 link->fwd(lp_lon, lp_lat, xy_x, xy_y);
121 }
122
123 template <typename T>
124 inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const
125 {
126 link->inv(xy_x, xy_y, lp_lon, lp_lat);
127 }
128
129 boost::shared_ptr<base_v<CalculationType, Parameters> > link;
130 CalculationType lamp;
131 CalculationType cphip, sphip;
132 };
133
134 template <typename StaticParameters, typename CalculationType, typename Parameters>
135 struct par_ob_tran_static
136 {
137 typedef typename srs::par4::detail::pick_o_proj_tag
138 <
139 StaticParameters
140 >::type o_proj_tag;
141
142 typedef typename projections::detail::static_projection_type
143 <
144 o_proj_tag,
145 srs_sphere_tag, // force spherical
146 StaticParameters,
147 CalculationType,
148 Parameters
149 >::type projection_type;
150
151 par_ob_tran_static(Parameters const& par)
152 : link(o_proj_parameters(par))
153 {}
154
155 template <typename T>
156 inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const
157 {
158 link.fwd(lp_lon, lp_lat, xy_x, xy_y);
159 }
160
161 template <typename T>
162 inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const
163 {
164 link.inv(xy_x, xy_y, lp_lon, lp_lat);
165 }
166
167 projection_type link;
168 CalculationType lamp;
169 CalculationType cphip, sphip;
170 };
171
172 template <typename T, typename Par>
173 inline void o_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& proj_parm)
174 {
175 T coslam, sinphi, cosphi;
176
177 coslam = cos(lp_lon);
178 sinphi = sin(lp_lat);
179 cosphi = cos(lp_lat);
180 lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam +
181 proj_parm.cphip * sinphi) + proj_parm.lamp);
182 lp_lat = aasin(proj_parm.sphip * sinphi - proj_parm.cphip * cosphi * coslam);
183
184 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
185 }
186
187 template <typename T, typename Par>
188 inline void o_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm)
189 {
190 T coslam, sinphi, cosphi;
191
192 proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat);
193 if (lp_lon != HUGE_VAL) {
194 coslam = cos(lp_lon -= proj_parm.lamp);
195 sinphi = sin(lp_lat);
196 cosphi = cos(lp_lat);
197 lp_lat = aasin(proj_parm.sphip * sinphi + proj_parm.cphip * cosphi * coslam);
198 lp_lon = aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam -
199 proj_parm.cphip * sinphi);
200 }
201 }
202
203 template <typename T, typename Par>
204 inline void t_forward(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y, Par const& proj_parm)
205 {
206 T cosphi, coslam;
207
208 cosphi = cos(lp_lat);
209 coslam = cos(lp_lon);
210 lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), sin(lp_lat)) + proj_parm.lamp);
211 lp_lat = aasin(- cosphi * coslam);
212 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
213 }
214
215 template <typename T, typename Par>
216 inline void t_inverse(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm)
217 {
218 T cosphi, t;
219
220 proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat);
221 if (lp_lon != HUGE_VAL) {
222 cosphi = cos(lp_lat);
223 t = lp_lon - proj_parm.lamp;
224 lp_lon = aatan2(cosphi * sin(t), - sin(lp_lat));
225 lp_lat = aasin(cosphi * cos(t));
226 }
227 }
228
229 // General Oblique Transformation
230 template <typename CalculationType, typename Parameters, typename ProjParameters>
231 inline CalculationType setup_ob_tran(Parameters & par, ProjParameters& proj_parm)
232 {
233 static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
234
235 CalculationType phip;
236
237 par.es = 0.; /* force to spherical */
238
239 // proj_parm.link should be created at this point
240
241 if (pj_param(par.params, "to_alpha").i) {
242 CalculationType lamc, phic, alpha;
243
244 lamc = pj_param(par.params, "ro_lon_c").f;
245 phic = pj_param(par.params, "ro_lat_c").f;
246 alpha = pj_param(par.params, "ro_alpha").f;
247 /*
248 if (fabs(phic) <= TOL ||
249 fabs(fabs(phic) - HALFPI) <= TOL ||
250 fabs(fabs(alpha) - HALFPI) <= TOL)
251 */
252 if (fabs(fabs(phic) - HALFPI) <= TOL)
253 BOOST_THROW_EXCEPTION( projection_exception(-32) );
254 proj_parm.lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic));
255 phip = aasin(cos(phic) * sin(alpha));
256 } else if (pj_param(par.params, "to_lat_p").i) { /* specified new pole */
257 proj_parm.lamp = pj_param(par.params, "ro_lon_p").f;
258 phip = pj_param(par.params, "ro_lat_p").f;
259 } else { /* specified new "equator" points */
260 CalculationType lam1, lam2, phi1, phi2, con;
261
262 lam1 = pj_param(par.params, "ro_lon_1").f;
263 phi1 = pj_param(par.params, "ro_lat_1").f;
264 lam2 = pj_param(par.params, "ro_lon_2").f;
265 phi2 = pj_param(par.params, "ro_lat_2").f;
266 if (fabs(phi1 - phi2) <= TOL ||
267 (con = fabs(phi1)) <= TOL ||
268 fabs(con - HALFPI) <= TOL ||
269 fabs(fabs(phi2) - HALFPI) <= TOL)
270 BOOST_THROW_EXCEPTION( projection_exception(-33) );
271 proj_parm.lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) -
272 sin(phi1) * cos(phi2) * cos(lam2),
273 sin(phi1) * cos(phi2) * sin(lam2) -
274 cos(phi1) * sin(phi2) * sin(lam1));
275 phip = atan(-cos(proj_parm.lamp - lam1) / tan(phi1));
276 }
277 if (fabs(phip) > TOL) { /* oblique */
278 proj_parm.cphip = cos(phip);
279 proj_parm.sphip = sin(phip);
280 } else { /* transverse */
281 }
282 // return phip to choose model
283 return phip;
284 }
285
286 // template class, using CRTP to implement forward/inverse
287 template <typename CalculationType, typename Parameters>
288 struct base_ob_tran_oblique : public base_t_fi<base_ob_tran_oblique<CalculationType, Parameters>,
289 CalculationType, Parameters>
290 {
291
292 typedef CalculationType geographic_type;
293 typedef CalculationType cartesian_type;
294
295 par_ob_tran<CalculationType, Parameters> m_proj_parm;
296
297 inline base_ob_tran_oblique(Parameters const& par,
298 par_ob_tran<CalculationType, Parameters> const& proj_parm)
299 : base_t_fi
300 <
301 base_ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters
302 >(*this, par)
303 , m_proj_parm(proj_parm)
304 {}
305
306 // FORWARD(o_forward) spheroid
307 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
308 inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
309 {
310 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
311 }
312
313 // INVERSE(o_inverse) spheroid
314 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
315 inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
316 {
317 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
318 }
319
320 static inline std::string get_name()
321 {
322 return "ob_tran_oblique";
323 }
324
325 };
326
327 // template class, using CRTP to implement forward/inverse
328 template <typename CalculationType, typename Parameters>
329 struct base_ob_tran_transverse : public base_t_fi<base_ob_tran_transverse<CalculationType, Parameters>,
330 CalculationType, Parameters>
331 {
332
333 typedef CalculationType geographic_type;
334 typedef CalculationType cartesian_type;
335
336 par_ob_tran<CalculationType, Parameters> m_proj_parm;
337
338 inline base_ob_tran_transverse(Parameters const& par,
339 par_ob_tran<CalculationType, Parameters> const& proj_parm)
340 : base_t_fi
341 <
342 base_ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters
343 >(*this, par)
344 , m_proj_parm(proj_parm)
345 {}
346
347 // FORWARD(t_forward) spheroid
348 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
349 inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
350 {
351 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
352 }
353
354 // INVERSE(t_inverse) spheroid
355 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
356 inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
357 {
358 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
359 }
360
361 static inline std::string get_name()
362 {
363 return "ob_tran_transverse";
364 }
365
366 };
367
368 // template class, using CRTP to implement forward/inverse
369 template <typename StaticParameters, typename CalculationType, typename Parameters>
370 struct base_ob_tran_static : public base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>,
371 CalculationType, Parameters>
372 {
373
374 typedef CalculationType geographic_type;
375 typedef CalculationType cartesian_type;
376
377 par_ob_tran_static<StaticParameters, CalculationType, Parameters> m_proj_parm;
378 bool m_is_oblique;
379
380 inline base_ob_tran_static(Parameters const& par)
381 : base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>, CalculationType, Parameters>(*this, par)
382 , m_proj_parm(par)
383 {}
384
385 // FORWARD(o_forward) spheroid
386 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
387 inline void fwd(geographic_type& lp_lon, geographic_type& lp_lat, cartesian_type& xy_x, cartesian_type& xy_y) const
388 {
389 if (m_is_oblique) {
390 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
391 } else {
392 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
393 }
394 }
395
396 // INVERSE(o_inverse) spheroid
397 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
398 inline void inv(cartesian_type& xy_x, cartesian_type& xy_y, geographic_type& lp_lon, geographic_type& lp_lat) const
399 {
400 if (m_is_oblique) {
401 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
402 } else {
403 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
404 }
405 }
406
407 static inline std::string get_name()
408 {
409 return "ob_tran";
410 }
411
412 };
413
414 }} // namespace detail::ob_tran
415 #endif // doxygen
416
417 /*!
418 \brief General Oblique Transformation projection
419 \ingroup projections
420 \tparam Geographic latlong point type
421 \tparam Cartesian xy point type
422 \tparam Parameters parameter type
423 \par Projection characteristics
424 - Miscellaneous
425 - Spheroid
426 \par Projection parameters
427 - o_proj (string)
428 - Plus projection parameters
429 - o_lat_p (degrees)
430 - o_lon_p (degrees)
431 - New pole
432 - o_alpha: Alpha (degrees)
433 - o_lon_c (degrees)
434 - o_lat_c (degrees)
435 - o_lon_1 (degrees)
436 - o_lat_1: Latitude of first standard parallel (degrees)
437 - o_lon_2 (degrees)
438 - o_lat_2: Latitude of second standard parallel (degrees)
439 \par Example
440 \image html ex_ob_tran.gif
441 */
442 template <typename CalculationType, typename Parameters>
443 struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters>
444 {
445 inline ob_tran_oblique(Parameters const& par,
446 detail::ob_tran::par_ob_tran<CalculationType, Parameters> const& proj_parm)
447 : detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters>(par, proj_parm)
448 {
449 // already done
450 //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
451 }
452 };
453
454 /*!
455 \brief General Oblique Transformation projection
456 \ingroup projections
457 \tparam Geographic latlong point type
458 \tparam Cartesian xy point type
459 \tparam Parameters parameter type
460 \par Projection characteristics
461 - Miscellaneous
462 - Spheroid
463 \par Projection parameters
464 - o_proj (string)
465 - Plus projection parameters
466 - o_lat_p (degrees)
467 - o_lon_p (degrees)
468 - New pole
469 - o_alpha: Alpha (degrees)
470 - o_lon_c (degrees)
471 - o_lat_c (degrees)
472 - o_lon_1 (degrees)
473 - o_lat_1: Latitude of first standard parallel (degrees)
474 - o_lon_2 (degrees)
475 - o_lat_2: Latitude of second standard parallel (degrees)
476 \par Example
477 \image html ex_ob_tran.gif
478 */
479 template <typename CalculationType, typename Parameters>
480 struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters>
481 {
482 inline ob_tran_transverse(Parameters const& par,
483 detail::ob_tran::par_ob_tran<CalculationType, Parameters> const& proj_parm)
484 : detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters>(par, proj_parm)
485 {
486 // already done
487 //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
488 }
489 };
490
491 /*!
492 \brief General Oblique Transformation projection
493 \ingroup projections
494 \tparam Geographic latlong point type
495 \tparam Cartesian xy point type
496 \tparam Parameters parameter type
497 \par Projection characteristics
498 - Miscellaneous
499 - Spheroid
500 \par Projection parameters
501 - o_proj (string)
502 - Plus projection parameters
503 - o_lat_p (degrees)
504 - o_lon_p (degrees)
505 - New pole
506 - o_alpha: Alpha (degrees)
507 - o_lon_c (degrees)
508 - o_lat_c (degrees)
509 - o_lon_1 (degrees)
510 - o_lat_1: Latitude of first standard parallel (degrees)
511 - o_lon_2 (degrees)
512 - o_lat_2: Latitude of second standard parallel (degrees)
513 \par Example
514 \image html ex_ob_tran.gif
515 */
516 template <typename StaticParameters, typename CalculationType, typename Parameters>
517 struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters>
518 {
519 inline ob_tran_static(const Parameters& par)
520 : detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters>(par)
521 {
522 CalculationType phip = detail::ob_tran::setup_ob_tran<CalculationType>(this->m_par, this->m_proj_parm);
523 this->m_is_oblique = fabs(phip) > detail::ob_tran::TOL;
524 }
525 };
526
527 #ifndef DOXYGEN_NO_DETAIL
528 namespace detail
529 {
530
531 // Static projection
532 template <typename BGP, typename CT, typename P>
533 struct static_projection_type<srs::par4::ob_tran, srs_sphere_tag, BGP, CT, P>
534 {
535 typedef ob_tran_static<BGP, CT, P> type;
536 };
537 template <typename BGP, typename CT, typename P>
538 struct static_projection_type<srs::par4::ob_tran, srs_spheroid_tag, BGP, CT, P>
539 {
540 typedef ob_tran_static<BGP, CT, P> type;
541 };
542
543 // Factory entry(s)
544 template <typename CalculationType, typename Parameters>
545 class ob_tran_entry : public detail::factory_entry<CalculationType, Parameters>
546 {
547 public :
548 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
549 {
550 Parameters params = par;
551 detail::ob_tran::par_ob_tran<CalculationType, Parameters> proj_parm(params);
552 CalculationType phip = detail::ob_tran::setup_ob_tran<CalculationType>(params, proj_parm);
553
554 if (fabs(phip) > detail::ob_tran::TOL)
555 return new base_v_fi<ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm);
556 else
557 return new base_v_fi<ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm);
558 }
559 };
560
561 template <typename CalculationType, typename Parameters>
562 inline void ob_tran_init(detail::base_factory<CalculationType, Parameters>& factory)
563 {
564 factory.add_to_factory("ob_tran", new ob_tran_entry<CalculationType, Parameters>);
565 }
566
567 } // namespace detail
568 #endif // doxygen
569
570 } // namespace projections
571
572 }} // namespace boost::geometry
573
574 #endif // BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
575