]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/geometry/srs/projections/proj/ob_tran.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / srs / projections / proj / ob_tran.hpp
CommitLineData
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// Permission is hereby granted, free of charge, to any person obtaining a
23// copy of this software and associated documentation files (the "Software"),
24// to deal in the Software without restriction, including without limitation
25// the rights to use, copy, modify, merge, publish, distribute, sublicense,
26// and/or sell copies of the Software, and to permit persons to whom the
27// Software is furnished to do so, subject to the following conditions:
28
29// The above copyright notice and this permission notice shall be included
30// in all copies or substantial portions of the Software.
31
32// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
33// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
35// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
37// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
38// DEALINGS IN THE SOFTWARE.
39
92f5a8d4
TL
40#ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
41#define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
42
20effc67
TL
43#include <type_traits>
44
11fdf7f2
TL
45#include <boost/geometry/util/math.hpp>
46#include <boost/shared_ptr.hpp>
47
20effc67
TL
48#include <boost/geometry/core/static_assert.hpp>
49
92f5a8d4 50#include <boost/geometry/srs/projections/impl/aasincos.hpp>
11fdf7f2
TL
51#include <boost/geometry/srs/projections/impl/base_static.hpp>
52#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
11fdf7f2 53#include <boost/geometry/srs/projections/impl/factory_entry.hpp>
92f5a8d4
TL
54#include <boost/geometry/srs/projections/impl/pj_ell_set.hpp>
55#include <boost/geometry/srs/projections/impl/projects.hpp>
11fdf7f2
TL
56
57namespace boost { namespace geometry
58{
59
11fdf7f2
TL
60namespace projections
61{
62 #ifndef DOXYGEN_NO_DETAIL
63 namespace detail {
64
65 // fwd declaration needed below
92f5a8d4
TL
66 template <typename T>
67 inline detail::dynamic_wrapper_b<T, projections::parameters<T> >*
68 create_new(srs::detail::proj4_parameters const& params,
69 projections::parameters<T> const& parameters);
70
71 template <typename T>
72 inline detail::dynamic_wrapper_b<T, projections::parameters<T> >*
73 create_new(srs::dpar::parameters<T> const& params,
74 projections::parameters<T> const& parameters);
11fdf7f2
TL
75
76 } // namespace detail
77
78 namespace detail { namespace ob_tran
79 {
80
92f5a8d4 81 static const double tolerance = 1e-10;
11fdf7f2
TL
82
83 template <typename Parameters>
92f5a8d4
TL
84 inline Parameters o_proj_parameters(srs::detail::proj4_parameters const& params,
85 Parameters const& par)
11fdf7f2 86 {
92f5a8d4
TL
87 /* copy existing header into new */
88 Parameters pj = par;
11fdf7f2
TL
89
90 /* get name of projection to be translated */
92f5a8d4
TL
91 pj.id = pj_get_param_s(params, "o_proj");
92 if (pj.id.is_unknown())
93 BOOST_THROW_EXCEPTION( projection_exception(error_no_rotation_proj) );
94
95 /* avoid endless recursion */
96 if( pj.id.name == "ob_tran")
97 BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_find_proj) );
98
99 // Commented out for consistency with Proj4 >= 5.0.0
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 T, typename Parameters>
108 inline Parameters o_proj_parameters(srs::dpar::parameters<T> const& params,
109 Parameters const& par)
110 {
11fdf7f2 111 /* copy existing header into new */
92f5a8d4
TL
112 Parameters pj = par;
113
114 /* get name of projection to be translated */
115 typename srs::dpar::parameters<T>::const_iterator
116 it = pj_param_find(params, srs::dpar::o_proj);
117 if (it != params.end())
118 pj.id = static_cast<srs::dpar::value_proj>(it->template get_value<int>());
119 else
120 BOOST_THROW_EXCEPTION( projection_exception(error_no_rotation_proj) );
121
122 /* avoid endless recursion */
123 if( pj.id.id == srs::dpar::proj_ob_tran)
124 BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_find_proj) );
125
126 // Commented out for consistency with Proj4 >= 5.0.0
11fdf7f2 127 /* force spherical earth */
92f5a8d4
TL
128 //pj.one_es = pj.rone_es = 1.;
129 //pj.es = pj.e = 0.;
11fdf7f2
TL
130
131 return pj;
132 }
133
20effc67
TL
134 template <typename ...Ps, typename Parameters>
135 inline Parameters o_proj_parameters(srs::spar::parameters<Ps...> const& /*params*/,
92f5a8d4
TL
136 Parameters const& par)
137 {
138 /* copy existing header into new */
139 Parameters pj = par;
140
141 /* get name of projection to be translated */
20effc67 142 typedef srs::spar::parameters<Ps...> params_type;
f67539c2 143 typedef typename geometry::tuples::find_if
92f5a8d4
TL
144 <
145 params_type,
146 srs::spar::detail::is_param_t<srs::spar::o_proj>::pred
147 >::type o_proj_type;
148
f67539c2 149 static const bool is_found = geometry::tuples::is_found<o_proj_type>::value;
20effc67
TL
150 BOOST_GEOMETRY_STATIC_ASSERT((is_found),
151 "Rotation projection not specified.",
152 params_type);
92f5a8d4
TL
153
154 typedef typename o_proj_type::type proj_type;
155 static const bool is_specialized = srs::spar::detail::proj_traits<proj_type>::is_specialized;
20effc67
TL
156 BOOST_GEOMETRY_STATIC_ASSERT((is_specialized),
157 "Rotation projection not specified.",
158 params_type);
92f5a8d4
TL
159
160 pj.id = srs::spar::detail::proj_traits<proj_type>::id;
161
162 /* avoid endless recursion */
20effc67
TL
163 static const bool is_non_resursive = ! std::is_same<proj_type, srs::spar::proj_ob_tran>::value;
164 BOOST_GEOMETRY_STATIC_ASSERT((is_non_resursive),
165 "o_proj parameter can not be set to ob_tran projection.",
166 params_type);
92f5a8d4
TL
167
168 // Commented out for consistency with Proj4 >= 5.0.0
169 /* force spherical earth */
170 //pj.one_es = pj.rone_es = 1.;
171 //pj.es = pj.e = 0.;
172
173 return pj;
174 }
175
176 // TODO: It's possible that the original Parameters could be used
177 // instead of a copy in link.
178 // But it's not possible with the current implementation of
179 // dynamic_wrapper_b always storing params
180
181 template <typename T, typename Parameters>
11fdf7f2
TL
182 struct par_ob_tran
183 {
92f5a8d4
TL
184 template <typename Params>
185 par_ob_tran(Params const& params, Parameters const& par)
186 : link(projections::detail::create_new(params, o_proj_parameters(params, par)))
11fdf7f2
TL
187 {
188 if (! link.get())
92f5a8d4 189 BOOST_THROW_EXCEPTION( projection_exception(error_unknown_projection_id) );
11fdf7f2
TL
190 }
191
92f5a8d4 192 inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 193 {
92f5a8d4 194 link->fwd(link->params(), lp_lon, lp_lat, xy_x, xy_y);
11fdf7f2
TL
195 }
196
92f5a8d4 197 inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2 198 {
92f5a8d4 199 link->inv(link->params(), xy_x, xy_y, lp_lon, lp_lat);
11fdf7f2
TL
200 }
201
92f5a8d4
TL
202 boost::shared_ptr<dynamic_wrapper_b<T, Parameters> > link;
203 T lamp;
204 T cphip, sphip;
11fdf7f2
TL
205 };
206
92f5a8d4 207 template <typename StaticParameters, typename T, typename Parameters>
11fdf7f2
TL
208 struct par_ob_tran_static
209 {
92f5a8d4
TL
210 // this metafunction handles static error handling
211 typedef typename srs::spar::detail::pick_o_proj_tag
11fdf7f2
TL
212 <
213 StaticParameters
214 >::type o_proj_tag;
215
92f5a8d4 216 /* avoid endless recursion */
20effc67
TL
217 static const bool is_o_proj_not_ob_tran = ! std::is_same<o_proj_tag, srs::spar::proj_ob_tran>::value;
218 BOOST_GEOMETRY_STATIC_ASSERT((is_o_proj_not_ob_tran),
219 "o_proj parameter can not be set to ob_tran projection.",
220 StaticParameters);
92f5a8d4 221
11fdf7f2
TL
222 typedef typename projections::detail::static_projection_type
223 <
224 o_proj_tag,
92f5a8d4
TL
225 // Commented out for consistency with Proj4 >= 5.0.0
226 //srs_sphere_tag, // force spherical
227 typename projections::detail::static_srs_tag<StaticParameters>::type,
11fdf7f2 228 StaticParameters,
92f5a8d4 229 T,
11fdf7f2
TL
230 Parameters
231 >::type projection_type;
232
92f5a8d4
TL
233 par_ob_tran_static(StaticParameters const& params, Parameters const& par)
234 : link(params, o_proj_parameters(params, par))
11fdf7f2
TL
235 {}
236
92f5a8d4 237 inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 238 {
92f5a8d4 239 link.fwd(link.params(), lp_lon, lp_lat, xy_x, xy_y);
11fdf7f2
TL
240 }
241
92f5a8d4 242 inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2 243 {
92f5a8d4 244 link.inv(link.params(), xy_x, xy_y, lp_lon, lp_lat);
11fdf7f2
TL
245 }
246
247 projection_type link;
92f5a8d4
TL
248 T lamp;
249 T cphip, sphip;
11fdf7f2
TL
250 };
251
252 template <typename T, typename Par>
92f5a8d4 253 inline void o_forward(T lp_lon, T lp_lat, T& xy_x, T& xy_y, Par const& proj_parm)
11fdf7f2
TL
254 {
255 T coslam, sinphi, cosphi;
256
257 coslam = cos(lp_lon);
258 sinphi = sin(lp_lat);
259 cosphi = cos(lp_lat);
260 lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam +
261 proj_parm.cphip * sinphi) + proj_parm.lamp);
262 lp_lat = aasin(proj_parm.sphip * sinphi - proj_parm.cphip * cosphi * coslam);
263
264 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
265 }
266
267 template <typename T, typename Par>
92f5a8d4 268 inline void o_inverse(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm)
11fdf7f2
TL
269 {
270 T coslam, sinphi, cosphi;
271
272 proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat);
273 if (lp_lon != HUGE_VAL) {
274 coslam = cos(lp_lon -= proj_parm.lamp);
275 sinphi = sin(lp_lat);
276 cosphi = cos(lp_lat);
277 lp_lat = aasin(proj_parm.sphip * sinphi + proj_parm.cphip * cosphi * coslam);
278 lp_lon = aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam -
279 proj_parm.cphip * sinphi);
280 }
281 }
282
283 template <typename T, typename Par>
92f5a8d4 284 inline void t_forward(T lp_lon, T lp_lat, T& xy_x, T& xy_y, Par const& proj_parm)
11fdf7f2
TL
285 {
286 T cosphi, coslam;
287
288 cosphi = cos(lp_lat);
289 coslam = cos(lp_lon);
290 lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), sin(lp_lat)) + proj_parm.lamp);
291 lp_lat = aasin(- cosphi * coslam);
92f5a8d4 292
11fdf7f2
TL
293 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
294 }
295
296 template <typename T, typename Par>
92f5a8d4 297 inline void t_inverse(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm)
11fdf7f2
TL
298 {
299 T cosphi, t;
300
301 proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat);
302 if (lp_lon != HUGE_VAL) {
303 cosphi = cos(lp_lat);
304 t = lp_lon - proj_parm.lamp;
305 lp_lon = aatan2(cosphi * sin(t), - sin(lp_lat));
306 lp_lat = aasin(cosphi * cos(t));
307 }
308 }
309
310 // General Oblique Transformation
92f5a8d4
TL
311 template <typename T, typename Params, typename Parameters, typename ProjParameters>
312 inline T setup_ob_tran(Params const& params, Parameters & /*par*/, ProjParameters& proj_parm)
11fdf7f2 313 {
92f5a8d4 314 static const T half_pi = detail::half_pi<T>();
11fdf7f2 315
92f5a8d4 316 T phip, alpha;
11fdf7f2 317
92f5a8d4
TL
318 // Commented out for consistency with Proj4 >= 5.0.0
319 //par.es = 0.; /* force to spherical */
11fdf7f2
TL
320
321 // proj_parm.link should be created at this point
322
92f5a8d4
TL
323 if (pj_param_r<srs::spar::o_alpha>(params, "o_alpha", srs::dpar::o_alpha, alpha)) {
324 T lamc, phic;
325
326 lamc = pj_get_param_r<T, srs::spar::o_lon_c>(params, "o_lon_c", srs::dpar::o_lon_c);
327 phic = pj_get_param_r<T, srs::spar::o_lon_c>(params, "o_lat_c", srs::dpar::o_lat_c);
328 //alpha = pj_get_param_r(par.params, "o_alpha");
329
330 if (fabs(fabs(phic) - half_pi) <= tolerance)
331 BOOST_THROW_EXCEPTION( projection_exception(error_lat_0_or_alpha_eq_90) );
332
11fdf7f2
TL
333 proj_parm.lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic));
334 phip = aasin(cos(phic) * sin(alpha));
92f5a8d4
TL
335 } else if (pj_param_r<srs::spar::o_lat_p>(params, "o_lat_p", srs::dpar::o_lat_p, phip)) { /* specified new pole */
336 proj_parm.lamp = pj_get_param_r<T, srs::spar::o_lon_p>(params, "o_lon_p", srs::dpar::o_lon_p);
337 //phip = pj_param_r(par.params, "o_lat_p");
11fdf7f2 338 } else { /* specified new "equator" points */
92f5a8d4
TL
339 T lam1, lam2, phi1, phi2, con;
340
341 lam1 = pj_get_param_r<T, srs::spar::o_lon_1>(params, "o_lon_1", srs::dpar::o_lon_1);
342 phi1 = pj_get_param_r<T, srs::spar::o_lat_1>(params, "o_lat_1", srs::dpar::o_lat_1);
343 lam2 = pj_get_param_r<T, srs::spar::o_lon_2>(params, "o_lon_2", srs::dpar::o_lon_2);
344 phi2 = pj_get_param_r<T, srs::spar::o_lat_2>(params, "o_lat_2", srs::dpar::o_lat_2);
345 if (fabs(phi1 - phi2) <= tolerance || (con = fabs(phi1)) <= tolerance ||
346 fabs(con - half_pi) <= tolerance || fabs(fabs(phi2) - half_pi) <= tolerance)
347 BOOST_THROW_EXCEPTION( projection_exception(error_lat_1_or_2_zero_or_90) );
348
11fdf7f2
TL
349 proj_parm.lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) -
350 sin(phi1) * cos(phi2) * cos(lam2),
351 sin(phi1) * cos(phi2) * sin(lam2) -
352 cos(phi1) * sin(phi2) * sin(lam1));
353 phip = atan(-cos(proj_parm.lamp - lam1) / tan(phi1));
354 }
92f5a8d4
TL
355
356 if (fabs(phip) > tolerance) { /* oblique */
11fdf7f2
TL
357 proj_parm.cphip = cos(phip);
358 proj_parm.sphip = sin(phip);
359 } else { /* transverse */
360 }
92f5a8d4
TL
361
362 // TODO:
363 /* Support some rather speculative test cases, where the rotated projection */
364 /* is actually latlong. We do not want scaling in that case... */
365 //if (proj_parm.link...mutable_parameters().right==PJ_IO_UNITS_ANGULAR)
366 // par.right = PJ_IO_UNITS_PROJECTED;
367
11fdf7f2
TL
368 // return phip to choose model
369 return phip;
370 }
371
92f5a8d4
TL
372 template <typename T, typename Parameters>
373 struct base_ob_tran_oblique
11fdf7f2 374 {
92f5a8d4 375 par_ob_tran<T, Parameters> m_proj_parm;
11fdf7f2 376
92f5a8d4
TL
377 inline base_ob_tran_oblique(par_ob_tran<T, Parameters> const& proj_parm)
378 : m_proj_parm(proj_parm)
11fdf7f2
TL
379 {}
380
381 // FORWARD(o_forward) spheroid
382 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
92f5a8d4 383 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 384 {
92f5a8d4 385 // NOTE: Parameters ignored, m_proj_parm.link has a copy
11fdf7f2
TL
386 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
387 }
388
389 // INVERSE(o_inverse) spheroid
390 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
92f5a8d4 391 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2 392 {
92f5a8d4 393 // NOTE: Parameters ignored, m_proj_parm.link has a copy
11fdf7f2
TL
394 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
395 }
396
397 static inline std::string get_name()
398 {
399 return "ob_tran_oblique";
400 }
401
402 };
403
92f5a8d4
TL
404 template <typename T, typename Parameters>
405 struct base_ob_tran_transverse
11fdf7f2 406 {
92f5a8d4 407 par_ob_tran<T, Parameters> m_proj_parm;
11fdf7f2 408
92f5a8d4
TL
409 inline base_ob_tran_transverse(par_ob_tran<T, Parameters> const& proj_parm)
410 : m_proj_parm(proj_parm)
11fdf7f2
TL
411 {}
412
413 // FORWARD(t_forward) spheroid
414 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
92f5a8d4 415 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 416 {
92f5a8d4 417 // NOTE: Parameters ignored, m_proj_parm.link has a copy
11fdf7f2
TL
418 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
419 }
420
421 // INVERSE(t_inverse) spheroid
422 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
92f5a8d4 423 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2 424 {
92f5a8d4 425 // NOTE: Parameters ignored, m_proj_parm.link has a copy
11fdf7f2
TL
426 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
427 }
428
429 static inline std::string get_name()
430 {
431 return "ob_tran_transverse";
432 }
433
434 };
435
92f5a8d4
TL
436 template <typename StaticParameters, typename T, typename Parameters>
437 struct base_ob_tran_static
11fdf7f2 438 {
92f5a8d4 439 par_ob_tran_static<StaticParameters, T, Parameters> m_proj_parm;
11fdf7f2
TL
440 bool m_is_oblique;
441
92f5a8d4
TL
442 inline base_ob_tran_static(StaticParameters const& params, Parameters const& par)
443 : m_proj_parm(params, par)
11fdf7f2
TL
444 {}
445
446 // FORWARD(o_forward) spheroid
447 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
92f5a8d4 448 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
11fdf7f2 449 {
92f5a8d4 450 // NOTE: Parameters ignored, m_proj_parm.link has a copy
11fdf7f2
TL
451 if (m_is_oblique) {
452 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
453 } else {
454 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
455 }
456 }
457
458 // INVERSE(o_inverse) spheroid
459 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
92f5a8d4 460 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
11fdf7f2 461 {
92f5a8d4 462 // NOTE: Parameters ignored, m_proj_parm.link has a copy
11fdf7f2
TL
463 if (m_is_oblique) {
464 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
465 } else {
466 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
467 }
468 }
469
470 static inline std::string get_name()
471 {
472 return "ob_tran";
473 }
474
475 };
476
477 }} // namespace detail::ob_tran
478 #endif // doxygen
479
480 /*!
481 \brief General Oblique Transformation projection
482 \ingroup projections
483 \tparam Geographic latlong point type
484 \tparam Cartesian xy point type
485 \tparam Parameters parameter type
486 \par Projection characteristics
487 - Miscellaneous
488 - Spheroid
489 \par Projection parameters
490 - o_proj (string)
491 - Plus projection parameters
492 - o_lat_p (degrees)
493 - o_lon_p (degrees)
494 - New pole
495 - o_alpha: Alpha (degrees)
496 - o_lon_c (degrees)
497 - o_lat_c (degrees)
498 - o_lon_1 (degrees)
499 - o_lat_1: Latitude of first standard parallel (degrees)
500 - o_lon_2 (degrees)
501 - o_lat_2: Latitude of second standard parallel (degrees)
502 \par Example
503 \image html ex_ob_tran.gif
504 */
92f5a8d4
TL
505 template <typename T, typename Parameters>
506 struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<T, Parameters>
11fdf7f2 507 {
92f5a8d4
TL
508 template <typename Params>
509 inline ob_tran_oblique(Params const& , Parameters const& ,
510 detail::ob_tran::par_ob_tran<T, Parameters> const& proj_parm)
511 : detail::ob_tran::base_ob_tran_oblique<T, Parameters>(proj_parm)
11fdf7f2
TL
512 {
513 // already done
514 //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
515 }
516 };
517
518 /*!
519 \brief General Oblique Transformation projection
520 \ingroup projections
521 \tparam Geographic latlong point type
522 \tparam Cartesian xy point type
523 \tparam Parameters parameter type
524 \par Projection characteristics
525 - Miscellaneous
526 - Spheroid
527 \par Projection parameters
528 - o_proj (string)
529 - Plus projection parameters
530 - o_lat_p (degrees)
531 - o_lon_p (degrees)
532 - New pole
533 - o_alpha: Alpha (degrees)
534 - o_lon_c (degrees)
535 - o_lat_c (degrees)
536 - o_lon_1 (degrees)
537 - o_lat_1: Latitude of first standard parallel (degrees)
538 - o_lon_2 (degrees)
539 - o_lat_2: Latitude of second standard parallel (degrees)
540 \par Example
541 \image html ex_ob_tran.gif
542 */
92f5a8d4
TL
543 template <typename T, typename Parameters>
544 struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<T, Parameters>
545 {
546 template <typename Params>
547 inline ob_tran_transverse(Params const& , Parameters const& ,
548 detail::ob_tran::par_ob_tran<T, Parameters> const& proj_parm)
549 : detail::ob_tran::base_ob_tran_transverse<T, Parameters>(proj_parm)
11fdf7f2
TL
550 {
551 // already done
552 //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
553 }
554 };
555
556 /*!
557 \brief General Oblique Transformation projection
558 \ingroup projections
559 \tparam Geographic latlong point type
560 \tparam Cartesian xy point type
561 \tparam Parameters parameter type
562 \par Projection characteristics
563 - Miscellaneous
564 - Spheroid
565 \par Projection parameters
566 - o_proj (string)
567 - Plus projection parameters
568 - o_lat_p (degrees)
569 - o_lon_p (degrees)
570 - New pole
571 - o_alpha: Alpha (degrees)
572 - o_lon_c (degrees)
573 - o_lat_c (degrees)
574 - o_lon_1 (degrees)
575 - o_lat_1: Latitude of first standard parallel (degrees)
576 - o_lon_2 (degrees)
577 - o_lat_2: Latitude of second standard parallel (degrees)
578 \par Example
579 \image html ex_ob_tran.gif
580 */
92f5a8d4
TL
581 template <typename StaticParameters, typename T, typename Parameters>
582 struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, T, Parameters>
11fdf7f2 583 {
92f5a8d4
TL
584 inline ob_tran_static(StaticParameters const& params, Parameters const& par)
585 : detail::ob_tran::base_ob_tran_static<StaticParameters, T, Parameters>(params, par)
11fdf7f2 586 {
92f5a8d4
TL
587 T phip = detail::ob_tran::setup_ob_tran<T>(params, par, this->m_proj_parm);
588 this->m_is_oblique = fabs(phip) > detail::ob_tran::tolerance;
11fdf7f2
TL
589 }
590 };
591
592 #ifndef DOXYGEN_NO_DETAIL
593 namespace detail
594 {
595
596 // Static projection
92f5a8d4
TL
597 template <typename SP, typename CT, typename P>
598 struct static_projection_type<srs::spar::proj_ob_tran, srs_sphere_tag, SP, CT, P>
11fdf7f2 599 {
92f5a8d4 600 typedef static_wrapper_fi<ob_tran_static<SP, CT, P>, P> type;
11fdf7f2 601 };
92f5a8d4
TL
602 template <typename SP, typename CT, typename P>
603 struct static_projection_type<srs::spar::proj_ob_tran, srs_spheroid_tag, SP, CT, P>
11fdf7f2 604 {
92f5a8d4 605 typedef static_wrapper_fi<ob_tran_static<SP, CT, P>, P> type;
11fdf7f2
TL
606 };
607
608 // Factory entry(s)
92f5a8d4 609 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ob_tran_entry)
11fdf7f2 610 {
92f5a8d4
TL
611 Parameters parameters_copy = parameters;
612 detail::ob_tran::par_ob_tran<T, Parameters> proj_parm(params, parameters_copy);
613 T phip = detail::ob_tran::setup_ob_tran<T>(params, parameters_copy, proj_parm);
614
615 if (fabs(phip) > detail::ob_tran::tolerance)
616 return new dynamic_wrapper_fi<ob_tran_oblique<T, Parameters>, T, Parameters>(params, parameters_copy, proj_parm);
617 else
618 return new dynamic_wrapper_fi<ob_tran_transverse<T, Parameters>, T, Parameters>(params, parameters_copy, proj_parm);
619 }
620 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END
11fdf7f2 621
92f5a8d4 622 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(ob_tran_init)
11fdf7f2 623 {
92f5a8d4 624 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(ob_tran, ob_tran_entry)
11fdf7f2
TL
625 }
626
627 } // namespace detail
628 #endif // doxygen
629
630} // namespace projections
631
632}} // namespace boost::geometry
633
634#endif // BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
635