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 // 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 40 #ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP 41 #define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP 42 43 #include <boost/geometry/srs/projections/impl/base_static.hpp> 44 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp> 45 #include <boost/geometry/srs/projections/impl/factory_entry.hpp> 46 #include <boost/geometry/srs/projections/impl/pj_auth.hpp> 47 #include <boost/geometry/srs/projections/impl/pj_param.hpp> 48 #include <boost/geometry/srs/projections/impl/pj_qsfn.hpp> 49 #include <boost/geometry/srs/projections/impl/projects.hpp> 50 51 #include <boost/geometry/util/math.hpp> 52 53 namespace boost { namespace geometry 54 { 55 56 namespace projections 57 { 58 #ifndef DOXYGEN_NO_DETAIL 59 namespace detail { namespace cea 60 { 61 62 static const double epsilon = 1e-10; 63 64 template <typename T> 65 struct par_cea 66 { 67 T qp; 68 detail::apa<T> apa; 69 }; 70 71 template <typename T, typename Parameters> 72 struct base_cea_ellipsoid 73 { 74 par_cea<T> m_proj_parm; 75 76 // FORWARD(e_forward) spheroid 77 // Project coordinates from geographic (lon, lat) to cartesian (x, y) fwdboost::geometry::projections::detail::cea::base_cea_ellipsoid78 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const 79 { 80 xy_x = par.k0 * lp_lon; 81 xy_y = .5 * pj_qsfn(sin(lp_lat), par.e, par.one_es) / par.k0; 82 } 83 84 // INVERSE(e_inverse) spheroid 85 // Project coordinates from cartesian (x, y) to geographic (lon, lat) invboost::geometry::projections::detail::cea::base_cea_ellipsoid86 inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const 87 { 88 lp_lat = pj_authlat(asin( 2. * xy_y * par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa); 89 lp_lon = xy_x / par.k0; 90 } 91 get_nameboost::geometry::projections::detail::cea::base_cea_ellipsoid92 static inline std::string get_name() 93 { 94 return "cea_ellipsoid"; 95 } 96 97 }; 98 99 template <typename T, typename Parameters> 100 struct base_cea_spheroid 101 { 102 par_cea<T> m_proj_parm; 103 104 // FORWARD(s_forward) spheroid 105 // Project coordinates from geographic (lon, lat) to cartesian (x, y) fwdboost::geometry::projections::detail::cea::base_cea_spheroid106 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const 107 { 108 xy_x = par.k0 * lp_lon; 109 xy_y = sin(lp_lat) / par.k0; 110 } 111 112 // INVERSE(s_inverse) spheroid 113 // Project coordinates from cartesian (x, y) to geographic (lon, lat) invboost::geometry::projections::detail::cea::base_cea_spheroid114 inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const 115 { 116 static const T half_pi = detail::half_pi<T>(); 117 118 T t; 119 120 if ((t = fabs(xy_y *= par.k0)) - epsilon <= 1.) { 121 if (t >= 1.) 122 lp_lat = xy_y < 0. ? -half_pi : half_pi; 123 else 124 lp_lat = asin(xy_y); 125 lp_lon = xy_x / par.k0; 126 } else 127 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); 128 } 129 get_nameboost::geometry::projections::detail::cea::base_cea_spheroid130 static inline std::string get_name() 131 { 132 return "cea_spheroid"; 133 } 134 135 }; 136 137 // Equal Area Cylindrical 138 template <typename Params, typename Parameters, typename T> setup_cea(Params const & params,Parameters & par,par_cea<T> & proj_parm)139 inline void setup_cea(Params const& params, Parameters& par, par_cea<T>& proj_parm) 140 { 141 T t = 0; 142 143 if (pj_param_r<srs::spar::lat_ts>(params, "lat_ts", srs::dpar::lat_ts, t)) { 144 par.k0 = cos(t); 145 if (par.k0 < 0.) { 146 BOOST_THROW_EXCEPTION( projection_exception(error_lat_ts_larger_than_90) ); 147 } 148 } 149 if (par.es != 0.0) { 150 t = sin(t); 151 par.k0 /= sqrt(1. - par.es * t * t); 152 par.e = sqrt(par.es); 153 proj_parm.apa = pj_authset<T>(par.es); 154 155 proj_parm.qp = pj_qsfn(T(1), par.e, par.one_es); 156 } 157 } 158 159 }} // namespace detail::cea 160 #endif // doxygen 161 162 /*! 163 \brief Equal Area Cylindrical projection 164 \ingroup projections 165 \tparam Geographic latlong point type 166 \tparam Cartesian xy point type 167 \tparam Parameters parameter type 168 \par Projection characteristics 169 - Cylindrical 170 - Spheroid 171 - Ellipsoid 172 \par Projection parameters 173 - lat_ts: Latitude of true scale (degrees) 174 \par Example 175 \image html ex_cea.gif 176 */ 177 template <typename T, typename Parameters> 178 struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid<T, Parameters> 179 { 180 template <typename Params> cea_ellipsoidboost::geometry::projections::cea_ellipsoid181 inline cea_ellipsoid(Params const& params, Parameters & par) 182 { 183 detail::cea::setup_cea(params, par, this->m_proj_parm); 184 } 185 }; 186 187 /*! 188 \brief Equal Area Cylindrical projection 189 \ingroup projections 190 \tparam Geographic latlong point type 191 \tparam Cartesian xy point type 192 \tparam Parameters parameter type 193 \par Projection characteristics 194 - Cylindrical 195 - Spheroid 196 - Ellipsoid 197 \par Projection parameters 198 - lat_ts: Latitude of true scale (degrees) 199 \par Example 200 \image html ex_cea.gif 201 */ 202 template <typename T, typename Parameters> 203 struct cea_spheroid : public detail::cea::base_cea_spheroid<T, Parameters> 204 { 205 template <typename Params> cea_spheroidboost::geometry::projections::cea_spheroid206 inline cea_spheroid(Params const& params, Parameters & par) 207 { 208 detail::cea::setup_cea(params, par, this->m_proj_parm); 209 } 210 }; 211 212 #ifndef DOXYGEN_NO_DETAIL 213 namespace detail 214 { 215 216 // Static projection BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_cea,cea_spheroid,cea_ellipsoid)217 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_cea, cea_spheroid, cea_ellipsoid) 218 219 // Factory entry(s) 220 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(cea_entry, cea_spheroid, cea_ellipsoid) 221 222 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(cea_init) 223 { 224 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(cea, cea_entry); 225 } 226 227 } // namespace detail 228 #endif // doxygen 229 230 } // namespace projections 231 232 }} // namespace boost::geometry 233 234 #endif // BOOST_GEOMETRY_PROJECTIONS_CEA_HPP 235 236