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, 2018.
8 // Modifications copyright (c) 2013-2018 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<Geometry1, Geometry2, Strategy>();
67 concepts::check<Geometry1 const>();
68 concepts::check<Geometry2 const>();
69 assert_dimension_equal<Geometry1, Geometry2>();
70
71 return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1,
72 geometry2,
73 strategy);
74 }
75
76 template <typename Geometry1, typename Geometry2>
applyboost::geometry::resolve_strategy::covered_by77 static inline bool apply(Geometry1 const& geometry1,
78 Geometry2 const& geometry2,
79 default_strategy)
80 {
81 typedef typename strategy::covered_by::services::default_strategy
82 <
83 Geometry1,
84 Geometry2
85 >::type strategy_type;
86
87 return covered_by::apply(geometry1, geometry2, strategy_type());
88 }
89 };
90
91 } // namespace resolve_strategy
92
93
94 namespace resolve_variant {
95
96 template <typename Geometry1, typename Geometry2>
97 struct covered_by
98 {
99 template <typename Strategy>
applyboost::geometry::resolve_variant::covered_by100 static inline bool apply(Geometry1 const& geometry1,
101 Geometry2 const& geometry2,
102 Strategy const& strategy)
103 {
104 return resolve_strategy::covered_by
105 ::apply(geometry1, geometry2, strategy);
106 }
107 };
108
109 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
110 struct covered_by<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
111 {
112 template <typename Strategy>
113 struct visitor: boost::static_visitor<bool>
114 {
115 Geometry2 const& m_geometry2;
116 Strategy const& m_strategy;
117
visitorboost::geometry::resolve_variant::covered_by::visitor118 visitor(Geometry2 const& geometry2, Strategy const& strategy)
119 : m_geometry2(geometry2), m_strategy(strategy) {}
120
121 template <typename Geometry1>
operator ()boost::geometry::resolve_variant::covered_by::visitor122 bool operator()(Geometry1 const& geometry1) const
123 {
124 return covered_by<Geometry1, Geometry2>
125 ::apply(geometry1, m_geometry2, m_strategy);
126 }
127 };
128
129 template <typename Strategy>
130 static inline bool
applyboost::geometry::resolve_variant::covered_by131 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
132 Geometry2 const& geometry2,
133 Strategy const& strategy)
134 {
135 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
136 }
137 };
138
139 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
140 struct covered_by<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
141 {
142 template <typename Strategy>
143 struct visitor: boost::static_visitor<bool>
144 {
145 Geometry1 const& m_geometry1;
146 Strategy const& m_strategy;
147
visitorboost::geometry::resolve_variant::covered_by::visitor148 visitor(Geometry1 const& geometry1, Strategy const& strategy)
149 : m_geometry1(geometry1), m_strategy(strategy) {}
150
151 template <typename Geometry2>
operator ()boost::geometry::resolve_variant::covered_by::visitor152 bool operator()(Geometry2 const& geometry2) const
153 {
154 return covered_by<Geometry1, Geometry2>
155 ::apply(m_geometry1, geometry2, m_strategy);
156 }
157 };
158
159 template <typename Strategy>
160 static inline bool
applyboost::geometry::resolve_variant::covered_by161 apply(Geometry1 const& geometry1,
162 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
163 Strategy const& strategy)
164 {
165 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
166 }
167 };
168
169 template <
170 BOOST_VARIANT_ENUM_PARAMS(typename T1),
171 BOOST_VARIANT_ENUM_PARAMS(typename T2)
172 >
173 struct covered_by<
174 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
175 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
176 >
177 {
178 template <typename Strategy>
179 struct visitor: boost::static_visitor<bool>
180 {
181 Strategy const& m_strategy;
182
visitorboost::geometry::resolve_variant::covered_by::visitor183 visitor(Strategy const& strategy): m_strategy(strategy) {}
184
185 template <typename Geometry1, typename Geometry2>
operator ()boost::geometry::resolve_variant::covered_by::visitor186 bool operator()(Geometry1 const& geometry1,
187 Geometry2 const& geometry2) const
188 {
189 return covered_by<Geometry1, Geometry2>
190 ::apply(geometry1, geometry2, m_strategy);
191 }
192 };
193
194 template <typename Strategy>
195 static inline bool
applyboost::geometry::resolve_variant::covered_by196 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
197 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
198 Strategy const& strategy)
199 {
200 return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
201 }
202 };
203
204 } // namespace resolve_variant
205
206
207 /*!
208 \brief \brief_check12{is inside or on border}
209 \ingroup covered_by
210 \details \details_check12{covered_by, is inside or on border}.
211 \tparam Geometry1 \tparam_geometry
212 \tparam Geometry2 \tparam_geometry
213 \param geometry1 \param_geometry which might be inside or on the border of the second geometry
214 \param geometry2 \param_geometry which might cover the first geometry
215 \return true if geometry1 is inside of or on the border of geometry2,
216 else false
217 \note The default strategy is used for covered_by detection
218
219 \qbk{[include reference/algorithms/covered_by.qbk]}
220 \qbk{
221 [heading Examples]
222 [covered_by]
223 [covered_by_output]
224 }
225 */
226 template<typename Geometry1, typename Geometry2>
covered_by(Geometry1 const & geometry1,Geometry2 const & geometry2)227 inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
228 {
229 return resolve_variant::covered_by<Geometry1, Geometry2>
230 ::apply(geometry1, geometry2, default_strategy());
231 }
232
233 /*!
234 \brief \brief_check12{is inside or on border} \brief_strategy
235 \ingroup covered_by
236 \details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
237 \tparam Geometry1 \tparam_geometry
238 \tparam Geometry2 \tparam_geometry
239 \param geometry1 \param_geometry which might be inside or on the border of the second geometry
240 \param geometry2 \param_geometry which might cover the first geometry
241 \param strategy strategy to be used
242 \return true if geometry1 is inside of or on the border of geometry2,
243 else false
244
245 \qbk{distinguish,with strategy}
246 \qbk{[include reference/algorithms/covered_by.qbk]}
247
248 */
249 template<typename Geometry1, typename Geometry2, typename Strategy>
covered_by(Geometry1 const & geometry1,Geometry2 const & geometry2,Strategy const & strategy)250 inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
251 Strategy const& strategy)
252 {
253 return resolve_variant::covered_by<Geometry1, Geometry2>
254 ::apply(geometry1, geometry2, strategy);
255 }
256
257 }} // namespace boost::geometry
258
259 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_COVERED_BY_INTERFACE_HPP
260