Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / geometry / srs / projections / proj / sterea.hpp
1 // Boost.Geometry - gis-projections (based on PROJ4)
2
3 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
4
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.
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
18 // Last updated version of proj: 5.0.0
19
20 // Original copyright notice:
21
22 // Copyright (c) 2003   Gerald I. Evenden
23
24 // Permission is hereby granted, free of charge, to any person obtaining a
25 // copy of this software and associated documentation files (the "Software"),
26 // to deal in the Software without restriction, including without limitation
27 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
28 // and/or sell copies of the Software, and to permit persons to whom the
29 // Software is furnished to do so, subject to the following conditions:
30
31 // The above copyright notice and this permission notice shall be included
32 // in all copies or substantial portions of the Software.
33
34 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
35 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
37 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
40 // DEALINGS IN THE SOFTWARE.
41
42 #ifndef BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
43 #define BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
44
45 #include <boost/math/special_functions/hypot.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/pj_gauss.hpp>
52
53
54 namespace boost { namespace geometry
55 {
56
57 namespace projections
58 {
59     #ifndef DOXYGEN_NO_DETAIL
60     namespace detail { namespace sterea
61     {
62
63             template <typename T>
64             struct par_sterea
65             {
66                 T phic0;
67                 T cosc0, sinc0;
68                 T R2;
69                 gauss<T> en;
70             };
71
72             template <typename T, typename Parameters>
73             struct base_sterea_ellipsoid
74             {
75                 par_sterea<T> m_proj_parm;
76
77                 // FORWARD(e_forward)  ellipsoid
78                 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
79                 inline void fwd(Parameters const& par, T lp_lon, T lp_lat, T& xy_x, T& xy_y) const
80                 {
81                     T cosc, sinc, cosl_, k;
82
83                     detail::gauss_fwd(m_proj_parm.en, lp_lon, lp_lat);
84                     sinc = sin(lp_lat);
85                     cosc = cos(lp_lat);
86                     cosl_ = cos(lp_lon);
87                     k = par.k0 * this->m_proj_parm.R2 / (1. + this->m_proj_parm.sinc0 * sinc + this->m_proj_parm.cosc0 * cosc * cosl_);
88                     xy_x = k * cosc * sin(lp_lon);
89                     xy_y = k * (this->m_proj_parm.cosc0 * sinc - this->m_proj_parm.sinc0 * cosc * cosl_);
90                 }
91
92                 // INVERSE(e_inverse)  ellipsoid
93                 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
94                 inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const
95                 {
96                     T rho, c, sinc, cosc;
97
98                     xy_x /= par.k0;
99                     xy_y /= par.k0;
100                     if((rho = boost::math::hypot(xy_x, xy_y)) != 0.0) {
101                         c = 2. * atan2(rho, this->m_proj_parm.R2);
102                         sinc = sin(c);
103                         cosc = cos(c);
104                         lp_lat = asin(cosc * this->m_proj_parm.sinc0 + xy_y * sinc * this->m_proj_parm.cosc0 / rho);
105                         lp_lon = atan2(xy_x * sinc, rho * this->m_proj_parm.cosc0 * cosc -
106                                         xy_y * this->m_proj_parm.sinc0 * sinc);
107                     } else {
108                         lp_lat = this->m_proj_parm.phic0;
109                         lp_lon = 0.;
110                     }
111                     detail::gauss_inv(m_proj_parm.en, lp_lon, lp_lat);
112                 }
113
114                 static inline std::string get_name()
115                 {
116                     return "sterea_ellipsoid";
117                 }
118
119             };
120
121             // Oblique Stereographic Alternative
122             template <typename Parameters, typename T>
123             inline void setup_sterea(Parameters const& par, par_sterea<T>& proj_parm)
124             {
125                 T R;
126
127                 proj_parm.en = detail::gauss_ini(par.e, par.phi0, proj_parm.phic0, R);
128                 proj_parm.sinc0 = sin(proj_parm.phic0);
129                 proj_parm.cosc0 = cos(proj_parm.phic0);
130                 proj_parm.R2 = 2. * R;
131             }
132
133     }} // namespace detail::sterea
134     #endif // doxygen
135
136     /*!
137         \brief Oblique Stereographic Alternative projection
138         \ingroup projections
139         \tparam Geographic latlong point type
140         \tparam Cartesian xy point type
141         \tparam Parameters parameter type
142         \par Projection characteristics
143          - Azimuthal
144          - Spheroid
145          - Ellipsoid
146         \par Example
147         \image html ex_sterea.gif
148     */
149     template <typename T, typename Parameters>
150     struct sterea_ellipsoid : public detail::sterea::base_sterea_ellipsoid<T, Parameters>
151     {
152         template <typename Params>
153         inline sterea_ellipsoid(Params const& , Parameters const& par)
154         {
155             detail::sterea::setup_sterea(par, this->m_proj_parm);
156         }
157     };
158
159     #ifndef DOXYGEN_NO_DETAIL
160     namespace detail
161     {
162
163         // Static projection
164         BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_sterea, sterea_ellipsoid)
165
166         // Factory entry(s)
167         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(sterea_entry, sterea_ellipsoid)
168         
169         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(sterea_init)
170         {
171             BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(sterea, sterea_entry)
172         }
173
174     } // namespace detail
175     #endif // doxygen
176
177 } // namespace projections
178
179 }} // namespace boost::geometry
180
181 #endif // BOOST_GEOMETRY_PROJECTIONS_STEREA_HPP
182