Warning, file /include/boost/geometry/srs/projections/proj/ob_tran.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
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 #ifndef BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
0043 #define BOOST_GEOMETRY_PROJECTIONS_OB_TRAN_HPP
0044
0045 #include <memory>
0046 #include <type_traits>
0047
0048 #include <boost/geometry/core/static_assert.hpp>
0049 #include <boost/geometry/srs/projections/impl/aasincos.hpp>
0050 #include <boost/geometry/srs/projections/impl/base_static.hpp>
0051 #include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
0052 #include <boost/geometry/srs/projections/impl/factory_entry.hpp>
0053 #include <boost/geometry/srs/projections/impl/pj_ell_set.hpp>
0054 #include <boost/geometry/srs/projections/impl/projects.hpp>
0055 #include <boost/geometry/util/math.hpp>
0056
0057 namespace boost { namespace geometry
0058 {
0059
0060 namespace projections
0061 {
0062 #ifndef DOXYGEN_NO_DETAIL
0063 namespace detail {
0064
0065
0066 template <typename T>
0067 inline detail::dynamic_wrapper_b<T, projections::parameters<T> >*
0068 create_new(srs::detail::proj4_parameters const& params,
0069 projections::parameters<T> const& parameters);
0070
0071 template <typename T>
0072 inline detail::dynamic_wrapper_b<T, projections::parameters<T> >*
0073 create_new(srs::dpar::parameters<T> const& params,
0074 projections::parameters<T> const& parameters);
0075
0076 }
0077
0078 namespace detail { namespace ob_tran
0079 {
0080
0081 static const double tolerance = 1e-10;
0082
0083 template <typename Parameters>
0084 inline Parameters o_proj_parameters(srs::detail::proj4_parameters const& params,
0085 Parameters const& par)
0086 {
0087
0088 Parameters pj = par;
0089
0090
0091 pj.id = pj_get_param_s(params, "o_proj");
0092 if (pj.id.is_unknown())
0093 BOOST_THROW_EXCEPTION( projection_exception(error_no_rotation_proj) );
0094
0095
0096 if( pj.id.name == "ob_tran")
0097 BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_find_proj) );
0098
0099
0100
0101
0102
0103
0104 return pj;
0105 }
0106
0107 template <typename T, typename Parameters>
0108 inline Parameters o_proj_parameters(srs::dpar::parameters<T> const& params,
0109 Parameters const& par)
0110 {
0111
0112 Parameters pj = par;
0113
0114
0115 typename srs::dpar::parameters<T>::const_iterator
0116 it = pj_param_find(params, srs::dpar::o_proj);
0117 if (it != params.end())
0118 pj.id = static_cast<srs::dpar::value_proj>(it->template get_value<int>());
0119 else
0120 BOOST_THROW_EXCEPTION( projection_exception(error_no_rotation_proj) );
0121
0122
0123 if( pj.id.id == srs::dpar::proj_ob_tran)
0124 BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_find_proj) );
0125
0126
0127
0128
0129
0130
0131 return pj;
0132 }
0133
0134 template <typename ...Ps, typename Parameters>
0135 inline Parameters o_proj_parameters(srs::spar::parameters<Ps...> const& ,
0136 Parameters const& par)
0137 {
0138
0139 Parameters pj = par;
0140
0141
0142 typedef srs::spar::parameters<Ps...> params_type;
0143 typedef typename geometry::tuples::find_if
0144 <
0145 params_type,
0146 srs::spar::detail::is_param_t<srs::spar::o_proj>::pred
0147 >::type o_proj_type;
0148
0149 static const bool is_found = geometry::tuples::is_found<o_proj_type>::value;
0150 BOOST_GEOMETRY_STATIC_ASSERT((is_found),
0151 "Rotation projection not specified.",
0152 params_type);
0153
0154 typedef typename o_proj_type::type proj_type;
0155 static const bool is_specialized = srs::spar::detail::proj_traits<proj_type>::is_specialized;
0156 BOOST_GEOMETRY_STATIC_ASSERT((is_specialized),
0157 "Rotation projection not specified.",
0158 params_type);
0159
0160 pj.id = srs::spar::detail::proj_traits<proj_type>::id;
0161
0162
0163 static const bool is_non_resursive = ! std::is_same<proj_type, srs::spar::proj_ob_tran>::value;
0164 BOOST_GEOMETRY_STATIC_ASSERT((is_non_resursive),
0165 "o_proj parameter can not be set to ob_tran projection.",
0166 params_type);
0167
0168
0169
0170
0171
0172
0173 return pj;
0174 }
0175
0176
0177
0178
0179
0180
0181 template <typename T, typename Parameters>
0182 struct par_ob_tran
0183 {
0184 template <typename Params>
0185 par_ob_tran(Params const& params, Parameters const& par)
0186 : link(projections::detail::create_new(params, o_proj_parameters(params, par)))
0187 {
0188 if (! link.get())
0189 BOOST_THROW_EXCEPTION( projection_exception(error_unknown_projection_id) );
0190 }
0191
0192 inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0193 {
0194 link->fwd(link->params(), lp_lon, lp_lat, xy_x, xy_y);
0195 }
0196
0197 inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0198 {
0199 link->inv(link->params(), xy_x, xy_y, lp_lon, lp_lat);
0200 }
0201
0202 std::shared_ptr<dynamic_wrapper_b<T, Parameters> > link;
0203 T lamp = 0;
0204 T cphip = 0;
0205 T sphip = 0;
0206 };
0207
0208 template <typename StaticParameters, typename T, typename Parameters>
0209 struct par_ob_tran_static
0210 {
0211
0212 typedef typename srs::spar::detail::pick_o_proj_tag
0213 <
0214 StaticParameters
0215 >::type o_proj_tag;
0216
0217
0218 static const bool is_o_proj_not_ob_tran = ! std::is_same<o_proj_tag, srs::spar::proj_ob_tran>::value;
0219 BOOST_GEOMETRY_STATIC_ASSERT((is_o_proj_not_ob_tran),
0220 "o_proj parameter can not be set to ob_tran projection.",
0221 StaticParameters);
0222
0223 typedef typename projections::detail::static_projection_type
0224 <
0225 o_proj_tag,
0226
0227
0228 typename projections::detail::static_srs_tag<StaticParameters>::type,
0229 StaticParameters,
0230 T,
0231 Parameters
0232 >::type projection_type;
0233
0234 par_ob_tran_static(StaticParameters const& params, Parameters const& par)
0235 : link(params, o_proj_parameters(params, par))
0236 {}
0237
0238 inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0239 {
0240 link.fwd(link.params(), lp_lon, lp_lat, xy_x, xy_y);
0241 }
0242
0243 inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0244 {
0245 link.inv(link.params(), xy_x, xy_y, lp_lon, lp_lat);
0246 }
0247
0248 projection_type link;
0249 T lamp = 0;
0250 T cphip = 0;
0251 T sphip = 0;
0252 };
0253
0254 template <typename T, typename Par>
0255 inline void o_forward(T lp_lon, T lp_lat, T& xy_x, T& xy_y, Par const& proj_parm)
0256 {
0257 T coslam, sinphi, cosphi;
0258
0259 coslam = cos(lp_lon);
0260 sinphi = sin(lp_lat);
0261 cosphi = cos(lp_lat);
0262 lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam +
0263 proj_parm.cphip * sinphi) + proj_parm.lamp);
0264 lp_lat = aasin(proj_parm.sphip * sinphi - proj_parm.cphip * cosphi * coslam);
0265
0266 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
0267 }
0268
0269 template <typename T, typename Par>
0270 inline void o_inverse(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm)
0271 {
0272 T coslam, sinphi, cosphi;
0273
0274 proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat);
0275 if (lp_lon != HUGE_VAL) {
0276 coslam = cos(lp_lon -= proj_parm.lamp);
0277 sinphi = sin(lp_lat);
0278 cosphi = cos(lp_lat);
0279 lp_lat = aasin(proj_parm.sphip * sinphi + proj_parm.cphip * cosphi * coslam);
0280 lp_lon = aatan2(cosphi * sin(lp_lon), proj_parm.sphip * cosphi * coslam -
0281 proj_parm.cphip * sinphi);
0282 }
0283 }
0284
0285 template <typename T, typename Par>
0286 inline void t_forward(T lp_lon, T lp_lat, T& xy_x, T& xy_y, Par const& proj_parm)
0287 {
0288 T cosphi, coslam;
0289
0290 cosphi = cos(lp_lat);
0291 coslam = cos(lp_lon);
0292 lp_lon = adjlon(aatan2(cosphi * sin(lp_lon), sin(lp_lat)) + proj_parm.lamp);
0293 lp_lat = aasin(- cosphi * coslam);
0294
0295 proj_parm.fwd(lp_lon, lp_lat, xy_x, xy_y);
0296 }
0297
0298 template <typename T, typename Par>
0299 inline void t_inverse(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat, Par const& proj_parm)
0300 {
0301 T cosphi, t;
0302
0303 proj_parm.inv(xy_x, xy_y, lp_lon, lp_lat);
0304 if (lp_lon != HUGE_VAL) {
0305 cosphi = cos(lp_lat);
0306 t = lp_lon - proj_parm.lamp;
0307 lp_lon = aatan2(cosphi * sin(t), - sin(lp_lat));
0308 lp_lat = aasin(cosphi * cos(t));
0309 }
0310 }
0311
0312
0313 template <typename T, typename Params, typename Parameters, typename ProjParameters>
0314 inline T setup_ob_tran(Params const& params, Parameters & , ProjParameters& proj_parm)
0315 {
0316 static const T half_pi = detail::half_pi<T>();
0317
0318 T phip, alpha;
0319
0320
0321
0322
0323
0324
0325 if (pj_param_r<srs::spar::o_alpha>(params, "o_alpha", srs::dpar::o_alpha, alpha)) {
0326 T lamc, phic;
0327
0328 lamc = pj_get_param_r<T, srs::spar::o_lon_c>(params, "o_lon_c", srs::dpar::o_lon_c);
0329 phic = pj_get_param_r<T, srs::spar::o_lon_c>(params, "o_lat_c", srs::dpar::o_lat_c);
0330
0331
0332 if (fabs(fabs(phic) - half_pi) <= tolerance)
0333 BOOST_THROW_EXCEPTION( projection_exception(error_lat_0_or_alpha_eq_90) );
0334
0335 proj_parm.lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic));
0336 phip = aasin(cos(phic) * sin(alpha));
0337 } else if (pj_param_r<srs::spar::o_lat_p>(params, "o_lat_p", srs::dpar::o_lat_p, phip)) {
0338 proj_parm.lamp = pj_get_param_r<T, srs::spar::o_lon_p>(params, "o_lon_p", srs::dpar::o_lon_p);
0339
0340 } else {
0341 T lam1, lam2, phi1, phi2, con;
0342
0343 lam1 = pj_get_param_r<T, srs::spar::o_lon_1>(params, "o_lon_1", srs::dpar::o_lon_1);
0344 phi1 = pj_get_param_r<T, srs::spar::o_lat_1>(params, "o_lat_1", srs::dpar::o_lat_1);
0345 lam2 = pj_get_param_r<T, srs::spar::o_lon_2>(params, "o_lon_2", srs::dpar::o_lon_2);
0346 phi2 = pj_get_param_r<T, srs::spar::o_lat_2>(params, "o_lat_2", srs::dpar::o_lat_2);
0347 if (fabs(phi1 - phi2) <= tolerance || (con = fabs(phi1)) <= tolerance ||
0348 fabs(con - half_pi) <= tolerance || fabs(fabs(phi2) - half_pi) <= tolerance)
0349 BOOST_THROW_EXCEPTION( projection_exception(error_lat_1_or_2_zero_or_90) );
0350
0351 proj_parm.lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) -
0352 sin(phi1) * cos(phi2) * cos(lam2),
0353 sin(phi1) * cos(phi2) * sin(lam2) -
0354 cos(phi1) * sin(phi2) * sin(lam1));
0355 phip = atan(-cos(proj_parm.lamp - lam1) / tan(phi1));
0356 }
0357
0358 if (fabs(phip) > tolerance) {
0359 proj_parm.cphip = cos(phip);
0360 proj_parm.sphip = sin(phip);
0361 } else {
0362 }
0363
0364
0365
0366
0367
0368
0369
0370
0371 return phip;
0372 }
0373
0374 template <typename T, typename Parameters>
0375 struct base_ob_tran_oblique
0376 {
0377 par_ob_tran<T, Parameters> m_proj_parm;
0378
0379 inline base_ob_tran_oblique(par_ob_tran<T, Parameters> const& proj_parm)
0380 : m_proj_parm(proj_parm)
0381 {}
0382
0383
0384
0385 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0386 {
0387
0388 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
0389 }
0390
0391
0392
0393 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0394 {
0395
0396 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
0397 }
0398
0399 static inline std::string get_name()
0400 {
0401 return "ob_tran_oblique";
0402 }
0403
0404 };
0405
0406 template <typename T, typename Parameters>
0407 struct base_ob_tran_transverse
0408 {
0409 par_ob_tran<T, Parameters> m_proj_parm;
0410
0411 inline base_ob_tran_transverse(par_ob_tran<T, Parameters> const& proj_parm)
0412 : m_proj_parm(proj_parm)
0413 {}
0414
0415
0416
0417 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0418 {
0419
0420 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
0421 }
0422
0423
0424
0425 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0426 {
0427
0428 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
0429 }
0430
0431 static inline std::string get_name()
0432 {
0433 return "ob_tran_transverse";
0434 }
0435
0436 };
0437
0438 template <typename StaticParameters, typename T, typename Parameters>
0439 struct base_ob_tran_static
0440 {
0441 par_ob_tran_static<StaticParameters, T, Parameters> m_proj_parm;
0442 bool m_is_oblique;
0443
0444 inline base_ob_tran_static(StaticParameters const& params, Parameters const& par)
0445 : m_proj_parm(params, par)
0446 {}
0447
0448
0449
0450 inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const
0451 {
0452
0453 if (m_is_oblique) {
0454 o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
0455 } else {
0456 t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm);
0457 }
0458 }
0459
0460
0461
0462 inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const
0463 {
0464
0465 if (m_is_oblique) {
0466 o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
0467 } else {
0468 t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm);
0469 }
0470 }
0471
0472 static inline std::string get_name()
0473 {
0474 return "ob_tran";
0475 }
0476
0477 };
0478
0479 }}
0480 #endif
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507 template <typename T, typename Parameters>
0508 struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique<T, Parameters>
0509 {
0510 template <typename Params>
0511 inline ob_tran_oblique(Params const& , Parameters const& ,
0512 detail::ob_tran::par_ob_tran<T, Parameters> const& proj_parm)
0513 : detail::ob_tran::base_ob_tran_oblique<T, Parameters>(proj_parm)
0514 {
0515
0516
0517 }
0518 };
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545 template <typename T, typename Parameters>
0546 struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse<T, Parameters>
0547 {
0548 template <typename Params>
0549 inline ob_tran_transverse(Params const& , Parameters const& ,
0550 detail::ob_tran::par_ob_tran<T, Parameters> const& proj_parm)
0551 : detail::ob_tran::base_ob_tran_transverse<T, Parameters>(proj_parm)
0552 {
0553
0554
0555 }
0556 };
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 template <typename StaticParameters, typename T, typename Parameters>
0584 struct ob_tran_static : public detail::ob_tran::base_ob_tran_static<StaticParameters, T, Parameters>
0585 {
0586 inline ob_tran_static(StaticParameters const& params, Parameters const& par)
0587 : detail::ob_tran::base_ob_tran_static<StaticParameters, T, Parameters>(params, par)
0588 {
0589 T phip = detail::ob_tran::setup_ob_tran<T>(params, par, this->m_proj_parm);
0590 this->m_is_oblique = fabs(phip) > detail::ob_tran::tolerance;
0591 }
0592 };
0593
0594 #ifndef DOXYGEN_NO_DETAIL
0595 namespace detail
0596 {
0597
0598
0599 template <typename SP, typename CT, typename P>
0600 struct static_projection_type<srs::spar::proj_ob_tran, srs_sphere_tag, SP, CT, P>
0601 {
0602 typedef static_wrapper_fi<ob_tran_static<SP, CT, P>, P> type;
0603 };
0604 template <typename SP, typename CT, typename P>
0605 struct static_projection_type<srs::spar::proj_ob_tran, srs_spheroid_tag, SP, CT, P>
0606 {
0607 typedef static_wrapper_fi<ob_tran_static<SP, CT, P>, P> type;
0608 };
0609
0610
0611 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ob_tran_entry)
0612 {
0613 Parameters parameters_copy = parameters;
0614 detail::ob_tran::par_ob_tran<T, Parameters> proj_parm(params, parameters_copy);
0615 T phip = detail::ob_tran::setup_ob_tran<T>(params, parameters_copy, proj_parm);
0616
0617 if (fabs(phip) > detail::ob_tran::tolerance)
0618 return new dynamic_wrapper_fi<ob_tran_oblique<T, Parameters>, T, Parameters>(params, parameters_copy, proj_parm);
0619 else
0620 return new dynamic_wrapper_fi<ob_tran_transverse<T, Parameters>, T, Parameters>(params, parameters_copy, proj_parm);
0621 }
0622 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END
0623
0624 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(ob_tran_init)
0625 {
0626 BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(ob_tran, ob_tran_entry)
0627 }
0628
0629 }
0630 #endif
0631
0632 }
0633
0634 }}
0635
0636 #endif
0637