Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:45

0001 // Boost.Geometry - gis-projections (based on PROJ4)
0002 
0003 // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2017, 2018, 2019.
0006 // Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
0007 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle.
0008 
0009 // Use, modification and distribution is subject to the Boost Software License,
0010 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0011 // http://www.boost.org/LICENSE_1_0.txt)
0012 
0013 // This file is converted from PROJ4, http://trac.osgeo.org/proj
0014 // PROJ4 is originally written by Gerald Evenden (then of the USGS)
0015 // PROJ4 is maintained by Frank Warmerdam
0016 // PROJ4 is converted to Boost.Geometry by Barend Gehrels
0017 
0018 // Last updated version of proj: 5.0.0
0019 
0020 // Original copyright notice:
0021 
0022 // Permission is hereby granted, free of charge, to any person obtaining a
0023 // copy of this software and associated documentation files (the "Software"),
0024 // to deal in the Software without restriction, including without limitation
0025 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
0026 // and/or sell copies of the Software, and to permit persons to whom the
0027 // Software is furnished to do so, subject to the following conditions:
0028 
0029 // The above copyright notice and this permission notice shall be included
0030 // in all copies or substantial portions of the Software.
0031 
0032 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0033 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0034 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
0035 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0036 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0037 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0038 // DEALINGS IN THE SOFTWARE.
0039 
0040 #ifndef BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
0041 #define BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
0042 
0043 #include <boost/math/special_functions/hypot.hpp>
0044 
0045 #include <boost/geometry/srs/projections/impl/aasincos.hpp>
0046 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0047 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0048 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0049 #include <boost/geometry/srs/projections/impl/pj_param.hpp>
0050 #include <boost/geometry/srs/projections/impl/projects.hpp>
0051 
0052 namespace boost { namespace geometry
0053 {
0054 
0055 namespace projections
0056 {
0057     #ifndef DOXYGEN_NO_DETAIL
0058     namespace detail { namespace oea
0059     {
0060             template <typename T>
0061             struct par_oea
0062             {
0063                 T    theta;
0064                 T    m, n;
0065                 T    two_r_m, two_r_n, rm, rn, hm, hn;
0066                 T    cp0, sp0;
0067             };
0068 
0069             template <typename T, typename Parameters>
0070             struct base_oea_spheroid
0071             {
0072                 par_oea<T> m_proj_parm;
0073 
0074                 // FORWARD(s_forward)  sphere
0075                 // Project coordinates from geographic (lon, lat) to cartesian (x, y)
0076                 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0077                 {
0078                     T Az, M, N, cp, sp, cl, shz;
0079 
0080                     cp = cos(lp_lat);
0081                     sp = sin(lp_lat);
0082                     cl = cos(lp_lon);
0083                     Az = aatan2(cp * sin(lp_lon), this->m_proj_parm.cp0 * sp - this->m_proj_parm.sp0 * cp * cl) + this->m_proj_parm.theta;
0084                     shz = sin(0.5 * aacos(this->m_proj_parm.sp0 * sp + this->m_proj_parm.cp0 * cp * cl));
0085                     M = aasin(shz * sin(Az));
0086                     N = aasin(shz * cos(Az) * cos(M) / cos(M * this->m_proj_parm.two_r_m));
0087                     xy_y = this->m_proj_parm.n * sin(N * this->m_proj_parm.two_r_n);
0088                     xy_x = this->m_proj_parm.m * sin(M * this->m_proj_parm.two_r_m) * cos(N) / cos(N * this->m_proj_parm.two_r_n);
0089                 }
0090 
0091                 // INVERSE(s_inverse)  sphere
0092                 // Project coordinates from cartesian (x, y) to geographic (lon, lat)
0093                 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0094                 {
0095                     T N, M, xp, yp, z, Az, cz, sz, cAz;
0096 
0097                     N = this->m_proj_parm.hn * aasin(xy_y * this->m_proj_parm.rn);
0098                     M = this->m_proj_parm.hm * aasin(xy_x * this->m_proj_parm.rm * cos(N * this->m_proj_parm.two_r_n) / cos(N));
0099                     xp = 2. * sin(M);
0100                     yp = 2. * sin(N) * cos(M * this->m_proj_parm.two_r_m) / cos(M);
0101                     cAz = cos(Az = aatan2(xp, yp) - this->m_proj_parm.theta);
0102                     z = 2. * aasin(0.5 * boost::math::hypot(xp, yp));
0103                     sz = sin(z);
0104                     cz = cos(z);
0105                     lp_lat = aasin(this->m_proj_parm.sp0 * cz + this->m_proj_parm.cp0 * sz * cAz);
0106                     lp_lon = aatan2(sz * sin(Az),
0107                         this->m_proj_parm.cp0 * cz - this->m_proj_parm.sp0 * sz * cAz);
0108                 }
0109 
0110                 static inline std::string get_name()
0111                 {
0112                     return "oea_spheroid";
0113                 }
0114 
0115             };
0116 
0117             // Oblated Equal Area
0118             template <typename Params, typename Parameters, typename T>
0119             inline void setup_oea(Params const& params, Parameters& par, par_oea<T>& proj_parm)
0120             {
0121                 if (((proj_parm.n = pj_get_param_f<T, srs::spar::n>(params, "n", srs::dpar::n)) <= 0.) ||
0122                     ((proj_parm.m = pj_get_param_f<T, srs::spar::m>(params, "m", srs::dpar::m)) <= 0.)) {
0123                     BOOST_THROW_EXCEPTION( projection_exception(error_invalid_m_or_n) );
0124                 } else {
0125                     proj_parm.theta = pj_get_param_r<T, srs::spar::theta>(params, "theta", srs::dpar::theta);
0126                     proj_parm.sp0 = sin(par.phi0);
0127                     proj_parm.cp0 = cos(par.phi0);
0128                     proj_parm.rn = 1./ proj_parm.n;
0129                     proj_parm.rm = 1./ proj_parm.m;
0130                     proj_parm.two_r_n = 2. * proj_parm.rn;
0131                     proj_parm.two_r_m = 2. * proj_parm.rm;
0132                     proj_parm.hm = 0.5 * proj_parm.m;
0133                     proj_parm.hn = 0.5 * proj_parm.n;
0134                     par.es = 0.;
0135                 }
0136             }
0137 
0138     }} // namespace detail::oea
0139     #endif // doxygen
0140 
0141     /*!
0142         \brief Oblated Equal Area projection
0143         \ingroup projections
0144         \tparam Geographic latlong point type
0145         \tparam Cartesian xy point type
0146         \tparam Parameters parameter type
0147         \par Projection characteristics
0148          - Miscellaneous
0149          - Spheroid
0150         \par Projection parameters
0151          - n (real)
0152          - m (real)
0153          - theta: Theta (degrees)
0154         \par Example
0155         \image html ex_oea.gif
0156     */
0157     template <typename T, typename Parameters>
0158     struct oea_spheroid : public detail::oea::base_oea_spheroid<T, Parameters>
0159     {
0160         template <typename Params>
0161         inline oea_spheroid(Params const& params, Parameters & par)
0162         {
0163             detail::oea::setup_oea(params, par, this->m_proj_parm);
0164         }
0165     };
0166 
0167     #ifndef DOXYGEN_NO_DETAIL
0168     namespace detail
0169     {
0170 
0171         // Static projection
0172         BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_oea, oea_spheroid)
0173 
0174         // Factory entry(s)
0175         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(oea_entry, oea_spheroid)
0176 
0177         BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(oea_init)
0178         {
0179             BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(oea, oea_entry)
0180         }
0181 
0182     } // namespace detail
0183     #endif // doxygen
0184 
0185 } // namespace projections
0186 
0187 }} // namespace boost::geometry
0188 
0189 #endif // BOOST_GEOMETRY_PROJECTIONS_OEA_HPP
0190