File indexing completed on 2025-01-18 09:35:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifndef BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
0041 #define BOOST_GEOMETRY_PROJECTIONS_CEA_HPP
0042
0043 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0044 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0045 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0046 #include <boost/geometry/srs/projections/impl/pj_auth.hpp>
0047 #include <boost/geometry/srs/projections/impl/pj_param.hpp>
0048 #include <boost/geometry/srs/projections/impl/pj_qsfn.hpp>
0049 #include <boost/geometry/srs/projections/impl/projects.hpp>
0050
0051 #include <boost/geometry/util/math.hpp>
0052
0053 namespace boost { namespace geometry
0054 {
0055
0056 namespace projections
0057 {
0058 #ifndef DOXYGEN_NO_DETAIL
0059 namespace detail { namespace cea
0060 {
0061
0062 static const double epsilon = 1e-10;
0063
0064 template <typename T>
0065 struct par_cea
0066 {
0067 T qp;
0068 detail::apa<T> apa;
0069 };
0070
0071 template <typename T, typename Parameters>
0072 struct base_cea_ellipsoid
0073 {
0074 par_cea<T> m_proj_parm;
0075
0076
0077
0078 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0079 {
0080 xy_x = par.k0 * lp_lon;
0081 xy_y = .5 * pj_qsfn(sin(lp_lat), par.e, par.one_es) / par.k0;
0082 }
0083
0084
0085
0086 inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0087 {
0088 lp_lat = pj_authlat(asin( 2. * xy_y * par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa);
0089 lp_lon = xy_x / par.k0;
0090 }
0091
0092 static inline std::string get_name()
0093 {
0094 return "cea_ellipsoid";
0095 }
0096
0097 };
0098
0099 template <typename T, typename Parameters>
0100 struct base_cea_spheroid
0101 {
0102 par_cea<T> m_proj_parm;
0103
0104
0105
0106 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0107 {
0108 xy_x = par.k0 * lp_lon;
0109 xy_y = sin(lp_lat) / par.k0;
0110 }
0111
0112
0113
0114 inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const
0115 {
0116 static const T half_pi = detail::half_pi<T>();
0117
0118 T t;
0119
0120 if ((t = fabs(xy_y *= par.k0)) - epsilon <= 1.) {
0121 if (t >= 1.)
0122 lp_lat = xy_y < 0. ? -half_pi : half_pi;
0123 else
0124 lp_lat = asin(xy_y);
0125 lp_lon = xy_x / par.k0;
0126 } else
0127 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
0128 }
0129
0130 static inline std::string get_name()
0131 {
0132 return "cea_spheroid";
0133 }
0134
0135 };
0136
0137
0138 template <typename Params, typename Parameters, typename T>
0139 inline void setup_cea(Params const& params, Parameters& par, par_cea<T>& proj_parm)
0140 {
0141 T t = 0;
0142
0143 if (pj_param_r<srs::spar::lat_ts>(params, "lat_ts", srs::dpar::lat_ts, t)) {
0144 par.k0 = cos(t);
0145 if (par.k0 < 0.) {
0146 BOOST_THROW_EXCEPTION( projection_exception(error_lat_ts_larger_than_90) );
0147 }
0148 }
0149 if (par.es != 0.0) {
0150 t = sin(t);
0151 par.k0 /= sqrt(1. - par.es * t * t);
0152 par.e = sqrt(par.es);
0153 proj_parm.apa = pj_authset<T>(par.es);
0154
0155 proj_parm.qp = pj_qsfn(T(1), par.e, par.one_es);
0156 }
0157 }
0158
0159 }}
0160 #endif
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 template <typename T, typename Parameters>
0178 struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid<T, Parameters>
0179 {
0180 template <typename Params>
0181 inline cea_ellipsoid(Params const& params, Parameters & par)
0182 {
0183 detail::cea::setup_cea(params, par, this->m_proj_parm);
0184 }
0185 };
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 template <typename T, typename Parameters>
0203 struct cea_spheroid : public detail::cea::base_cea_spheroid<T, Parameters>
0204 {
0205 template <typename Params>
0206 inline cea_spheroid(Params const& params, Parameters & par)
0207 {
0208 detail::cea::setup_cea(params, par, this->m_proj_parm);
0209 }
0210 };
0211
0212 #ifndef DOXYGEN_NO_DETAIL
0213 namespace detail
0214 {
0215
0216
0217 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_cea, cea_spheroid, cea_ellipsoid)
0218
0219
0220 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(cea_entry, cea_spheroid, cea_ellipsoid)
0221
0222 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(cea_init)
0223 {
0224 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(cea, cea_entry);
0225 }
0226
0227 }
0228 #endif
0229
0230 }
0231
0232 }}
0233
0234 #endif
0235