File indexing completed on 2025-01-18 09:35:44
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_MOLL_HPP
0041 #define BOOST_GEOMETRY_PROJECTIONS_MOLL_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 moll
0058 {
0059
0060 static const int max_iter = 10;
0061 static const double loop_tol = 1e-7;
0062
0063 template <typename T>
0064 struct par_moll
0065 {
0066 T C_x, C_y, C_p;
0067 };
0068
0069 template <typename T, typename Parameters>
0070 struct base_moll_spheroid
0071 {
0072 par_moll<T> m_proj_parm;
0073
0074
0075
0076 inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const
0077 {
0078 static const T half_pi = detail::half_pi<T>();
0079
0080 T k, V;
0081 int i;
0082
0083 k = this->m_proj_parm.C_p * sin(lp_lat);
0084 for (i = max_iter; i ; --i) {
0085 lp_lat -= V = (lp_lat + sin(lp_lat) - k) /
0086 (1. + cos(lp_lat));
0087 if (fabs(V) < loop_tol)
0088 break;
0089 }
0090 if (!i)
0091 lp_lat = (lp_lat < 0.) ? -half_pi : half_pi;
0092 else
0093 lp_lat *= 0.5;
0094 xy_x = this->m_proj_parm.C_x * lp_lon * cos(lp_lat);
0095 xy_y = this->m_proj_parm.C_y * sin(lp_lat);
0096 }
0097
0098
0099
0100 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0101 {
0102 static const T pi = detail::pi<T>();
0103
0104 lp_lat = aasin(xy_y / this->m_proj_parm.C_y);
0105 lp_lon = xy_x / (this->m_proj_parm.C_x * cos(lp_lat));
0106 if (fabs(lp_lon) < pi) {
0107 lp_lat += lp_lat;
0108 lp_lat = aasin((lp_lat + sin(lp_lat)) / this->m_proj_parm.C_p);
0109 } else {
0110 lp_lon = lp_lat = HUGE_VAL;
0111 }
0112 }
0113
0114 static inline std::string get_name()
0115 {
0116 return "moll_spheroid";
0117 }
0118
0119 };
0120
0121 template <typename Parameters, typename T>
0122 inline void setup(Parameters& par, par_moll<T>& proj_parm, T const& p)
0123 {
0124 T r, sp, p2 = p + p;
0125
0126 par.es = 0;
0127 sp = sin(p);
0128 r = sqrt(geometry::math::two_pi<T>() * sp / (p2 + sin(p2)));
0129
0130 proj_parm.C_x = 2. * r / geometry::math::pi<T>();
0131 proj_parm.C_y = r / sp;
0132 proj_parm.C_p = p2 + sin(p2);
0133 }
0134
0135
0136
0137 template <typename Parameters, typename T>
0138 inline void setup_moll(Parameters& par, par_moll<T>& proj_parm)
0139 {
0140 setup(par, proj_parm, geometry::math::half_pi<T>());
0141 }
0142
0143
0144 template <typename Parameters, typename T>
0145 inline void setup_wag4(Parameters& par, par_moll<T>& proj_parm)
0146 {
0147 setup(par, proj_parm, geometry::math::pi<T>()/3.);
0148 }
0149
0150
0151 template <typename Parameters, typename T>
0152 inline void setup_wag5(Parameters& par, par_moll<T>& proj_parm)
0153 {
0154 par.es = 0;
0155 proj_parm.C_x = 0.90977;
0156 proj_parm.C_y = 1.65014;
0157 proj_parm.C_p = 3.00896;
0158 }
0159
0160 }}
0161 #endif
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 template <typename T, typename Parameters>
0176 struct moll_spheroid : public detail::moll::base_moll_spheroid<T, Parameters>
0177 {
0178 template <typename Params>
0179 inline moll_spheroid(Params const& , Parameters & par)
0180 {
0181 detail::moll::setup_moll(par, this->m_proj_parm);
0182 }
0183 };
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 template <typename T, typename Parameters>
0198 struct wag4_spheroid : public detail::moll::base_moll_spheroid<T, Parameters>
0199 {
0200 template <typename Params>
0201 inline wag4_spheroid(Params const& , Parameters & par)
0202 {
0203 detail::moll::setup_wag4(par, this->m_proj_parm);
0204 }
0205 };
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 template <typename T, typename Parameters>
0220 struct wag5_spheroid : public detail::moll::base_moll_spheroid<T, Parameters>
0221 {
0222 template <typename Params>
0223 inline wag5_spheroid(Params const& , Parameters & par)
0224 {
0225 detail::moll::setup_wag5(par, this->m_proj_parm);
0226 }
0227 };
0228
0229 #ifndef DOXYGEN_NO_DETAIL
0230 namespace detail
0231 {
0232
0233
0234 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_moll, moll_spheroid)
0235 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag4, wag4_spheroid)
0236 BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag5, wag5_spheroid)
0237
0238
0239 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(moll_entry, moll_spheroid)
0240 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(wag4_entry, wag4_spheroid)
0241 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(wag5_entry, wag5_spheroid)
0242
0243 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(moll_init)
0244 {
0245 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(moll, moll_entry);
0246 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(wag4, wag4_entry);
0247 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(wag5, wag5_entry);
0248 }
0249
0250 }
0251 #endif
0252
0253 }
0254
0255 }}
0256
0257 #endif
0258