1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6 
7 // This file was modified by Oracle on 2013, 2014, 2017.
8 // Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
9 
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11 
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
14 
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
18 
19 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
21 
22 
23 #include <boost/variant/apply_visitor.hpp>
24 #include <boost/variant/static_visitor.hpp>
25 #include <boost/variant/variant_fwd.hpp>
26 
27 #include <boost/geometry/algorithms/detail/within/interface.hpp>
28 #include <boost/geometry/algorithms/not_implemented.hpp>
29 
30 #include <boost/geometry/strategies/cartesian/point_in_box.hpp>
31 #include <boost/geometry/strategies/cartesian/box_in_box.hpp>
32 #include <boost/geometry/strategies/default_strategy.hpp>
33 
34 
35 namespace boost { namespace geometry
36 {
37 
38 #ifndef DOXYGEN_NO_DISPATCH
39 namespace dispatch
40 {
41 
42 template
43 <
44     typename Geometry1,
45     typename Geometry2,
46     typename Tag1 = typename tag<Geometry1>::type,
47     typename Tag2 = typename tag<Geometry2>::type
48 >
49 struct covered_by
50     : not_implemented<Tag1, Tag2>
51 {};
52 
53 } // namespace dispatch
54 #endif // DOXYGEN_NO_DISPATCH
55 
56 
57 namespace resolve_strategy {
58 
59 struct covered_by
60 {
61     template <typename Geometry1, typename Geometry2, typename Strategy>
applyboost::geometry::resolve_strategy::covered_by62     static inline bool apply(Geometry1 const& geometry1,
63                              Geometry2 const& geometry2,
64                              Strategy const& strategy)
65     {
66         concepts::within::check
67             <
68                 typename tag<Geometry1>::type,
69                 typename tag<Geometry2>::type,
70                 typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
71                 Strategy
72             >();
73         concepts::check<Geometry1 const>();
74         concepts::check<Geometry2 const>();
75         assert_dimension_equal<Geometry1, Geometry2>();
76 
77         return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1,
78                                                                  geometry2,
79                                                                  strategy);
80     }
81 
82     template <typename Geometry1, typename Geometry2>
applyboost::geometry::resolve_strategy::covered_by83     static inline bool apply(Geometry1 const& geometry1,
84                              Geometry2 const& geometry2,
85                              default_strategy)
86     {
87         typedef typename strategy::covered_by::services::default_strategy
88             <
89                 Geometry1,
90                 Geometry2
91             >::type strategy_type;
92 
93         return covered_by::apply(geometry1, geometry2, strategy_type());
94     }
95 };
96 
97 } // namespace resolve_strategy
98 
99 
100 namespace resolve_variant {
101 
102 template <typename Geometry1, typename Geometry2>
103 struct covered_by
104 {
105     template <typename Strategy>
applyboost::geometry::resolve_variant::covered_by106     static inline bool apply(Geometry1 const& geometry1,
107                              Geometry2 const& geometry2,
108                              Strategy const& strategy)
109     {
110         return resolve_strategy::covered_by
111                                ::apply(geometry1, geometry2, strategy);
112     }
113 };
114 
115 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
116 struct covered_by<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
117 {
118     template <typename Strategy>
119     struct visitor: boost::static_visitor<bool>
120     {
121         Geometry2 const& m_geometry2;
122         Strategy const& m_strategy;
123 
visitorboost::geometry::resolve_variant::covered_by::visitor124         visitor(Geometry2 const& geometry2, Strategy const& strategy)
125         : m_geometry2(geometry2), m_strategy(strategy) {}
126 
127         template <typename Geometry1>
operator ()boost::geometry::resolve_variant::covered_by::visitor128         bool operator()(Geometry1 const& geometry1) const
129         {
130             return covered_by<Geometry1, Geometry2>
131                    ::apply(geometry1, m_geometry2, m_strategy);
132         }
133     };
134 
135     template <typename Strategy>
136     static inline bool
applyboost::geometry::resolve_variant::covered_by137     apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
138           Geometry2 const& geometry2,
139           Strategy const& strategy)
140     {
141         return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
142     }
143 };
144 
145 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
146 struct covered_by<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
147 {
148     template <typename Strategy>
149     struct visitor: boost::static_visitor<bool>
150     {
151         Geometry1 const& m_geometry1;
152         Strategy const& m_strategy;
153 
visitorboost::geometry::resolve_variant::covered_by::visitor154         visitor(Geometry1 const& geometry1, Strategy const& strategy)
155         : m_geometry1(geometry1), m_strategy(strategy) {}
156 
157         template <typename Geometry2>
operator ()boost::geometry::resolve_variant::covered_by::visitor158         bool operator()(Geometry2 const& geometry2) const
159         {
160             return covered_by<Geometry1, Geometry2>
161                    ::apply(m_geometry1, geometry2, m_strategy);
162         }
163     };
164 
165     template <typename Strategy>
166     static inline bool
applyboost::geometry::resolve_variant::covered_by167     apply(Geometry1 const& geometry1,
168           boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
169           Strategy const& strategy)
170     {
171         return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
172     }
173 };
174 
175 template <
176     BOOST_VARIANT_ENUM_PARAMS(typename T1),
177     BOOST_VARIANT_ENUM_PARAMS(typename T2)
178 >
179 struct covered_by<
180     boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
181     boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
182 >
183 {
184     template <typename Strategy>
185     struct visitor: boost::static_visitor<bool>
186     {
187         Strategy const& m_strategy;
188 
visitorboost::geometry::resolve_variant::covered_by::visitor189         visitor(Strategy const& strategy): m_strategy(strategy) {}
190 
191         template <typename Geometry1, typename Geometry2>
operator ()boost::geometry::resolve_variant::covered_by::visitor192         bool operator()(Geometry1 const& geometry1,
193                         Geometry2 const& geometry2) const
194         {
195             return covered_by<Geometry1, Geometry2>
196                    ::apply(geometry1, geometry2, m_strategy);
197         }
198     };
199 
200     template <typename Strategy>
201     static inline bool
applyboost::geometry::resolve_variant::covered_by202     apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
203           boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
204           Strategy const& strategy)
205     {
206         return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
207     }
208 };
209 
210 } // namespace resolve_variant
211 
212 
213 /*!
214 \brief \brief_check12{is inside or on border}
215 \ingroup covered_by
216 \details \details_check12{covered_by, is inside or on border}.
217 \tparam Geometry1 \tparam_geometry
218 \tparam Geometry2 \tparam_geometry
219 \param geometry1 \param_geometry which might be inside or on the border of the second geometry
220 \param geometry2 \param_geometry which might cover the first geometry
221 \return true if geometry1 is inside of or on the border of geometry2,
222     else false
223 \note The default strategy is used for covered_by detection
224 
225 \qbk{[include reference/algorithms/covered_by.qbk]}
226 
227  */
228 template<typename Geometry1, typename Geometry2>
covered_by(Geometry1 const & geometry1,Geometry2 const & geometry2)229 inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
230 {
231     return resolve_variant::covered_by<Geometry1, Geometry2>
232                           ::apply(geometry1, geometry2, default_strategy());
233 }
234 
235 /*!
236 \brief \brief_check12{is inside or on border} \brief_strategy
237 \ingroup covered_by
238 \details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
239 \tparam Geometry1 \tparam_geometry
240 \tparam Geometry2 \tparam_geometry
241 \param geometry1 \param_geometry which might be inside or on the border of the second geometry
242 \param geometry2 \param_geometry which might cover the first geometry
243 \param strategy strategy to be used
244 \return true if geometry1 is inside of or on the border of geometry2,
245     else false
246 
247 \qbk{distinguish,with strategy}
248 \qbk{[include reference/algorithms/covered_by.qbk]}
249 
250 */
251 template<typename Geometry1, typename Geometry2, typename Strategy>
covered_by(Geometry1 const & geometry1,Geometry2 const & geometry2,Strategy const & strategy)252 inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
253         Strategy const& strategy)
254 {
255     return resolve_variant::covered_by<Geometry1, Geometry2>
256                           ::apply(geometry1, geometry2, strategy);
257 }
258 
259 }} // namespace boost::geometry
260 
261 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
262