1 // Boost.Geometry
2 
3 // Copyright (c) 2020-2021, Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
6 
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
9 
10 #ifndef BOOST_GEOMETRY_STRATEGIES_ENVELOPE_GEOGRAPHIC_HPP
11 #define BOOST_GEOMETRY_STRATEGIES_ENVELOPE_GEOGRAPHIC_HPP
12 
13 
14 #include <type_traits>
15 
16 #include <boost/geometry/strategy/geographic/envelope.hpp>
17 #include <boost/geometry/strategy/geographic/envelope_segment.hpp>
18 
19 #include <boost/geometry/strategy/geographic/expand_segment.hpp> // TEMP
20 
21 #include <boost/geometry/strategies/envelope/spherical.hpp>
22 #include <boost/geometry/strategies/expand/geographic.hpp>
23 
24 
25 namespace boost { namespace geometry
26 {
27 
28 namespace strategies { namespace envelope
29 {
30 
31 template
32 <
33     typename FormulaPolicy = strategy::andoyer,
34     typename Spheroid = srs::spheroid<double>,
35     typename CalculationType = void
36 >
37 class geographic
38     : public strategies::expand::geographic<FormulaPolicy, Spheroid, CalculationType>
39 {
40     using base_t = strategies::expand::geographic<FormulaPolicy, Spheroid, CalculationType>;
41 
42 public:
43     geographic() = default;
44 
geographic(Spheroid const & spheroid)45     explicit geographic(Spheroid const& spheroid)
46         : base_t(spheroid)
47     {}
48 
49     template <typename Geometry, typename Box>
envelope(Geometry const &,Box const &,typename util::enable_if_point_t<Geometry> * =nullptr)50     static auto envelope(Geometry const&, Box const&,
51                          typename util::enable_if_point_t<Geometry> * = nullptr)
52     {
53         return strategy::envelope::spherical_point();
54     }
55 
56     template <typename Geometry, typename Box>
envelope(Geometry const &,Box const &,typename util::enable_if_multi_point_t<Geometry> * =nullptr)57     static auto envelope(Geometry const&, Box const&,
58                          typename util::enable_if_multi_point_t<Geometry> * = nullptr)
59     {
60         return strategy::envelope::spherical_multipoint();
61     }
62 
63     template <typename Geometry, typename Box>
envelope(Geometry const &,Box const &,typename util::enable_if_box_t<Geometry> * =nullptr)64     static auto envelope(Geometry const&, Box const&,
65                          typename util::enable_if_box_t<Geometry> * = nullptr)
66     {
67         return strategy::envelope::spherical_box();
68     }
69 
70     template <typename Geometry, typename Box>
envelope(Geometry const &,Box const &,typename util::enable_if_segment_t<Geometry> * =nullptr) const71     auto envelope(Geometry const&, Box const&,
72                   typename util::enable_if_segment_t<Geometry> * = nullptr) const
73     {
74         return strategy::envelope::geographic_segment
75             <
76                 FormulaPolicy, Spheroid, CalculationType
77             >(base_t::m_spheroid);
78     }
79 
80     template <typename Geometry, typename Box>
envelope(Geometry const &,Box const &,typename util::enable_if_polysegmental_t<Geometry> * =nullptr) const81     auto envelope(Geometry const&, Box const&,
82                   typename util::enable_if_polysegmental_t<Geometry> * = nullptr) const
83     {
84         return strategy::envelope::geographic
85             <
86                 FormulaPolicy, Spheroid, CalculationType
87             >(base_t::m_spheroid);
88     }
89 
90     template <typename Geometry, typename Box>
envelope(Geometry const &,Box const &,typename util::enable_if_geometry_collection_t<Geometry> * =nullptr) const91     auto envelope(Geometry const&, Box const&,
92                   typename util::enable_if_geometry_collection_t<Geometry> * = nullptr) const
93     {
94         return strategy::envelope::geographic
95             <
96                 FormulaPolicy, Spheroid, CalculationType
97             >(base_t::m_spheroid);
98     }
99 };
100 
101 
102 namespace services
103 {
104 
105 template <typename Geometry, typename Box>
106 struct default_strategy<Geometry, Box, geographic_tag>
107 {
108     using type = strategies::envelope::geographic<>;
109 };
110 
111 
112 template <typename FP, typename S, typename CT>
113 struct strategy_converter<strategy::envelope::geographic_segment<FP, S, CT> >
114 {
getboost::geometry::strategies::envelope::services::strategy_converter115     static auto get(strategy::envelope::geographic_segment<FP, S, CT> const& s)
116     {
117         return strategies::envelope::geographic<FP, S, CT>(s.model());
118     }
119 };
120 
121 template <typename FP, typename S, typename CT>
122 struct strategy_converter<strategy::envelope::geographic<FP, S, CT> >
123 {
getboost::geometry::strategies::envelope::services::strategy_converter124     static auto get(strategy::envelope::geographic<FP, S, CT> const& s)
125     {
126         return strategies::envelope::geographic<FP, S, CT>(s.model());
127     }
128 };
129 
130 } // namespace services
131 
132 }} // namespace strategies::envelope
133 
134 }} // namespace boost::geometry
135 
136 #endif // BOOST_GEOMETRY_STRATEGIES_ENVELOPE_GEOGRAPHIC_HPP
137