File indexing completed on 2025-01-18 09:35:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
0014 #define BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
0015
0016
0017 #include <string>
0018 #include <type_traits>
0019 #include <vector>
0020
0021 #include <boost/geometry/core/radius.hpp>
0022 #include <boost/geometry/core/tag.hpp>
0023 #include <boost/geometry/core/tags.hpp>
0024
0025 #include <boost/geometry/srs/projections/exception.hpp>
0026 #include <boost/geometry/srs/projections/par_data.hpp>
0027 #include <boost/geometry/srs/sphere.hpp>
0028 #include <boost/geometry/srs/spheroid.hpp>
0029
0030 #include <boost/geometry/util/range.hpp>
0031
0032 #include <boost/range/begin.hpp>
0033 #include <boost/range/end.hpp>
0034 #include <boost/range/size.hpp>
0035 #include <boost/range/value_type.hpp>
0036
0037 #include <boost/variant/get.hpp>
0038 #include <boost/variant/variant.hpp>
0039
0040
0041 namespace boost { namespace geometry { namespace srs
0042 {
0043
0044 namespace detail
0045 {
0046
0047 template <typename T, int I, typename ...>
0048 struct find_type_index_impl
0049 : std::integral_constant<int, I>
0050 {};
0051
0052 template
0053 <
0054 typename T,
0055 int I,
0056 typename Type,
0057 typename ...Types
0058 >
0059 struct find_type_index_impl<T, I, Type, Types...>
0060 : std::conditional_t
0061 <
0062 std::is_same<T, Type>::value,
0063 std::integral_constant<int, I>,
0064 typename find_type_index_impl<T, I + 1, Types...>::type
0065 >
0066 {};
0067
0068 template <typename Variant, typename T>
0069 struct find_type_index
0070 {};
0071
0072 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename T>
0073 struct find_type_index<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, T>
0074 : find_type_index_impl<T, 0, BOOST_VARIANT_ENUM_PARAMS(T)>
0075 {};
0076
0077
0078 template
0079 <
0080 typename Range,
0081 typename ToValue,
0082 bool IsRange = range::detail::is_range<Range>::value
0083 >
0084 struct is_convertible_range
0085 : std::is_convertible
0086 <
0087 typename boost::range_value<Range>::type,
0088 ToValue
0089 >
0090 {};
0091
0092 template
0093 <
0094 typename Range,
0095 typename ToValue
0096 >
0097 struct is_convertible_range<Range, ToValue, false>
0098 : std::false_type
0099 {};
0100
0101 }
0102
0103
0104 namespace dpar
0105 {
0106
0107 enum value_datum
0108 {
0109 datum_wgs84 = 0,
0110 datum_ggrs87,
0111 datum_nad83,
0112 datum_nad27,
0113 datum_potsdam,
0114 datum_carthage,
0115 datum_hermannskogel,
0116 datum_ire65,
0117 datum_nzgd49,
0118 datum_osgb36,
0119 };
0120
0121 enum value_ellps
0122 {
0123 ellps_merit = 0,
0124 ellps_sgs85,
0125 ellps_grs80,
0126 ellps_iau76,
0127 ellps_airy,
0128 ellps_apl4_9,
0129 ellps_nwl9d,
0130 ellps_mod_airy,
0131 ellps_andrae,
0132 ellps_aust_sa,
0133 ellps_grs67,
0134 ellps_bessel,
0135 ellps_bess_nam,
0136 ellps_clrk66,
0137 ellps_clrk80,
0138 ellps_clrk80ign,
0139 ellps_cpm,
0140 ellps_delmbr,
0141 ellps_engelis,
0142 ellps_evrst30,
0143 ellps_evrst48,
0144 ellps_evrst56,
0145 ellps_evrst69,
0146 ellps_evrstss,
0147 ellps_fschr60,
0148 ellps_fschr60m,
0149 ellps_fschr68,
0150 ellps_helmert,
0151 ellps_hough,
0152 ellps_intl,
0153 ellps_krass,
0154 ellps_kaula,
0155 ellps_lerch,
0156 ellps_mprts,
0157 ellps_new_intl,
0158 ellps_plessis,
0159 ellps_seasia,
0160 ellps_walbeck,
0161 ellps_wgs60,
0162 ellps_wgs66,
0163 ellps_wgs72,
0164 ellps_wgs84,
0165 ellps_sphere
0166 };
0167
0168 enum value_mode
0169 {
0170 mode_plane = 0,
0171 mode_di,
0172 mode_dd,
0173 mode_hex
0174 };
0175
0176 enum value_orient
0177 {
0178 orient_isea = 0,
0179 orient_pole,
0180 };
0181
0182 enum value_pm
0183 {
0184 pm_greenwich = 0,
0185 pm_lisbon,
0186 pm_paris,
0187 pm_bogota,
0188 pm_madrid,
0189 pm_rome,
0190 pm_bern,
0191 pm_jakarta,
0192 pm_ferro,
0193 pm_brussels,
0194 pm_stockholm,
0195 pm_athens,
0196 pm_oslo
0197 };
0198
0199 enum value_proj
0200 {
0201 proj_unknown = 0,
0202 proj_aea, proj_leac,
0203 proj_aeqd,
0204 proj_airy,
0205 proj_aitoff, proj_wintri,
0206 proj_august,
0207 proj_apian, proj_ortel, proj_bacon,
0208 proj_bipc,
0209 proj_boggs,
0210 proj_bonne,
0211 proj_cass,
0212 proj_cc,
0213 proj_cea,
0214 proj_chamb,
0215 proj_col_urban,
0216 proj_collg,
0217 proj_crast,
0218 proj_denoy,
0219 proj_eck1,
0220 proj_eck2,
0221 proj_eck3, proj_putp1, proj_wag6, proj_kav7,
0222 proj_eck4,
0223 proj_eck5,
0224 proj_eqc,
0225 proj_eqdc,
0226 proj_etmerc, proj_utm,
0227 proj_fahey,
0228 proj_fouc_s,
0229 proj_gall,
0230 proj_geocent,
0231 proj_geos,
0232 proj_gins8,
0233 proj_gn_sinu, proj_sinu, proj_eck6, proj_mbtfps,
0234 proj_gnom,
0235 proj_goode,
0236 proj_gstmerc,
0237 proj_hammer,
0238 proj_hatano,
0239 proj_healpix,
0240 proj_rhealpix,
0241 proj_igh,
0242 proj_imw_p,
0243 proj_isea,
0244 proj_krovak,
0245 proj_labrd,
0246 proj_laea,
0247 proj_lagrng,
0248 proj_larr,
0249 proj_lask,
0250 proj_lonlat, proj_latlon, proj_latlong, proj_longlat,
0251 proj_lcc,
0252 proj_lcca,
0253 proj_loxim,
0254 proj_lsat,
0255 proj_mbt_fps,
0256 proj_mbtfpp,
0257 proj_mbtfpq,
0258 proj_merc,
0259 proj_mill,
0260 proj_mil_os, proj_lee_os, proj_gs48, proj_alsk, proj_gs50,
0261 proj_moll, proj_wag4, proj_wag5,
0262 proj_natearth,
0263 proj_nell,
0264 proj_nell_h,
0265 proj_nicol,
0266 proj_nsper, proj_tpers,
0267 proj_nzmg,
0268 proj_ob_tran,
0269 proj_ocea,
0270 proj_oea,
0271 proj_omerc,
0272 proj_ortho,
0273 proj_poly,
0274 proj_putp2,
0275 proj_putp3, proj_putp3p,
0276 proj_putp4p, proj_weren,
0277 proj_putp5, proj_putp5p,
0278 proj_putp6, proj_putp6p,
0279 proj_qsc,
0280 proj_robin,
0281 proj_rouss,
0282 proj_rpoly,
0283 proj_euler, proj_murd1, proj_murd2, proj_murd3, proj_pconic, proj_tissot, proj_vitk1,
0284 proj_somerc,
0285 proj_stere, proj_ups,
0286 proj_sterea,
0287 proj_kav5, proj_qua_aut, proj_fouc, proj_mbt_s,
0288 proj_tcc,
0289 proj_tcea,
0290 proj_tmerc,
0291 proj_tpeqd,
0292 proj_urm5,
0293 proj_urmfps, proj_wag1,
0294 proj_vandg,
0295 proj_vandg2, proj_vandg3,
0296 proj_vandg4,
0297 proj_wag2,
0298 proj_wag3,
0299 proj_wag7,
0300 proj_webmerc,
0301 proj_wink1,
0302 proj_wink2
0303 };
0304
0305 enum value_sweep
0306 {
0307 sweep_x = 0, sweep_y
0308 };
0309
0310 enum value_units
0311 {
0312 units_km = 0,
0313 units_m,
0314 units_dm,
0315 units_cm,
0316 units_mm,
0317 units_kmi,
0318 units_in,
0319 units_ft,
0320 units_yd,
0321 units_mi,
0322 units_fath,
0323 units_ch,
0324 units_link,
0325 units_us_in,
0326 units_us_ft,
0327 units_us_yd,
0328 units_us_ch,
0329 units_us_mi,
0330 units_ind_yd,
0331 units_ind_ft,
0332 units_ind_ch
0333 };
0334
0335 enum name_f
0336 {
0337 a = 0,
0338 b,
0339 e,
0340 es,
0341 f,
0342 h,
0343 h_0,
0344 k = 7,
0345 k_0,
0346 m,
0347 n,
0348
0349
0350
0351 q = 14,
0352 r,
0353 rf,
0354 to_meter,
0355 vto_meter,
0356 w,
0357 x_0,
0358 y_0
0359 };
0360
0361 enum name_r
0362 {
0363 alpha = 22,
0364 azi,
0365 gamma,
0366 lat_0,
0367 lat_1,
0368 lat_2,
0369 lat_3,
0370 lat_b,
0371 lat_ts,
0372 lon_0,
0373 lon_1,
0374 lon_2,
0375 lon_3,
0376 lon_wrap,
0377 lonc,
0378 o_alpha,
0379 o_lat_1,
0380 o_lat_2,
0381 o_lat_c,
0382 o_lat_p,
0383 o_lon_1,
0384 o_lon_2,
0385 o_lon_c,
0386 o_lon_p,
0387 r_lat_a,
0388 r_lat_g,
0389 theta,
0390 tilt
0391 };
0392
0393 enum name_i
0394 {
0395 aperture = 50,
0396 lsat,
0397 north_square,
0398 path,
0399 resolution,
0400 south_square,
0401 zone
0402 };
0403
0404 enum name_be
0405 {
0406 czech = 57,
0407 geoc,
0408 guam,
0409 no_cut,
0410 no_defs,
0411 no_rot,
0412 ns,
0413 over,
0414 r_au,
0415 r_a,
0416 r_g,
0417 r_h,
0418 r_v,
0419 rescale,
0420 south,
0421 variant_c,
0422 no_off,
0423 hyperbolic
0424 };
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 enum name_datum
0437 {
0438 datum = 74
0439 };
0440
0441 enum name_ellps
0442 {
0443 ellps = 75
0444 };
0445
0446
0447
0448
0449
0450
0451 enum name_mode
0452 {
0453 mode = 77
0454 };
0455
0456 enum name_nadgrids
0457 {
0458 nadgrids = 78
0459 };
0460
0461 enum name_orient
0462 {
0463 orient = 79
0464 };
0465
0466 enum name_pm
0467 {
0468 pm = 80
0469 };
0470
0471 enum name_proj
0472 {
0473 o_proj = 81,
0474 proj
0475 };
0476
0477 enum name_sweep
0478 {
0479 sweep = 83
0480 };
0481
0482 enum name_towgs84
0483 {
0484 towgs84 = 84
0485 };
0486
0487 enum name_units
0488 {
0489 units = 85,
0490 vunits
0491 };
0492
0493 enum name_axis
0494 {
0495 axis = 86
0496 };
0497
0498 template <typename T>
0499 struct parameter
0500 {
0501 parameter()
0502 : m_id(-1), m_value(false)
0503 {}
0504
0505 parameter(name_f id, T const& v)
0506 : m_id(id), m_value(v)
0507 {}
0508
0509
0510 parameter(name_r id, T const& v)
0511 : m_id(id), m_value(v)
0512 {}
0513
0514 parameter(name_i id, int v)
0515 : m_id(id), m_value(v)
0516 {}
0517
0518 parameter(name_be id)
0519 : m_id(id), m_value(true)
0520 {}
0521
0522 parameter(name_be id, bool v)
0523 : m_id(id), m_value(v)
0524 {}
0525
0526 parameter(name_datum id, value_datum v)
0527 : m_id(id), m_value(int(v))
0528 {}
0529
0530 parameter(value_datum v)
0531 : m_id(datum), m_value(int(v))
0532 {}
0533
0534
0535 parameter(name_ellps id, value_ellps v)
0536 : m_id(id), m_value(int(v))
0537 {}
0538
0539 parameter(value_ellps v)
0540 : m_id(ellps), m_value(int(v))
0541 {}
0542
0543 template
0544 <
0545 typename Sphere,
0546 std::enable_if_t
0547 <
0548 std::is_same<typename geometry::tag<Sphere>::type, srs_sphere_tag>::value,
0549 int
0550 > = 0
0551 >
0552 parameter(name_ellps id, Sphere const& v)
0553 : m_id(id)
0554 , m_value(T(get_radius<0>(v)))
0555 {}
0556
0557 template
0558 <
0559 typename Spheroid,
0560 std::enable_if_t
0561 <
0562 std::is_same<typename geometry::tag<Spheroid>::type, srs_spheroid_tag>::value,
0563 int
0564 > = 0
0565 >
0566 parameter(name_ellps id, Spheroid const& v)
0567 : m_id(id)
0568 , m_value(srs::spheroid<T>(get_radius<0>(v), get_radius<2>(v)))
0569 {}
0570
0571 parameter(name_mode id, value_mode v)
0572 : m_id(id), m_value(int(v))
0573 {}
0574
0575 parameter(value_mode v)
0576 : m_id(mode), m_value(int(v))
0577 {}
0578
0579 template
0580 <
0581 typename Range,
0582 std::enable_if_t
0583 <
0584 detail::is_convertible_range<Range const, std::string>::value,
0585 int
0586 > = 0
0587 >
0588 parameter(name_nadgrids id, Range const& v)
0589 : m_id(id)
0590 , m_value(srs::detail::nadgrids(boost::begin(v), boost::end(v)))
0591 {}
0592
0593 parameter(name_nadgrids id, std::initializer_list<std::string> v)
0594 : m_id(id)
0595 , m_value(srs::detail::nadgrids(v))
0596 {}
0597
0598 parameter(name_orient id, value_orient v)
0599 : m_id(id), m_value(int(v))
0600 {}
0601
0602 parameter(value_orient v)
0603 : m_id(orient), m_value(int(v))
0604 {}
0605
0606
0607 parameter(name_pm id, value_pm v)
0608 : m_id(id), m_value(int(v))
0609 {}
0610
0611 parameter(value_pm v)
0612 : m_id(pm), m_value(int(v))
0613 {}
0614
0615
0616 parameter(name_pm id, T const& v)
0617 : m_id(id), m_value(v)
0618 {}
0619
0620 parameter(name_proj id, value_proj v)
0621 : m_id(id), m_value(int(v))
0622 {}
0623
0624 parameter(value_proj v)
0625 : m_id(proj), m_value(int(v))
0626 {}
0627
0628 parameter(name_sweep id, value_sweep v)
0629 : m_id(id), m_value(int(v))
0630 {}
0631
0632 parameter(value_sweep v)
0633 : m_id(sweep), m_value(int(v))
0634 {}
0635
0636 template
0637 <
0638 typename Range,
0639 std::enable_if_t
0640 <
0641 detail::is_convertible_range<Range const, T>::value,
0642 int
0643 > = 0
0644 >
0645 parameter(name_towgs84 id, Range const& v)
0646 : m_id(id)
0647 , m_value(srs::detail::towgs84<T>(boost::begin(v), boost::end(v)))
0648 {
0649 std::size_t n = boost::size(v);
0650 if (n != 3 && n != 7)
0651 {
0652 BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
0653 }
0654 }
0655
0656 parameter(name_towgs84 id, std::initializer_list<T> v)
0657 : m_id(id)
0658 , m_value(srs::detail::towgs84<T>(v))
0659 {
0660 std::size_t n = v.size();
0661 if (n != 3 && n != 7)
0662 {
0663 BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
0664 }
0665 }
0666
0667 parameter(name_axis id, std::initializer_list<int> v)
0668 : m_id(id)
0669 , m_value(srs::detail::axis(v))
0670 {
0671 std::size_t n = v.size();
0672 if (n != 3)
0673 {
0674 BOOST_THROW_EXCEPTION( projection_exception("Invalid number of axis elements. Should be 3.") );
0675 }
0676 }
0677
0678 parameter(name_units id, value_units v)
0679 : m_id(id), m_value(int(v))
0680 {}
0681
0682 parameter(value_units v)
0683 : m_id(units), m_value(int(v))
0684 {}
0685
0686 private:
0687 typedef boost::variant
0688 <
0689 bool,
0690 int,
0691 T,
0692 srs::spheroid<T>,
0693 srs::detail::nadgrids,
0694 srs::detail::towgs84<T>
0695 > variant_type;
0696
0697 public:
0698 bool is_id_equal(name_f const& id) const { return m_id == int(id); }
0699 bool is_id_equal(name_r const& id) const { return m_id == int(id); }
0700 bool is_id_equal(name_i const& id) const { return m_id == int(id); }
0701 bool is_id_equal(name_be const& id) const { return m_id == int(id); }
0702 bool is_id_equal(name_datum const& id) const { return m_id == int(id); }
0703 bool is_id_equal(name_ellps const& id) const { return m_id == int(id); }
0704 bool is_id_equal(name_mode const& id) const { return m_id == int(id); }
0705 bool is_id_equal(name_nadgrids const& id) const { return m_id == int(id); }
0706 bool is_id_equal(name_orient const& id) const { return m_id == int(id); }
0707 bool is_id_equal(name_pm const& id) const { return m_id == int(id); }
0708 bool is_id_equal(name_proj const& id) const { return m_id == int(id); }
0709 bool is_id_equal(name_sweep const& id) const { return m_id == int(id); }
0710 bool is_id_equal(name_towgs84 const& id) const { return m_id == int(id); }
0711 bool is_id_equal(name_units const& id) const { return m_id == int(id); }
0712 bool is_id_equal(name_axis const& id) const { return m_id == int(id); }
0713
0714 template <typename V>
0715 V const& get_value() const
0716 {
0717 return boost::get<V>(m_value);
0718 }
0719
0720 template <typename V>
0721 bool is_value_set() const
0722 {
0723 return m_value.which() == srs::detail::find_type_index<variant_type, V>::value;
0724 }
0725
0726 private:
0727 int m_id;
0728 variant_type m_value;
0729 };
0730
0731 template <typename T = double>
0732 class parameters
0733 {
0734 typedef std::vector<parameter<T> > container_type;
0735
0736 public:
0737 typedef typename container_type::value_type value_type;
0738 typedef typename container_type::const_iterator const_iterator;
0739 typedef typename container_type::const_reference const_reference;
0740 typedef typename container_type::size_type size_type;
0741
0742 BOOST_DEFAULTED_FUNCTION(parameters(), {})
0743
0744 template <typename Id>
0745 explicit parameters(Id id)
0746 {
0747 add(id);
0748 }
0749
0750 template <typename Id>
0751 parameters & add(Id id)
0752 {
0753 m_params.emplace_back(id);
0754 return *this;
0755 }
0756
0757 template <typename Id>
0758 parameters & operator()(Id id)
0759 {
0760 return add(id);
0761 }
0762
0763 template <typename Id, typename V>
0764 parameters(Id id, V && value)
0765 {
0766 add(id, std::forward<V>(value));
0767 }
0768
0769 template <typename Id, typename V>
0770 parameters & add(Id id, V && value)
0771 {
0772 m_params.emplace_back(id, std::forward<V>(value));
0773 return *this;
0774 }
0775
0776 template <typename Id, typename V>
0777 parameters & operator()(Id id, V && value)
0778 {
0779 return add(id, std::forward<V>(value));
0780 }
0781
0782 template <typename Id, typename V>
0783 parameters(Id id, std::initializer_list<V> value)
0784 {
0785 add(id, value);
0786 }
0787
0788 template <typename Id, typename V>
0789 parameters & add(Id id, std::initializer_list<V> value)
0790 {
0791 m_params.emplace_back(id, value);
0792 return *this;
0793 }
0794
0795 template <typename Id, typename V>
0796 parameters & operator()(Id id, std::initializer_list<V> value)
0797 {
0798 return add(id, value);
0799 }
0800
0801 const_iterator begin() const { return m_params.begin(); }
0802 const_iterator end() const { return m_params.end(); }
0803 const_reference operator[](size_type i) const { return m_params[i]; }
0804 size_type size() { return m_params.size(); }
0805 bool empty() { return m_params.empty(); }
0806
0807 private:
0808 container_type m_params;
0809 };
0810
0811
0812 }
0813
0814
0815 }}}
0816
0817
0818 #endif