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
0041
0042
0043
0044
0045 #ifndef BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
0046 #define BOOST_GEOMETRY_PROJECTIONS_AIRY_HPP
0047
0048 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0049 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0050 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0051 #include <boost/geometry/srs/projections/impl/pj_param.hpp>
0052 #include <boost/geometry/srs/projections/impl/projects.hpp>
0053
0054 #include <boost/geometry/util/math.hpp>
0055
0056 namespace boost { namespace geometry
0057 {
0058
0059 namespace projections
0060 {
0061 #ifndef DOXYGEN_NO_DETAIL
0062 namespace detail { namespace airy
0063 {
0064
0065 static const double epsilon = 1.e-10;
0066 enum mode_type {
0067 n_pole = 0,
0068 s_pole = 1,
0069 equit = 2,
0070 obliq = 3
0071 };
0072
0073 template <typename T>
0074 struct par_airy
0075 {
0076 T p_halfpi;
0077 T sinph0;
0078 T cosph0;
0079 T Cb;
0080 mode_type mode;
0081 bool no_cut;
0082 };
0083
0084 template <typename T, typename Parameters>
0085 struct base_airy_spheroid
0086 {
0087 par_airy<T> m_proj_parm;
0088
0089
0090
0091 inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const
0092 {
0093 static const T half_pi = detail::half_pi<T>();
0094
0095 T sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz;
0096
0097 sinlam = sin(lp_lon);
0098 coslam = cos(lp_lon);
0099 switch (this->m_proj_parm.mode) {
0100 case equit:
0101 case obliq:
0102 sinphi = sin(lp_lat);
0103 cosphi = cos(lp_lat);
0104 cosz = cosphi * coslam;
0105 if (this->m_proj_parm.mode == obliq)
0106 cosz = this->m_proj_parm.sinph0 * sinphi + this->m_proj_parm.cosph0 * cosz;
0107 if (!this->m_proj_parm.no_cut && cosz < -epsilon) {
0108 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
0109 }
0110 if (fabs(s = 1. - cosz) > epsilon) {
0111 t = 0.5 * (1. + cosz);
0112 Krho = -log(t)/s - this->m_proj_parm.Cb / t;
0113 } else
0114 Krho = 0.5 - this->m_proj_parm.Cb;
0115 xy_x = Krho * cosphi * sinlam;
0116 if (this->m_proj_parm.mode == obliq)
0117 xy_y = Krho * (this->m_proj_parm.cosph0 * sinphi -
0118 this->m_proj_parm.sinph0 * cosphi * coslam);
0119 else
0120 xy_y = Krho * sinphi;
0121 break;
0122 case s_pole:
0123 case n_pole:
0124 lp_lat = fabs(this->m_proj_parm.p_halfpi - lp_lat);
0125 if (!this->m_proj_parm.no_cut && (lp_lat - epsilon) > half_pi)
0126 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
0127 if ((lp_lat *= 0.5) > epsilon) {
0128 t = tan(lp_lat);
0129 Krho = -2.*(log(cos(lp_lat)) / t + t * this->m_proj_parm.Cb);
0130 xy_x = Krho * sinlam;
0131 xy_y = Krho * coslam;
0132 if (this->m_proj_parm.mode == n_pole)
0133 xy_y = -xy_y;
0134 } else
0135 xy_x = xy_y = 0.;
0136 }
0137 }
0138
0139 static inline std::string get_name()
0140 {
0141 return "airy_spheroid";
0142 }
0143
0144 };
0145
0146
0147 template <typename Params, typename Parameters, typename T>
0148 inline void setup_airy(Params const& params, Parameters& par, par_airy<T>& proj_parm)
0149 {
0150 static const T half_pi = detail::half_pi<T>();
0151
0152 T beta;
0153
0154 proj_parm.no_cut = pj_get_param_b<srs::spar::no_cut>(params, "no_cut", srs::dpar::no_cut);
0155 beta = 0.5 * (half_pi - pj_get_param_r<T, srs::spar::lat_b>(params, "lat_b", srs::dpar::lat_b));
0156 if (fabs(beta) < epsilon)
0157 proj_parm.Cb = -0.5;
0158 else {
0159 proj_parm.Cb = 1./tan(beta);
0160 proj_parm.Cb *= proj_parm.Cb * log(cos(beta));
0161 }
0162
0163 if (fabs(fabs(par.phi0) - half_pi) < epsilon)
0164 if (par.phi0 < 0.) {
0165 proj_parm.p_halfpi = -half_pi;
0166 proj_parm.mode = s_pole;
0167 } else {
0168 proj_parm.p_halfpi = half_pi;
0169 proj_parm.mode = n_pole;
0170 }
0171 else {
0172 if (fabs(par.phi0) < epsilon)
0173 proj_parm.mode = equit;
0174 else {
0175 proj_parm.mode = obliq;
0176 proj_parm.sinph0 = sin(par.phi0);
0177 proj_parm.cosph0 = cos(par.phi0);
0178 }
0179 }
0180 par.es = 0.;
0181 }
0182
0183 }}
0184 #endif
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 airy_spheroid : public detail::airy::base_airy_spheroid<T, Parameters>
0204 {
0205 template <typename Params>
0206 inline airy_spheroid(Params const& params, Parameters & par)
0207 {
0208 detail::airy::setup_airy(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_F(srs::spar::proj_airy, airy_spheroid)
0218
0219
0220 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(airy_entry, airy_spheroid)
0221
0222 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(airy_init)
0223 {
0224 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(airy, airy_entry)
0225 }
0226
0227 }
0228 #endif
0229
0230 }
0231
0232 }}
0233
0234 #endif
0235