dpar.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. // Boost.Geometry
  2. // Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
  3. // Copyright (c) 2017-2023, Oracle and/or its affiliates.
  4. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  5. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
  10. #define BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
  11. #include <string>
  12. #include <type_traits>
  13. #include <vector>
  14. #include <boost/geometry/core/radius.hpp>
  15. #include <boost/geometry/core/tag.hpp>
  16. #include <boost/geometry/core/tags.hpp>
  17. #include <boost/geometry/srs/projections/exception.hpp>
  18. #include <boost/geometry/srs/projections/par_data.hpp>
  19. #include <boost/geometry/srs/sphere.hpp>
  20. #include <boost/geometry/srs/spheroid.hpp>
  21. #include <boost/geometry/util/range.hpp>
  22. #include <boost/range/begin.hpp>
  23. #include <boost/range/end.hpp>
  24. #include <boost/range/size.hpp>
  25. #include <boost/range/value_type.hpp>
  26. #include <boost/variant/get.hpp>
  27. #include <boost/variant/variant.hpp>
  28. namespace boost { namespace geometry { namespace srs
  29. {
  30. namespace detail
  31. {
  32. template <typename T, int I, typename ...>
  33. struct find_type_index_impl
  34. : std::integral_constant<int, I>
  35. {};
  36. template
  37. <
  38. typename T,
  39. int I,
  40. typename Type,
  41. typename ...Types
  42. >
  43. struct find_type_index_impl<T, I, Type, Types...>
  44. : std::conditional_t
  45. <
  46. std::is_same<T, Type>::value,
  47. std::integral_constant<int, I>,
  48. typename find_type_index_impl<T, I + 1, Types...>::type
  49. >
  50. {};
  51. template <typename Variant, typename T>
  52. struct find_type_index
  53. {};
  54. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename T>
  55. struct find_type_index<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, T>
  56. : find_type_index_impl<T, 0, BOOST_VARIANT_ENUM_PARAMS(T)>
  57. {};
  58. template
  59. <
  60. typename Range,
  61. typename ToValue,
  62. bool IsRange = range::detail::is_range<Range>::value
  63. >
  64. struct is_convertible_range
  65. : std::is_convertible
  66. <
  67. typename boost::range_value<Range>::type,
  68. ToValue
  69. >
  70. {};
  71. template
  72. <
  73. typename Range,
  74. typename ToValue
  75. >
  76. struct is_convertible_range<Range, ToValue, false>
  77. : std::false_type
  78. {};
  79. } // namespace detail
  80. namespace dpar
  81. {
  82. enum value_datum
  83. {
  84. datum_wgs84 = 0,
  85. datum_ggrs87,
  86. datum_nad83,
  87. datum_nad27,
  88. datum_potsdam,
  89. datum_carthage,
  90. datum_hermannskogel,
  91. datum_ire65,
  92. datum_nzgd49,
  93. datum_osgb36,
  94. };
  95. enum value_ellps
  96. {
  97. ellps_merit = 0,
  98. ellps_sgs85,
  99. ellps_grs80,
  100. ellps_iau76,
  101. ellps_airy,
  102. ellps_apl4_9,
  103. ellps_nwl9d,
  104. ellps_mod_airy,
  105. ellps_andrae,
  106. ellps_aust_sa,
  107. ellps_grs67,
  108. ellps_bessel,
  109. ellps_bess_nam,
  110. ellps_clrk66,
  111. ellps_clrk80,
  112. ellps_clrk80ign,
  113. ellps_cpm,
  114. ellps_delmbr,
  115. ellps_engelis,
  116. ellps_evrst30,
  117. ellps_evrst48,
  118. ellps_evrst56,
  119. ellps_evrst69,
  120. ellps_evrstss,
  121. ellps_fschr60,
  122. ellps_fschr60m,
  123. ellps_fschr68,
  124. ellps_helmert,
  125. ellps_hough,
  126. ellps_intl,
  127. ellps_krass,
  128. ellps_kaula,
  129. ellps_lerch,
  130. ellps_mprts,
  131. ellps_new_intl,
  132. ellps_plessis,
  133. ellps_seasia,
  134. ellps_walbeck,
  135. ellps_wgs60,
  136. ellps_wgs66,
  137. ellps_wgs72,
  138. ellps_wgs84,
  139. ellps_sphere
  140. };
  141. enum value_mode
  142. {
  143. mode_plane = 0,
  144. mode_di,
  145. mode_dd,
  146. mode_hex
  147. };
  148. enum value_orient
  149. {
  150. orient_isea = 0,
  151. orient_pole,
  152. };
  153. enum value_pm
  154. {
  155. pm_greenwich = 0,
  156. pm_lisbon,
  157. pm_paris,
  158. pm_bogota,
  159. pm_madrid,
  160. pm_rome,
  161. pm_bern,
  162. pm_jakarta,
  163. pm_ferro,
  164. pm_brussels,
  165. pm_stockholm,
  166. pm_athens,
  167. pm_oslo
  168. };
  169. enum value_proj
  170. {
  171. proj_unknown = 0,
  172. proj_aea, proj_leac,
  173. proj_aeqd,
  174. proj_airy,
  175. proj_aitoff, proj_wintri,
  176. proj_august,
  177. proj_apian, proj_ortel, proj_bacon,
  178. proj_bipc,
  179. proj_boggs,
  180. proj_bonne,
  181. proj_cass,
  182. proj_cc,
  183. proj_cea,
  184. proj_chamb,
  185. proj_col_urban,
  186. proj_collg,
  187. proj_crast,
  188. proj_denoy,
  189. proj_eck1,
  190. proj_eck2,
  191. proj_eck3, proj_putp1, proj_wag6, proj_kav7,
  192. proj_eck4,
  193. proj_eck5,
  194. proj_eqc,
  195. proj_eqdc,
  196. proj_etmerc, proj_utm,
  197. proj_fahey,
  198. proj_fouc_s,
  199. proj_gall,
  200. proj_geocent,
  201. proj_geos,
  202. proj_gins8,
  203. proj_gn_sinu, proj_sinu, proj_eck6, proj_mbtfps,
  204. proj_gnom,
  205. proj_goode,
  206. proj_gstmerc,
  207. proj_hammer,
  208. proj_hatano,
  209. proj_healpix,
  210. proj_rhealpix,
  211. proj_igh,
  212. proj_imw_p,
  213. proj_isea,
  214. proj_krovak,
  215. proj_labrd,
  216. proj_laea,
  217. proj_lagrng,
  218. proj_larr,
  219. proj_lask,
  220. proj_lonlat, proj_latlon, proj_latlong, proj_longlat,
  221. proj_lcc,
  222. proj_lcca,
  223. proj_loxim,
  224. proj_lsat,
  225. proj_mbt_fps,
  226. proj_mbtfpp,
  227. proj_mbtfpq,
  228. proj_merc,
  229. proj_mill,
  230. proj_mil_os, proj_lee_os, proj_gs48, proj_alsk, proj_gs50,
  231. proj_moll, proj_wag4, proj_wag5,
  232. proj_natearth,
  233. proj_nell,
  234. proj_nell_h,
  235. proj_nicol,
  236. proj_nsper, proj_tpers,
  237. proj_nzmg,
  238. proj_ob_tran,
  239. proj_ocea,
  240. proj_oea,
  241. proj_omerc,
  242. proj_ortho,
  243. proj_poly,
  244. proj_putp2,
  245. proj_putp3, proj_putp3p,
  246. proj_putp4p, proj_weren,
  247. proj_putp5, proj_putp5p,
  248. proj_putp6, proj_putp6p,
  249. proj_qsc,
  250. proj_robin,
  251. proj_rouss,
  252. proj_rpoly,
  253. proj_euler, proj_murd1, proj_murd2, proj_murd3, proj_pconic, proj_tissot, proj_vitk1,
  254. proj_somerc,
  255. proj_stere, proj_ups,
  256. proj_sterea,
  257. proj_kav5, proj_qua_aut, proj_fouc, proj_mbt_s,
  258. proj_tcc,
  259. proj_tcea,
  260. proj_tmerc,
  261. proj_tpeqd,
  262. proj_urm5,
  263. proj_urmfps, proj_wag1,
  264. proj_vandg,
  265. proj_vandg2, proj_vandg3,
  266. proj_vandg4,
  267. proj_wag2,
  268. proj_wag3,
  269. proj_wag7,
  270. proj_webmerc,
  271. proj_wink1,
  272. proj_wink2
  273. };
  274. enum value_sweep
  275. {
  276. sweep_x = 0, sweep_y
  277. };
  278. enum value_units
  279. {
  280. units_km = 0,
  281. units_m,
  282. units_dm,
  283. units_cm,
  284. units_mm,
  285. units_kmi,
  286. units_in,
  287. units_ft,
  288. units_yd,
  289. units_mi,
  290. units_fath,
  291. units_ch,
  292. units_link,
  293. units_us_in,
  294. units_us_ft,
  295. units_us_yd,
  296. units_us_ch,
  297. units_us_mi,
  298. units_ind_yd,
  299. units_ind_ft,
  300. units_ind_ch
  301. };
  302. enum name_f
  303. {
  304. a = 0,
  305. b,
  306. e,
  307. es,
  308. f,
  309. h,
  310. h_0,
  311. k = 7,
  312. k_0,
  313. m, // also used for M
  314. n,
  315. //phdg_0, // currently not used
  316. //plat_0, // currently not used
  317. //plon_0, // currently not used
  318. q = 14,
  319. r, // originally R
  320. rf,
  321. to_meter,
  322. vto_meter,
  323. w, // originally W
  324. x_0,
  325. y_0
  326. };
  327. enum name_r
  328. {
  329. alpha = 22,
  330. azi,
  331. gamma,
  332. lat_0,
  333. lat_1,
  334. lat_2,
  335. lat_3,
  336. lat_b,
  337. lat_ts, // 30
  338. lon_0,
  339. lon_1,
  340. lon_2,
  341. lon_3,
  342. lon_wrap,
  343. lonc,
  344. o_alpha,
  345. o_lat_1,
  346. o_lat_2,
  347. o_lat_c, // 40
  348. o_lat_p,
  349. o_lon_1,
  350. o_lon_2,
  351. o_lon_c,
  352. o_lon_p,
  353. r_lat_a, // originally R_lat_a
  354. r_lat_g, // originally R_lat_g
  355. theta,
  356. tilt
  357. };
  358. enum name_i
  359. {
  360. aperture = 50,
  361. lsat,
  362. north_square,
  363. path,
  364. resolution,
  365. south_square,
  366. zone
  367. };
  368. enum name_be
  369. {
  370. czech = 57,
  371. geoc,
  372. guam,
  373. no_cut, // 60
  374. no_defs,
  375. no_rot,
  376. ns,
  377. over,
  378. r_au, // originally R_A
  379. r_a, // originally R_a
  380. r_g, // originally R_g
  381. r_h, // originally R_h
  382. r_v, // originally R_V
  383. rescale, // 70
  384. south,
  385. variant_c, // BG specific
  386. no_off,
  387. hyperbolic
  388. };
  389. /*enum name_catalog
  390. {
  391. catalog = 72 // currently not used
  392. };
  393. enum name_date
  394. {
  395. date = 73 // currently not used
  396. };*/
  397. enum name_datum
  398. {
  399. datum = 74
  400. };
  401. enum name_ellps
  402. {
  403. ellps = 75 // id, sphere or spheroid
  404. };
  405. /*enum name_geoidgrids
  406. {
  407. geoidgrids = 76 // currently not used
  408. };*/
  409. enum name_mode
  410. {
  411. mode = 77
  412. };
  413. enum name_nadgrids
  414. {
  415. nadgrids = 78 // arbitrary-length list of strings
  416. };
  417. enum name_orient
  418. {
  419. orient = 79
  420. };
  421. enum name_pm
  422. {
  423. pm = 80 // id or angle
  424. };
  425. enum name_proj
  426. {
  427. o_proj = 81,
  428. proj
  429. };
  430. enum name_sweep
  431. {
  432. sweep = 83
  433. };
  434. enum name_towgs84
  435. {
  436. towgs84 = 84 // 3 or 7 element list of numbers
  437. };
  438. enum name_units
  439. {
  440. units = 85,
  441. vunits
  442. };
  443. enum name_axis
  444. {
  445. axis = 86 // 3 element list of numbers
  446. };
  447. template <typename T>
  448. struct parameter
  449. {
  450. parameter()
  451. : m_id(-1), m_value(false)
  452. {}
  453. parameter(name_f id, T const& v)
  454. : m_id(id), m_value(v)
  455. {}
  456. // TODO various angle units
  457. parameter(name_r id, T const& v)
  458. : m_id(id), m_value(v)
  459. {}
  460. parameter(name_i id, int v)
  461. : m_id(id), m_value(v)
  462. {}
  463. parameter(name_be id)
  464. : m_id(id), m_value(true)
  465. {}
  466. parameter(name_be id, bool v)
  467. : m_id(id), m_value(v)
  468. {}
  469. parameter(name_datum id, value_datum v)
  470. : m_id(id), m_value(int(v))
  471. {}
  472. parameter(value_datum v)
  473. : m_id(datum), m_value(int(v))
  474. {}
  475. // TODO: store model at this point?
  476. parameter(name_ellps id, value_ellps v)
  477. : m_id(id), m_value(int(v))
  478. {}
  479. // TODO: store model at this point?
  480. parameter(value_ellps v)
  481. : m_id(ellps), m_value(int(v))
  482. {}
  483. template
  484. <
  485. typename Sphere,
  486. std::enable_if_t
  487. <
  488. std::is_same<typename geometry::tag<Sphere>::type, srs_sphere_tag>::value,
  489. int
  490. > = 0
  491. >
  492. parameter(name_ellps id, Sphere const& v)
  493. : m_id(id)
  494. , m_value(T(get_radius<0>(v)))
  495. {}
  496. template
  497. <
  498. typename Spheroid,
  499. std::enable_if_t
  500. <
  501. std::is_same<typename geometry::tag<Spheroid>::type, srs_spheroid_tag>::value,
  502. int
  503. > = 0
  504. >
  505. parameter(name_ellps id, Spheroid const& v)
  506. : m_id(id)
  507. , m_value(srs::spheroid<T>(get_radius<0>(v), get_radius<2>(v)))
  508. {}
  509. parameter(name_mode id, value_mode v)
  510. : m_id(id), m_value(int(v))
  511. {}
  512. parameter(value_mode v)
  513. : m_id(mode), m_value(int(v))
  514. {}
  515. template
  516. <
  517. typename Range,
  518. std::enable_if_t
  519. <
  520. detail::is_convertible_range<Range const, std::string>::value,
  521. int
  522. > = 0
  523. >
  524. parameter(name_nadgrids id, Range const& v)
  525. : m_id(id)
  526. , m_value(srs::detail::nadgrids(boost::begin(v), boost::end(v)))
  527. {}
  528. parameter(name_nadgrids id, std::initializer_list<std::string> v)
  529. : m_id(id)
  530. , m_value(srs::detail::nadgrids(v))
  531. {}
  532. parameter(name_orient id, value_orient v)
  533. : m_id(id), m_value(int(v))
  534. {}
  535. parameter(value_orient v)
  536. : m_id(orient), m_value(int(v))
  537. {}
  538. // TODO: store to_meters at this point?
  539. parameter(name_pm id, value_pm v)
  540. : m_id(id), m_value(int(v))
  541. {}
  542. // TODO: store to_meters at this point?
  543. parameter(value_pm v)
  544. : m_id(pm), m_value(int(v))
  545. {}
  546. // TODO angle units
  547. parameter(name_pm id, T const& v)
  548. : m_id(id), m_value(v)
  549. {}
  550. parameter(name_proj id, value_proj v)
  551. : m_id(id), m_value(int(v))
  552. {}
  553. parameter(value_proj v)
  554. : m_id(proj), m_value(int(v))
  555. {}
  556. parameter(name_sweep id, value_sweep v)
  557. : m_id(id), m_value(int(v))
  558. {}
  559. parameter(value_sweep v)
  560. : m_id(sweep), m_value(int(v))
  561. {}
  562. template
  563. <
  564. typename Range,
  565. std::enable_if_t
  566. <
  567. detail::is_convertible_range<Range const, T>::value,
  568. int
  569. > = 0
  570. >
  571. parameter(name_towgs84 id, Range const& v)
  572. : m_id(id)
  573. , m_value(srs::detail::towgs84<T>(boost::begin(v), boost::end(v)))
  574. {
  575. std::size_t n = boost::size(v);
  576. if (n != 3 && n != 7)
  577. {
  578. BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
  579. }
  580. }
  581. parameter(name_towgs84 id, std::initializer_list<T> v)
  582. : m_id(id)
  583. , m_value(srs::detail::towgs84<T>(v))
  584. {
  585. std::size_t n = v.size();
  586. if (n != 3 && n != 7)
  587. {
  588. BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
  589. }
  590. }
  591. parameter(name_axis id, std::initializer_list<int> v)
  592. : m_id(id)
  593. , m_value(srs::detail::axis(v))
  594. {
  595. std::size_t n = v.size();
  596. if (n != 3)
  597. {
  598. BOOST_THROW_EXCEPTION( projection_exception("Invalid number of axis elements. Should be 3.") );
  599. }
  600. }
  601. parameter(name_units id, value_units v)
  602. : m_id(id), m_value(int(v))
  603. {}
  604. parameter(value_units v)
  605. : m_id(units), m_value(int(v))
  606. {}
  607. private:
  608. typedef boost::variant
  609. <
  610. bool,
  611. int,
  612. T,
  613. srs::spheroid<T>,
  614. srs::detail::nadgrids,
  615. srs::detail::towgs84<T>
  616. > variant_type;
  617. public:
  618. bool is_id_equal(name_f const& id) const { return m_id == int(id); }
  619. bool is_id_equal(name_r const& id) const { return m_id == int(id); }
  620. bool is_id_equal(name_i const& id) const { return m_id == int(id); }
  621. bool is_id_equal(name_be const& id) const { return m_id == int(id); }
  622. bool is_id_equal(name_datum const& id) const { return m_id == int(id); }
  623. bool is_id_equal(name_ellps const& id) const { return m_id == int(id); }
  624. bool is_id_equal(name_mode const& id) const { return m_id == int(id); }
  625. bool is_id_equal(name_nadgrids const& id) const { return m_id == int(id); }
  626. bool is_id_equal(name_orient const& id) const { return m_id == int(id); }
  627. bool is_id_equal(name_pm const& id) const { return m_id == int(id); }
  628. bool is_id_equal(name_proj const& id) const { return m_id == int(id); }
  629. bool is_id_equal(name_sweep const& id) const { return m_id == int(id); }
  630. bool is_id_equal(name_towgs84 const& id) const { return m_id == int(id); }
  631. bool is_id_equal(name_units const& id) const { return m_id == int(id); }
  632. bool is_id_equal(name_axis const& id) const { return m_id == int(id); }
  633. template <typename V>
  634. V const& get_value() const
  635. {
  636. return boost::get<V>(m_value);
  637. }
  638. template <typename V>
  639. bool is_value_set() const
  640. {
  641. return m_value.which() == srs::detail::find_type_index<variant_type, V>::value;
  642. }
  643. private:
  644. int m_id;
  645. variant_type m_value;
  646. };
  647. template <typename T = double>
  648. class parameters
  649. {
  650. typedef std::vector<parameter<T> > container_type;
  651. public:
  652. typedef typename container_type::value_type value_type;
  653. typedef typename container_type::const_iterator const_iterator;
  654. typedef typename container_type::const_reference const_reference;
  655. typedef typename container_type::size_type size_type;
  656. BOOST_DEFAULTED_FUNCTION(parameters(), {})
  657. template <typename Id>
  658. explicit parameters(Id id)
  659. {
  660. add(id);
  661. }
  662. template <typename Id>
  663. parameters & add(Id id)
  664. {
  665. m_params.emplace_back(id);
  666. return *this;
  667. }
  668. template <typename Id>
  669. parameters & operator()(Id id)
  670. {
  671. return add(id);
  672. }
  673. template <typename Id, typename V>
  674. parameters(Id id, V && value)
  675. {
  676. add(id, std::forward<V>(value));
  677. }
  678. template <typename Id, typename V>
  679. parameters & add(Id id, V && value)
  680. {
  681. m_params.emplace_back(id, std::forward<V>(value));
  682. return *this;
  683. }
  684. template <typename Id, typename V>
  685. parameters & operator()(Id id, V && value)
  686. {
  687. return add(id, std::forward<V>(value));
  688. }
  689. template <typename Id, typename V>
  690. parameters(Id id, std::initializer_list<V> value)
  691. {
  692. add(id, value);
  693. }
  694. template <typename Id, typename V>
  695. parameters & add(Id id, std::initializer_list<V> value)
  696. {
  697. m_params.emplace_back(id, value);
  698. return *this;
  699. }
  700. template <typename Id, typename V>
  701. parameters & operator()(Id id, std::initializer_list<V> value)
  702. {
  703. return add(id, value);
  704. }
  705. const_iterator begin() const { return m_params.begin(); }
  706. const_iterator end() const { return m_params.end(); }
  707. const_reference operator[](size_type i) const { return m_params[i]; }
  708. size_type size() { return m_params.size(); }
  709. bool empty() { return m_params.empty(); }
  710. private:
  711. container_type m_params;
  712. };
  713. } // namespace dpar
  714. }}} // namespace boost::geometry::srs
  715. #endif // BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP