1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
6 
7 // This file was modified by Oracle on 2015-2020.
8 // Modifications copyright (c) 2015-2020, Oracle and/or its affiliates.
9 
10 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
11 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
12 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
13 
14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
16 
17 // Distributed under the Boost Software License, Version 1.0.
18 // (See accompanying file LICENSE_1_0.txt or copy at
19 // http://www.boost.org/LICENSE_1_0.txt)
20 
21 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
22 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
23 
24 
25 #include <boost/variant/apply_visitor.hpp>
26 #include <boost/variant/static_visitor.hpp>
27 #include <boost/variant/variant_fwd.hpp>
28 
29 #include <boost/geometry/algorithms/dispatch/envelope.hpp>
30 
31 #include <boost/geometry/core/coordinate_system.hpp>
32 #include <boost/geometry/core/tag.hpp>
33 #include <boost/geometry/core/tags.hpp>
34 
35 #include <boost/geometry/geometries/concepts/check.hpp>
36 
37 #include <boost/geometry/strategies/default_strategy.hpp>
38 #include <boost/geometry/strategies/detail.hpp>
39 #include <boost/geometry/strategies/envelope/services.hpp>
40 #include <boost/geometry/strategy/envelope.hpp>
41 
42 #include <boost/geometry/util/select_most_precise.hpp>
43 
44 
45 namespace boost { namespace geometry
46 {
47 
48 namespace resolve_strategy
49 {
50 
51 template
52 <
53     typename Strategy,
54     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
55 >
56 struct envelope
57 {
58     template <typename Geometry, typename Box>
applyboost::geometry::resolve_strategy::envelope59     static inline void apply(Geometry const& geometry,
60                              Box& box,
61                              Strategy const& strategy)
62     {
63         dispatch::envelope<Geometry>::apply(geometry, box, strategy);
64     }
65 };
66 
67 template <typename Strategy>
68 struct envelope<Strategy, false>
69 {
70     template <typename Geometry, typename Box>
applyboost::geometry::resolve_strategy::envelope71     static inline void apply(Geometry const& geometry,
72                              Box& box,
73                              Strategy const& strategy)
74     {
75         using strategies::envelope::services::strategy_converter;
76         return dispatch::envelope
77             <
78                 Geometry
79             >::apply(geometry, box, strategy_converter<Strategy>::get(strategy));
80     }
81 };
82 
83 template <>
84 struct envelope<default_strategy, false>
85 {
86     template <typename Geometry, typename Box>
applyboost::geometry::resolve_strategy::envelope87     static inline void apply(Geometry const& geometry,
88                              Box& box,
89                              default_strategy)
90     {
91         typedef typename strategies::envelope::services::default_strategy
92             <
93                 Geometry, Box
94             >::type strategy_type;
95 
96         dispatch::envelope<Geometry>::apply(geometry, box, strategy_type());
97     }
98 };
99 
100 } // namespace resolve_strategy
101 
102 namespace resolve_variant
103 {
104 
105 template <typename Geometry>
106 struct envelope
107 {
108     template <typename Box, typename Strategy>
applyboost::geometry::resolve_variant::envelope109     static inline void apply(Geometry const& geometry,
110                              Box& box,
111                              Strategy const& strategy)
112     {
113         concepts::check<Geometry const>();
114         concepts::check<Box>();
115 
116         resolve_strategy::envelope<Strategy>::apply(geometry, box, strategy);
117     }
118 };
119 
120 
121 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
122 struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
123 {
124     template <typename Box, typename Strategy>
125     struct visitor: boost::static_visitor<void>
126     {
127         Box& m_box;
128         Strategy const& m_strategy;
129 
visitorboost::geometry::resolve_variant::envelope::visitor130         visitor(Box& box, Strategy const& strategy)
131             : m_box(box)
132             , m_strategy(strategy)
133         {}
134 
135         template <typename Geometry>
operator ()boost::geometry::resolve_variant::envelope::visitor136         void operator()(Geometry const& geometry) const
137         {
138             envelope<Geometry>::apply(geometry, m_box, m_strategy);
139         }
140     };
141 
142     template <typename Box, typename Strategy>
143     static inline void
applyboost::geometry::resolve_variant::envelope144     apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry,
145           Box& box,
146           Strategy const& strategy)
147     {
148         boost::apply_visitor(visitor<Box, Strategy>(box, strategy), geometry);
149     }
150 };
151 
152 } // namespace resolve_variant
153 
154 
155 /*!
156 \brief \brief_calc{envelope (with strategy)}
157 \ingroup envelope
158 \details \details_calc{envelope,\det_envelope}.
159 \tparam Geometry \tparam_geometry
160 \tparam Box \tparam_box
161 \tparam Strategy \tparam_strategy{Envelope}
162 \param geometry \param_geometry
163 \param mbr \param_box \param_set{envelope}
164 \param strategy \param_strategy{envelope}
165 
166 \qbk{distinguish,with strategy}
167 \qbk{[include reference/algorithms/envelope.qbk]}
168 \qbk{
169 [heading Example]
170 [envelope] [envelope_output]
171 }
172 */
173 template<typename Geometry, typename Box, typename Strategy>
envelope(Geometry const & geometry,Box & mbr,Strategy const & strategy)174 inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strategy)
175 {
176     resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
177 }
178 
179 /*!
180 \brief \brief_calc{envelope}
181 \ingroup envelope
182 \details \details_calc{envelope,\det_envelope}.
183 \tparam Geometry \tparam_geometry
184 \tparam Box \tparam_box
185 \param geometry \param_geometry
186 \param mbr \param_box \param_set{envelope}
187 
188 \qbk{[include reference/algorithms/envelope.qbk]}
189 \qbk{
190 [heading Example]
191 [envelope] [envelope_output]
192 }
193 */
194 template<typename Geometry, typename Box>
envelope(Geometry const & geometry,Box & mbr)195 inline void envelope(Geometry const& geometry, Box& mbr)
196 {
197     resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
198 }
199 
200 
201 /*!
202 \brief \brief_calc{envelope}
203 \ingroup envelope
204 \details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
205 \tparam Box \tparam_box
206 \tparam Geometry \tparam_geometry
207 \tparam Strategy \tparam_strategy{Envelope}
208 \param geometry \param_geometry
209 \param strategy \param_strategy{envelope}
210 \return \return_calc{envelope}
211 
212 \qbk{distinguish,with strategy}
213 \qbk{[include reference/algorithms/envelope.qbk]}
214 \qbk{
215 [heading Example]
216 [return_envelope] [return_envelope_output]
217 }
218 */
219 template<typename Box, typename Geometry, typename Strategy>
return_envelope(Geometry const & geometry,Strategy const & strategy)220 inline Box return_envelope(Geometry const& geometry, Strategy const& strategy)
221 {
222     Box mbr;
223     resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy);
224     return mbr;
225 }
226 
227 /*!
228 \brief \brief_calc{envelope}
229 \ingroup envelope
230 \details \details_calc{return_envelope,\det_envelope}. \details_return{envelope}
231 \tparam Box \tparam_box
232 \tparam Geometry \tparam_geometry
233 \param geometry \param_geometry
234 \return \return_calc{envelope}
235 
236 \qbk{[include reference/algorithms/envelope.qbk]}
237 \qbk{
238 [heading Example]
239 [return_envelope] [return_envelope_output]
240 }
241 */
242 template<typename Box, typename Geometry>
return_envelope(Geometry const & geometry)243 inline Box return_envelope(Geometry const& geometry)
244 {
245     Box mbr;
246     resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy());
247     return mbr;
248 }
249 
250 }} // namespace boost::geometry
251 
252 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
253