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 #ifndef BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
0042 #define BOOST_GEOMETRY_PROJECTIONS_CASS_HPP
0043
0044 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0045 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0046 #include <boost/geometry/srs/projections/impl/projects.hpp>
0047 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0048 #include <boost/geometry/srs/projections/impl/pj_generic_inverse.hpp>
0049 #include <boost/geometry/srs/projections/impl/pj_mlfn.hpp>
0050 #include <boost/geometry/srs/projections/impl/pj_param.hpp>
0051
0052 namespace boost { namespace geometry
0053 {
0054
0055 namespace projections
0056 {
0057 #ifndef DOXYGEN_NO_DETAIL
0058 namespace detail { namespace cass
0059 {
0060
0061
0062
0063
0064
0065
0066
0067
0068 template <typename T>
0069 inline T C1() { return .16666666666666666666666666666666666666; }
0070 template <typename T>
0071 inline T C2() { return .00833333333333333333333333333333333333; }
0072 template <typename T>
0073 inline T C3() { return .04166666666666666666666666666666666666; }
0074 template <typename T>
0075 inline T C4() { return .33333333333333333333333333333333333333; }
0076 template <typename T>
0077 inline T C5() { return .06666666666666666666666666666666666666; }
0078
0079 template <typename T>
0080 struct par_cass
0081 {
0082 T m0;
0083 detail::en<T> en;
0084 bool hyperbolic;
0085 };
0086
0087 template <typename T, typename Parameters>
0088 struct base_cass_ellipsoid
0089 {
0090 par_cass<T> m_proj_parm;
0091
0092
0093
0094 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat,
0095 T& xy_x, T& xy_y) const
0096 {
0097 static T const C1 = cass::C1<T>();
0098 static T const C2 = cass::C2<T>();
0099 static T const C3 = cass::C3<T>();
0100
0101 T sinlplat = sin(lp_lat);
0102 T c = cos(lp_lat);
0103 xy_y = pj_mlfn(lp_lat, sinlplat, c, this->m_proj_parm.en);
0104 T n_square = 1./(1. - par.es * sinlplat * sinlplat);
0105 T n = sqrt(n_square);
0106 T tn = tan(lp_lat);
0107 T t = tn * tn;
0108 T a1 = lp_lon * c;
0109 c *= par.es * c / (1 - par.es);
0110 T a2 = a1 * a1;
0111 xy_x = n * a1 * (1. - a2 * t *
0112 (C1 - (8. - t + 8. * c) * a2 * C2));
0113 xy_y -= this->m_proj_parm.m0 - n * tn * a2 *
0114 (.5 + (5. - t + 6. * c) * a2 * C3);
0115 if ( this->m_proj_parm.hyperbolic )
0116 {
0117 T const rho = n_square * (1. - par.es) * n;
0118 xy_y -= xy_y * xy_y * xy_y / (6 * rho * n);
0119 }
0120 }
0121
0122
0123
0124 inline void inv(Parameters const& par, T const& xy_x, T const& xy_y,
0125 T& lp_lon, T& lp_lat) const
0126 {
0127 static const T C3 = cass::C3<T>();
0128 static const T C4 = cass::C4<T>();
0129 static const T C5 = cass::C5<T>();
0130
0131 T ph1;
0132
0133 ph1 = pj_inv_mlfn(this->m_proj_parm.m0 + xy_y, par.es, this->m_proj_parm.en);
0134 T tn = tan(ph1); T t = tn * tn;
0135 T n = sin(ph1);
0136 T r = 1. / (1. - par.es * n * n);
0137 n = sqrt(r);
0138 r *= (1. - par.es) * n;
0139 T dd = xy_x / n;
0140 T d2 = dd * dd;
0141 lp_lat = ph1 - (n * tn / r) * d2 *
0142 (.5 - (1. + 3. * t) * d2 * C3);
0143 lp_lon = dd * (1. + t * d2 *
0144 (-C4 + (1. + 3. * t) * d2 * C5)) / cos(ph1);
0145 if ( this->m_proj_parm.hyperbolic )
0146 {
0147
0148
0149
0150 pj_generic_inverse_2d(xy_x, xy_y, par, this, lp_lat, lp_lon);
0151 }
0152 }
0153
0154 static inline std::string get_name()
0155 {
0156 return "cass_ellipsoid";
0157 }
0158
0159 };
0160
0161 template <typename T, typename Parameters>
0162 struct base_cass_spheroid
0163 {
0164 par_cass<T> m_proj_parm;
0165
0166
0167
0168 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat,
0169 T& xy_x, T& xy_y) const
0170 {
0171 xy_x = asin(cos(lp_lat) * sin(lp_lon));
0172 xy_y = atan2(tan(lp_lat) , cos(lp_lon)) - par.phi0;
0173 }
0174
0175
0176
0177 inline void inv(Parameters const& par, T const& xy_x, T const& xy_y,
0178 T& lp_lon, T& lp_lat) const
0179 {
0180 T dd = xy_y + par.phi0;
0181 lp_lat = asin(sin(dd) * cos(xy_x));
0182 lp_lon = atan2(tan(xy_x), cos(dd));
0183 }
0184
0185 static inline std::string get_name()
0186 {
0187 return "cass_spheroid";
0188 }
0189
0190 };
0191
0192
0193 template <typename Params, typename Parameters, typename T>
0194 inline void setup_cass(Params const& params, Parameters& par, par_cass<T>& proj_parm)
0195 {
0196 if (par.es) {
0197 proj_parm.en = pj_enfn<T>(par.es);
0198 proj_parm.m0 = pj_mlfn(par.phi0, sin(par.phi0), cos(par.phi0), proj_parm.en);
0199 } else {
0200 }
0201 proj_parm.hyperbolic = false;
0202 if (pj_param_exists<srs::spar::hyperbolic>(params, "hyperbolic", srs::dpar::hyperbolic))
0203 proj_parm.hyperbolic = true;
0204
0205 }
0206
0207 }}
0208 #endif
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223 template <typename T, typename Parameters>
0224 struct cass_ellipsoid : public detail::cass::base_cass_ellipsoid<T, Parameters>
0225 {
0226 template <typename Params>
0227 inline cass_ellipsoid(Params const& params, Parameters const& par)
0228 {
0229 detail::cass::setup_cass(params, par, this->m_proj_parm);
0230 }
0231 };
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 template <typename T, typename Parameters>
0247 struct cass_spheroid : public detail::cass::base_cass_spheroid<T, Parameters>
0248 {
0249 template <typename Params>
0250 inline cass_spheroid(Params const& params, Parameters const& par)
0251 {
0252 detail::cass::setup_cass(params, par, this->m_proj_parm);
0253 }
0254 };
0255
0256 #ifndef DOXYGEN_NO_DETAIL
0257 namespace detail
0258 {
0259
0260
0261 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_cass, cass_spheroid,
0262 cass_ellipsoid)
0263
0264
0265 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(cass_entry, cass_spheroid, cass_ellipsoid)
0266
0267 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(cass_init)
0268 {
0269 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(cass, cass_entry);
0270 }
0271
0272 }
0273 #endif
0274
0275 }
0276
0277 }}
0278
0279 #endif
0280