3 // Copyright (c) 2017-2020, Oracle and/or its affiliates.
4 // 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)
10 #ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
11 #define BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP
15 #include <type_traits>
18 #include <boost/geometry/core/radius.hpp>
19 #include <boost/geometry/core/tag.hpp>
20 #include <boost/geometry/core/tags.hpp>
22 #include <boost/geometry/srs/projections/exception.hpp>
23 #include <boost/geometry/srs/projections/par_data.hpp>
24 #include <boost/geometry/srs/sphere.hpp>
25 #include <boost/geometry/srs/spheroid.hpp>
27 #include <boost/geometry/util/range.hpp>
29 #include <boost/range/begin.hpp>
30 #include <boost/range/end.hpp>
31 #include <boost/range/size.hpp>
32 #include <boost/range/value_type.hpp>
33 #include <boost/tuple/tuple.hpp>
34 #include <boost/variant/variant.hpp>
37 namespace boost { namespace geometry { namespace srs
43 template <typename T, int I, typename ...>
44 struct find_type_index_impl
45 : std::integral_constant<int, I>
55 struct find_type_index_impl<T, I, Type, Types...>
58 std::is_same<T, Type>::value,
59 std::integral_constant<int, I>,
60 typename find_type_index_impl<T, I + 1, Types...>::type
64 template <typename Variant, typename T>
65 struct find_type_index
68 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename T>
69 struct find_type_index<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, T>
70 : find_type_index_impl<T, 0, BOOST_VARIANT_ENUM_PARAMS(T)>
78 bool IsRange = range::detail::is_range<Range>::value
80 struct is_convertible_range
83 typename boost::range_value<Range>::type,
93 struct is_convertible_range<Range, ToValue, false>
201 proj_aitoff, proj_wintri,
203 proj_apian, proj_ortel, proj_bacon,
216 proj_eck3, proj_putp1, proj_wag6, proj_kav7,
221 proj_etmerc, proj_utm,
228 proj_gn_sinu, proj_sinu, proj_eck6, proj_mbtfps,
245 proj_lonlat, proj_latlon, proj_latlong, proj_longlat,
255 proj_mil_os, proj_lee_os, proj_gs48, proj_alsk, proj_gs50,
256 proj_moll, proj_wag4, proj_wag5,
261 proj_nsper, proj_tpers,
270 proj_putp3, proj_putp3p,
271 proj_putp4p, proj_weren,
272 proj_putp5, proj_putp5p,
273 proj_putp6, proj_putp6p,
278 proj_euler, proj_murd1, proj_murd2, proj_murd3, proj_pconic, proj_tissot, proj_vitk1,
280 proj_stere, proj_ups,
282 proj_kav5, proj_qua_aut, proj_fouc, proj_mbt_s,
288 proj_urmfps, proj_wag1,
290 proj_vandg2, proj_vandg3,
337 //h_0, // currently not used
340 m, // also used for M
342 //phdg_0, // currently not used
343 //plat_0, // currently not used
344 //plon_0, // currently not used
381 r_lat_a, // originally R_lat_a
382 r_lat_g, // originally R_lat_g
408 r_au, // originally R_A
409 r_a, // originally R_a
410 r_g, // originally R_g
411 r_h, // originally R_h
412 r_v, // originally R_V
419 catalog = 72 // currently not used
424 date = 73 // currently not used
434 ellps = 75 // id, sphere or spheroid
437 /*enum name_geoidgrids
439 geoidgrids = 76 // currently not used
449 nadgrids = 78 // arbitrary-length list of strings
459 pm = 80 // id or angle
475 towgs84 = 84 // 3 or 7 element list of numbers
484 template <typename T>
488 : m_id(-1), m_value(false)
491 parameter(name_f id, T const& v)
492 : m_id(id), m_value(v)
495 // TODO various angle units
496 parameter(name_r id, T const& v)
497 : m_id(id), m_value(v)
500 parameter(name_i id, int v)
501 : m_id(id), m_value(v)
504 parameter(name_be id)
505 : m_id(id), m_value(true)
508 parameter(name_be id, bool v)
509 : m_id(id), m_value(v)
512 parameter(name_datum id, value_datum v)
513 : m_id(id), m_value(int(v))
516 parameter(value_datum v)
517 : m_id(datum), m_value(int(v))
520 // TODO: store model at this point?
521 parameter(name_ellps id, value_ellps v)
522 : m_id(id), m_value(int(v))
524 // TODO: store model at this point?
525 parameter(value_ellps v)
526 : m_id(ellps), m_value(int(v))
534 std::is_same<typename geometry::tag<Sphere>::type, srs_sphere_tag>::value,
538 parameter(name_ellps id, Sphere const& v)
540 , m_value(T(get_radius<0>(v)))
548 std::is_same<typename geometry::tag<Spheroid>::type, srs_spheroid_tag>::value,
552 parameter(name_ellps id, Spheroid const& v)
554 , m_value(srs::spheroid<T>(get_radius<0>(v), get_radius<2>(v)))
557 parameter(name_mode id, value_mode v)
558 : m_id(id), m_value(int(v))
561 parameter(value_mode v)
562 : m_id(mode), m_value(int(v))
570 detail::is_convertible_range<Range const, std::string>::value,
574 parameter(name_nadgrids id, Range const& v)
576 , m_value(srs::detail::nadgrids(boost::begin(v), boost::end(v)))
579 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
580 parameter(name_nadgrids id, std::initializer_list<std::string> v)
582 , m_value(srs::detail::nadgrids(v))
586 parameter(name_orient id, value_orient v)
587 : m_id(id), m_value(int(v))
590 parameter(value_orient v)
591 : m_id(orient), m_value(int(v))
594 // TODO: store to_meters at this point?
595 parameter(name_pm id, value_pm v)
596 : m_id(id), m_value(int(v))
598 // TODO: store to_meters at this point?
599 parameter(value_pm v)
600 : m_id(pm), m_value(int(v))
604 parameter(name_pm id, T const& v)
605 : m_id(id), m_value(v)
608 parameter(name_proj id, value_proj v)
609 : m_id(id), m_value(int(v))
612 parameter(value_proj v)
613 : m_id(proj), m_value(int(v))
616 parameter(name_sweep id, value_sweep v)
617 : m_id(id), m_value(int(v))
620 parameter(value_sweep v)
621 : m_id(sweep), m_value(int(v))
629 detail::is_convertible_range<Range const, T>::value,
633 parameter(name_towgs84 id, Range const& v)
635 , m_value(srs::detail::towgs84<T>(boost::begin(v), boost::end(v)))
637 std::size_t n = boost::size(v);
638 if (n != 3 && n != 7)
640 BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
644 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
645 parameter(name_towgs84 id, std::initializer_list<T> v)
647 , m_value(srs::detail::towgs84<T>(v))
649 std::size_t n = v.size();
650 if (n != 3 && n != 7)
652 BOOST_THROW_EXCEPTION( projection_exception("Invalid number of towgs84 elements. Should be 3 or 7.") );
657 parameter(name_units id, value_units v)
658 : m_id(id), m_value(int(v))
661 parameter(value_units v)
662 : m_id(units), m_value(int(v))
666 typedef boost::variant
672 srs::detail::nadgrids,
673 srs::detail::towgs84<T>
677 bool is_id_equal(name_f const& id) const { return m_id == int(id); }
678 bool is_id_equal(name_r const& id) const { return m_id == int(id); }
679 bool is_id_equal(name_i const& id) const { return m_id == int(id); }
680 bool is_id_equal(name_be const& id) const { return m_id == int(id); }
681 bool is_id_equal(name_datum const& id) const { return m_id == int(id); }
682 bool is_id_equal(name_ellps const& id) const { return m_id == int(id); }
683 bool is_id_equal(name_mode const& id) const { return m_id == int(id); }
684 bool is_id_equal(name_nadgrids const& id) const { return m_id == int(id); }
685 bool is_id_equal(name_orient const& id) const { return m_id == int(id); }
686 bool is_id_equal(name_pm const& id) const { return m_id == int(id); }
687 bool is_id_equal(name_proj const& id) const { return m_id == int(id); }
688 bool is_id_equal(name_sweep const& id) const { return m_id == int(id); }
689 bool is_id_equal(name_towgs84 const& id) const { return m_id == int(id); }
690 bool is_id_equal(name_units const& id) const { return m_id == int(id); }
692 template <typename V>
693 V const& get_value() const
695 return boost::get<V>(m_value);
698 template <typename V>
699 bool is_value_set() const
701 return m_value.which() == srs::detail::find_type_index<variant_type, V>::value;
706 variant_type m_value;
709 template <typename T = double>
712 typedef std::vector<parameter<T> > container_type;
715 typedef typename container_type::value_type value_type;
716 typedef typename container_type::const_iterator const_iterator;
717 typedef typename container_type::const_reference const_reference;
718 typedef typename container_type::size_type size_type;
720 BOOST_DEFAULTED_FUNCTION(parameters(), {})
722 #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
723 template <typename Id>
724 explicit parameters(Id id)
729 template <typename Id>
730 parameters & add(Id id)
732 m_params.push_back(parameter<T>(id));
736 template <typename Id>
737 parameters & operator()(Id id)
742 template <typename Id, typename V>
743 parameters(Id id, V const& value)
748 template <typename Id, typename V>
749 parameters & add(Id id, V const& value)
751 m_params.push_back(parameter<T>(id, value));
755 template <typename Id, typename V>
756 parameters & operator()(Id id, V const& value)
758 return add(id, value);
761 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
762 template <typename Id, typename V>
763 parameters(Id id, std::initializer_list<V> value)
768 template <typename Id, typename V>
769 parameters & add(Id id, std::initializer_list<V> value)
771 m_params.push_back(parameter<T>(id, value));
775 template <typename Id, typename V>
776 parameters & operator()(Id id, std::initializer_list<V> value)
778 return add(id, value);
780 #endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
781 #else // BOOST_NO_CXX11_RVALUE_REFERENCES || BOOST_NO_CXX11_RVALUE_REFERENCES
782 template <typename Id>
783 explicit parameters(Id id)
788 template <typename Id>
789 parameters & add(Id id)
791 m_params.emplace_back(id);
795 template <typename Id>
796 parameters & operator()(Id id)
801 template <typename Id, typename V>
802 parameters(Id id, V && value)
804 add(id, std::forward<V>(value));
807 template <typename Id, typename V>
808 parameters & add(Id id, V && value)
810 m_params.emplace_back(id, std::forward<V>(value));
814 template <typename Id, typename V>
815 parameters & operator()(Id id, V && value)
817 return add(id, std::forward<V>(value));
820 #ifndef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
821 template <typename Id, typename V>
822 parameters(Id id, std::initializer_list<V> value)
827 template <typename Id, typename V>
828 parameters & add(Id id, std::initializer_list<V> value)
830 m_params.emplace_back(id, value);
834 template <typename Id, typename V>
835 parameters & operator()(Id id, std::initializer_list<V> value)
837 return add(id, value);
839 #endif // BOOST_NO_CXX11_HDR_INITIALIZER_LIST
840 #endif // BOOST_NO_CXX11_RVALUE_REFERENCES || BOOST_NO_CXX11_RVALUE_REFERENCES
842 const_iterator begin() const { return m_params.begin(); }
843 const_iterator end() const { return m_params.end(); }
844 const_reference operator[](size_type i) const { return m_params[i]; }
845 size_type size() { return m_params.size(); }
846 bool empty() { return m_params.empty(); }
849 container_type m_params;
856 }}} // namespace boost::geometry::srs
859 #endif // BOOST_GEOMETRY_SRS_PROJECTIONS_DPAR_HPP