1 // Boost.Geometry - gis-projections (based on PROJ4)
3 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2017, 2018, 2019.
6 // Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
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)
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
18 // Last updated version of proj: 5.0.0
20 // Original copyright notice:
22 // Purpose: Implementation of the airy (Airy) projection.
23 // Author: Gerald Evenden (1995)
24 // Thomas Knudsen (2016) - revise/add regression tests
25 // Copyright (c) 1995, Gerald Evenden
27 // Permission is hereby granted, free of charge, to any person obtaining a
28 // copy of this software and associated documentation files (the "Software"),
29 // to deal in the Software without restriction, including without limitation
30 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
31 // and/or sell copies of the Software, and to permit persons to whom the
32 // Software is furnished to do so, subject to the following conditions:
34 // The above copyright notice and this permission notice shall be included
35 // in all copies or substantial portions of the Software.
37 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
40 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43 // DEALINGS IN THE SOFTWARE.
45 #ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
46 #define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
48 #include <boost/geometry/srs/projections/impl/base_static.hpp>
49 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
50 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
51 #include <boost/geometry/srs/projections/impl/pj_param.hpp>
52 #include <boost/geometry/srs/projections/impl/projects.hpp>
54 #include <boost/geometry/util/math.hpp>
56 namespace boost { namespace geometry
61 #ifndef DOXYGEN_NO_DETAIL
62 namespace detail { namespace airy
65 static const double epsilon = 1.e-10;
81 bool no_cut; /* do not cut at hemisphere limit */
84 template <typename T, typename Parameters>
85 struct base_airy_spheroid
87 par_airy<T> m_proj_parm;
89 // FORWARD(s_forward) spheroid
90 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
91 inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const
93 static const T half_pi = detail::half_pi<T>();
95 T sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz;
99 switch (this->m_proj_parm.mode) {
102 sinphi = sin(lp_lat);
103 cosphi = cos(lp_lat);
104 cosz = cosphi * coslam;
105 if (this->m_proj_parm.mode == obliq)
106 cosz = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosz;
107 if (!this->m_proj_parm.no_cut && cosz < -epsilon) {
108 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
110 if (fabs(s = 1. - cosz) > epsilon) {
111 t = 0.5 * (1. + cosz);
112 Krho = -log(t)/s - this->m_proj_parm.Cb / t;
114 Krho = 0.5 - this->m_proj_parm.Cb;
115 xy_x = Krho * cosphi * sinlam;
116 if (this->m_proj_parm.mode == obliq)
117 xy_y = Krho * (this->m_proj_parm.cosph0 * sinphi -
118 this->m_proj_parm.sinph0 * cosphi * coslam);
120 xy_y = Krho * sinphi;
124 lp_lat = fabs(this->m_proj_parm.p_halfpi - lp_lat);
125 if (!this->m_proj_parm.no_cut && (lp_lat - epsilon) > half_pi)
126 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
127 if ((lp_lat *= 0.5) > epsilon) {
129 Krho = -2.*(log(cos(lp_lat)) / t + t * this->m_proj_parm.Cb);
130 xy_x = Krho * sinlam;
131 xy_y = Krho * coslam;
132 if (this->m_proj_parm.mode == n_pole)
139 static inline std::string get_name()
141 return "airy_spheroid";
147 template <typename Params, typename Parameters, typename T>
148 inline void setup_airy(Params const& params, Parameters& par, par_airy<T>& proj_parm)
150 static const T half_pi = detail::half_pi<T>();
154 proj_parm.no_cut = pj_get_param_b<srs::spar::no_cut>(params, "no_cut", srs::dpar::no_cut);
155 beta = 0.5 * (half_pi - pj_get_param_r<T, srs::spar::lat_b>(params, "lat_b", srs::dpar::lat_b));
156 if (fabs(beta) < epsilon)
159 proj_parm.Cb = 1./tan(beta);
160 proj_parm.Cb *= proj_parm.Cb * log(cos(beta));
163 if (fabs(fabs(par.phi0) - half_pi) < epsilon)
165 proj_parm.p_halfpi = -half_pi;
166 proj_parm.mode = s_pole;
168 proj_parm.p_halfpi = half_pi;
169 proj_parm.mode = n_pole;
172 if (fabs(par.phi0) < epsilon)
173 proj_parm.mode = equit;
175 proj_parm.mode = obliq;
176 proj_parm.sinph0 = sin(par.phi0);
177 proj_parm.cosph0 = cos(par.phi0);
183 }} // namespace detail::airy
187 \brief Airy projection
189 \tparam Geographic latlong point type
190 \tparam Cartesian xy point type
191 \tparam Parameters parameter type
192 \par Projection characteristics
196 \par Projection parameters
197 - no_cut: Do not cut at hemisphere limit (boolean)
200 \image html ex_airy.gif
202 template <typename T, typename Parameters>
203 struct airy_spheroid : public detail::airy::base_airy_spheroid<T, Parameters>
205 template <typename Params>
206 inline airy_spheroid(Params const& params, Parameters & par)
208 detail::airy::setup_airy(params, par, this->m_proj_parm);
212 #ifndef DOXYGEN_NO_DETAIL
217 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_airy, airy_spheroid)
220 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(airy_entry, airy_spheroid)
222 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(airy_init)
224 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(airy, airy_entry)
227 } // namespace detail
230 } // namespace projections
232 }} // namespace boost::geometry
234 #endif // BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP