1 #ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
2 #define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
4 // Boost.Geometry - extensions-gis-projections (based on PROJ4)
5 // This file is automatically generated. DO NOT EDIT.
7 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
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.
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)
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
22 // Last updated version of proj: 4.9.1
24 // Original copyright notice:
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:
33 // The above copyright notice and this permission notice shall be included
34 // in all copies or substantial portions of the Software.
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.
44 #include <boost/geometry/util/math.hpp>
45 #include <boost/shared_ptr.hpp>
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>
53 namespace boost { namespace geometry
56 namespace srs { namespace par4
58 //struct ob_tran_oblique {};
59 //struct ob_tran_transverse {};
62 }} //namespace srs::par4
66 #ifndef DOXYGEN_NO_DETAIL
69 // fwd declaration needed below
70 template <typename CalculationType>
71 inline detail::base_v<CalculationType, parameters<CalculationType> >*
72 create_new(parameters<CalculationType> const& parameters);
76 namespace detail { namespace ob_tran
79 static const double TOL = 1e-10;
81 template <typename Parameters>
82 inline Parameters o_proj_parameters(Parameters const& par)
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;
100 /* force spherical earth */
101 pj.one_es = pj.rone_es = 1.;
107 template <typename CalculationType, typename Parameters>
110 par_ob_tran(Parameters const& par)
111 : link(projections::detail::create_new(o_proj_parameters(par)))
114 BOOST_THROW_EXCEPTION( projection_exception(-26) );
117 template <typename T>
118 inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const
120 link->fwd(lp_lon, lp_lat, xy_x, xy_y);
123 template <typename T>
124 inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const
126 link->inv(xy_x, xy_y, lp_lon, lp_lat);
129 boost::shared_ptr<base_v<CalculationType, Parameters> > link;
130 CalculationType lamp;
131 CalculationType cphip, sphip;
134 template <typename StaticParameters, typename CalculationType, typename Parameters>
135 struct par_ob_tran_static
137 typedef typename srs::par4::detail::pick_o_proj_tag
142 typedef typename projections::detail::static_projection_type
145 srs_sphere_tag, // force spherical
149 >::type projection_type;
151 par_ob_tran_static(Parameters const& par)
152 : link(o_proj_parameters(par))
155 template <typename T>
156 inline void fwd(T& lp_lon, T& lp_lat, T& xy_x, T& xy_y) const
158 link.fwd(lp_lon, lp_lat, xy_x, xy_y);
161 template <typename T>
162 inline void inv(T& xy_x, T& xy_y, T& lp_lon, T& lp_lat) const
164 link.inv(xy_x, xy_y, lp_lon, lp_lat);
167 projection_type link;
168 CalculationType lamp;
169 CalculationType cphip, sphip;
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)
175 T coslam, sinphi, cosphi;
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);
184 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
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)
190 T coslam, sinphi, cosphi;
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);
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)
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);
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)
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));
229 // General Oblique Transformation
230 template <typename CalculationType, typename Parameters, typename ProjParameters>
231 inline CalculationType setup_ob_tran(Parameters & par, ProjParameters& proj_parm)
233 static const CalculationType HALFPI = detail::HALFPI<CalculationType>();
235 CalculationType phip;
237 par.es = 0.; /* force to spherical */
239 // proj_parm.link should be created at this point
241 if (pj_param(par.params, "to_alpha").i) {
242 CalculationType lamc, phic, alpha;
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;
248 if (fabs(phic) <= TOL ||
249 fabs(fabs(phic) - HALFPI) <= TOL ||
250 fabs(fabs(alpha) - HALFPI) <= TOL)
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;
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));
277 if (fabs(phip) > TOL) { /* oblique */
278 proj_parm.cphip = cos(phip);
279 proj_parm.sphip = sin(phip);
280 } else { /* transverse */
282 // return phip to choose model
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>
292 typedef CalculationType geographic_type;
293 typedef CalculationType cartesian_type;
295 par_ob_tran<CalculationType, Parameters> m_proj_parm;
297 inline base_ob_tran_oblique(Parameters const& par,
298 par_ob_tran<CalculationType, Parameters> const& proj_parm)
301 base_ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters
303 , m_proj_parm(proj_parm)
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
310 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
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
317 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
320 static inline std::string get_name()
322 return "ob_tran_oblique";
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>
333 typedef CalculationType geographic_type;
334 typedef CalculationType cartesian_type;
336 par_ob_tran<CalculationType, Parameters> m_proj_parm;
338 inline base_ob_tran_transverse(Parameters const& par,
339 par_ob_tran<CalculationType, Parameters> const& proj_parm)
342 base_ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters
344 , m_proj_parm(proj_parm)
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
351 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
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
358 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
361 static inline std::string get_name()
363 return "ob_tran_transverse";
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>
374 typedef CalculationType geographic_type;
375 typedef CalculationType cartesian_type;
377 par_ob_tran_static<StaticParameters, CalculationType, Parameters> m_proj_parm;
380 inline base_ob_tran_static(Parameters const& par)
381 : base_t_fi<base_ob_tran_static<StaticParameters, CalculationType, Parameters>, CalculationType, Parameters>(*this, par)
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
390 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
392 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
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
401 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
403 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
407 static inline std::string get_name()
414 }} // namespace detail::ob_tran
418 \brief General Oblique Transformation projection
420 \tparam Geographic latlong point type
421 \tparam Cartesian xy point type
422 \tparam Parameters parameter type
423 \par Projection characteristics
426 \par Projection parameters
428 - Plus projection parameters
432 - o_alpha: Alpha (degrees)
436 - o_lat_1: Latitude of first standard parallel (degrees)
438 - o_lat_2: Latitude of second standard parallel (degrees)
440 \image html ex_ob_tran.gif
442 template <typename CalculationType, typename Parameters>
443 struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<CalculationType, Parameters>
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)
450 //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
455 \brief General Oblique Transformation projection
457 \tparam Geographic latlong point type
458 \tparam Cartesian xy point type
459 \tparam Parameters parameter type
460 \par Projection characteristics
463 \par Projection parameters
465 - Plus projection parameters
469 - o_alpha: Alpha (degrees)
473 - o_lat_1: Latitude of first standard parallel (degrees)
475 - o_lat_2: Latitude of second standard parallel (degrees)
477 \image html ex_ob_tran.gif
479 template <typename CalculationType, typename Parameters>
480 struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<CalculationType, Parameters>
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)
487 //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm);
492 \brief General Oblique Transformation projection
494 \tparam Geographic latlong point type
495 \tparam Cartesian xy point type
496 \tparam Parameters parameter type
497 \par Projection characteristics
500 \par Projection parameters
502 - Plus projection parameters
506 - o_alpha: Alpha (degrees)
510 - o_lat_1: Latitude of first standard parallel (degrees)
512 - o_lat_2: Latitude of second standard parallel (degrees)
514 \image html ex_ob_tran.gif
516 template <typename StaticParameters, typename CalculationType, typename Parameters>
517 struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters>
519 inline ob_tran_static(const Parameters& par)
520 : detail::ob_tran::base_ob_tran_static<StaticParameters, CalculationType, Parameters>(par)
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;
527 #ifndef DOXYGEN_NO_DETAIL
532 template <typename BGP, typename CT, typename P>
533 struct static_projection_type<srs::par4::ob_tran, srs_sphere_tag, BGP, CT, P>
535 typedef ob_tran_static<BGP, CT, P> type;
537 template <typename BGP, typename CT, typename P>
538 struct static_projection_type<srs::par4::ob_tran, srs_spheroid_tag, BGP, CT, P>
540 typedef ob_tran_static<BGP, CT, P> type;
544 template <typename CalculationType, typename Parameters>
545 class ob_tran_entry : public detail::factory_entry<CalculationType, Parameters>
548 virtual base_v<CalculationType, Parameters>* create_new(const Parameters& par) const
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);
554 if (fabs(phip) > detail::ob_tran::TOL)
555 return new base_v_fi<ob_tran_oblique<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm);
557 return new base_v_fi<ob_tran_transverse<CalculationType, Parameters>, CalculationType, Parameters>(params, proj_parm);
561 template <typename CalculationType, typename Parameters>
562 inline void ob_tran_init(detail::base_factory<CalculationType, Parameters>& factory)
564 factory.add_to_factory("ob_tran", new ob_tran_entry<CalculationType, Parameters>);
567 } // namespace detail
570 } // namespace projections
572 }} // namespace boost::geometry
574 #endif // BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP