File indexing completed on 2025-01-18 09:35:46
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_SOMERC_HPP
0041 #define BOOST_GEOMETRY_PROJECTIONS_SOMERC_HPP
0042
0043 #include <boost/geometry/util/math.hpp>
0044
0045 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0046 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0047 #include <boost/geometry/srs/projections/impl/projects.hpp>
0048 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0049 #include <boost/geometry/srs/projections/impl/aasincos.hpp>
0050
0051 namespace boost { namespace geometry
0052 {
0053
0054 namespace projections
0055 {
0056 #ifndef DOXYGEN_NO_DETAIL
0057 namespace detail { namespace somerc
0058 {
0059 static const double epsilon = 1.e-10;
0060 static const int n_iter = 6;
0061
0062 template <typename T>
0063 struct par_somerc
0064 {
0065 T K, c, hlf_e, kR, cosp0, sinp0;
0066 };
0067
0068 template <typename T, typename Parameters>
0069 struct base_somerc_ellipsoid
0070 {
0071 par_somerc<T> m_proj_parm;
0072
0073
0074
0075 inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0076 {
0077 static const T fourth_pi = detail::fourth_pi<T>();
0078 static const T half_pi = detail::half_pi<T>();
0079
0080 T phip, lamp, phipp, lampp, sp, cp;
0081
0082 sp = par.e * sin(lp_lat);
0083 phip = 2.* atan( exp( this->m_proj_parm.c * (
0084 log(tan(fourth_pi + 0.5 * lp_lat)) - this->m_proj_parm.hlf_e * log((1. + sp)/(1. - sp)))
0085 + this->m_proj_parm.K)) - half_pi;
0086 lamp = this->m_proj_parm.c * lp_lon;
0087 cp = cos(phip);
0088 phipp = aasin(this->m_proj_parm.cosp0 * sin(phip) - this->m_proj_parm.sinp0 * cp * cos(lamp));
0089 lampp = aasin(cp * sin(lamp) / cos(phipp));
0090 xy_x = this->m_proj_parm.kR * lampp;
0091 xy_y = this->m_proj_parm.kR * log(tan(fourth_pi + 0.5 * phipp));
0092 }
0093
0094
0095
0096 inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0097 {
0098 static const T fourth_pi = detail::fourth_pi<T>();
0099
0100 T phip, lamp, phipp, lampp, cp, esp, con, delp;
0101 int i;
0102
0103 phipp = 2. * (atan(exp(xy_y / this->m_proj_parm.kR)) - fourth_pi);
0104 lampp = xy_x / this->m_proj_parm.kR;
0105 cp = cos(phipp);
0106 phip = aasin(this->m_proj_parm.cosp0 * sin(phipp) + this->m_proj_parm.sinp0 * cp * cos(lampp));
0107 lamp = aasin(cp * sin(lampp) / cos(phip));
0108 con = (this->m_proj_parm.K - log(tan(fourth_pi + 0.5 * phip)))/this->m_proj_parm.c;
0109 for (i = n_iter; i ; --i) {
0110 esp = par.e * sin(phip);
0111 delp = (con + log(tan(fourth_pi + 0.5 * phip)) - this->m_proj_parm.hlf_e *
0112 log((1. + esp)/(1. - esp)) ) *
0113 (1. - esp * esp) * cos(phip) * par.rone_es;
0114 phip -= delp;
0115 if (fabs(delp) < epsilon)
0116 break;
0117 }
0118 if (i) {
0119 lp_lat = phip;
0120 lp_lon = lamp / this->m_proj_parm.c;
0121 } else {
0122 BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) );
0123 }
0124 }
0125
0126 static inline std::string get_name()
0127 {
0128 return "somerc_ellipsoid";
0129 }
0130
0131 };
0132
0133
0134 template <typename Parameters, typename T>
0135 inline void setup_somerc(Parameters const& par, par_somerc<T>& proj_parm)
0136 {
0137 static const T fourth_pi = detail::fourth_pi<T>();
0138
0139 T cp, phip0, sp;
0140
0141 proj_parm.hlf_e = 0.5 * par.e;
0142 cp = cos(par.phi0);
0143 cp *= cp;
0144 proj_parm.c = sqrt(1 + par.es * cp * cp * par.rone_es);
0145 sp = sin(par.phi0);
0146 proj_parm.cosp0 = cos( phip0 = aasin(proj_parm.sinp0 = sp / proj_parm.c) );
0147 sp *= par.e;
0148 proj_parm.K = log(tan(fourth_pi + 0.5 * phip0)) - proj_parm.c * (
0149 log(tan(fourth_pi + 0.5 * par.phi0)) - proj_parm.hlf_e *
0150 log((1. + sp) / (1. - sp)));
0151 proj_parm.kR = par.k0 * sqrt(par.one_es) / (1. - sp * sp);
0152 }
0153
0154 }}
0155 #endif
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170 template <typename T, typename Parameters>
0171 struct somerc_ellipsoid : public detail::somerc::base_somerc_ellipsoid<T, Parameters>
0172 {
0173 template <typename Params>
0174 inline somerc_ellipsoid(Params const& , Parameters const& par)
0175 {
0176 detail::somerc::setup_somerc(par, this->m_proj_parm);
0177 }
0178 };
0179
0180 #ifndef DOXYGEN_NO_DETAIL
0181 namespace detail
0182 {
0183
0184
0185 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_somerc, somerc_ellipsoid)
0186
0187
0188 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(somerc_entry, somerc_ellipsoid)
0189
0190 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(somerc_init)
0191 {
0192 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(somerc, somerc_entry)
0193 }
0194
0195 }
0196 #endif
0197
0198 }
0199
0200 }}
0201
0202 #endif
0203