]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
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 | // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. | |
7 | ||
1e59de90 TL |
8 | // This file was modified by Oracle on 2013-2021. |
9 | // Modifications copyright (c) 2013-2021, Oracle and/or its affiliates. | |
b32b8144 FG |
10 | |
11 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
12 | ||
13 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
14 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
15 | ||
16 | // Use, modification and distribution is subject to the Boost Software License, | |
17 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
18 | // http://www.boost.org/LICENSE_1_0.txt) | |
19 | ||
20 | #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP | |
21 | #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP | |
22 | ||
23 | ||
24 | #include <deque> | |
25 | ||
26 | #include <boost/variant/apply_visitor.hpp> | |
27 | #include <boost/variant/static_visitor.hpp> | |
28 | #include <boost/variant/variant_fwd.hpp> | |
29 | ||
30 | #include <boost/geometry/core/reverse_dispatch.hpp> | |
31 | #include <boost/geometry/core/tag.hpp> | |
32 | #include <boost/geometry/core/tag_cast.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> | |
1e59de90 TL |
38 | #include <boost/geometry/strategies/detail.hpp> |
39 | #include <boost/geometry/strategies/relate/services.hpp> | |
b32b8144 FG |
40 | |
41 | ||
42 | namespace boost { namespace geometry | |
43 | { | |
44 | ||
45 | #ifndef DOXYGEN_NO_DISPATCH | |
46 | namespace dispatch { | |
47 | ||
48 | // TODO: Since CastedTags are used is Reverse needed? | |
49 | ||
50 | template | |
51 | < | |
52 | typename Geometry1, | |
53 | typename Geometry2, | |
54 | typename Tag1 = typename tag<Geometry1>::type, | |
55 | typename Tag2 = typename tag<Geometry2>::type, | |
56 | typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type, | |
57 | typename CastedTag2 = typename tag_cast<Tag2, pointlike_tag, linear_tag, areal_tag>::type, | |
58 | bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value | |
59 | > | |
60 | struct touches | |
61 | : not_implemented<Tag1, Tag2> | |
62 | {}; | |
63 | ||
64 | // If reversal is needed, perform it | |
65 | template | |
66 | < | |
67 | typename Geometry1, typename Geometry2, | |
68 | typename Tag1, typename Tag2, | |
69 | typename CastedTag1, typename CastedTag2 | |
70 | > | |
71 | struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true> | |
72 | : touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false> | |
73 | { | |
74 | template <typename Strategy> | |
75 | static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy) | |
76 | { | |
77 | return touches<Geometry2, Geometry1>::apply(g2, g1, strategy); | |
78 | } | |
79 | }; | |
80 | ||
81 | } // namespace dispatch | |
82 | #endif // DOXYGEN_NO_DISPATCH | |
83 | ||
84 | ||
85 | namespace resolve_strategy | |
86 | { | |
87 | ||
1e59de90 TL |
88 | template |
89 | < | |
90 | typename Strategy, | |
91 | bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value | |
92 | > | |
b32b8144 FG |
93 | struct touches |
94 | { | |
1e59de90 | 95 | template <typename Geometry1, typename Geometry2> |
b32b8144 FG |
96 | static inline bool apply(Geometry1 const& geometry1, |
97 | Geometry2 const& geometry2, | |
98 | Strategy const& strategy) | |
99 | { | |
100 | return dispatch::touches | |
101 | < | |
102 | Geometry1, Geometry2 | |
103 | >::apply(geometry1, geometry2, strategy); | |
104 | } | |
1e59de90 | 105 | }; |
b32b8144 | 106 | |
1e59de90 TL |
107 | template <typename Strategy> |
108 | struct touches<Strategy, false> | |
109 | { | |
110 | template <typename Geometry1, typename Geometry2> | |
111 | static inline bool apply(Geometry1 const& geometry1, | |
112 | Geometry2 const& geometry2, | |
113 | Strategy const& strategy) | |
114 | { | |
115 | using strategies::relate::services::strategy_converter; | |
116 | ||
117 | return dispatch::touches | |
118 | < | |
119 | Geometry1, Geometry2 | |
120 | >::apply(geometry1, geometry2, | |
121 | strategy_converter<Strategy>::get(strategy)); | |
122 | } | |
123 | }; | |
124 | ||
125 | template <> | |
126 | struct touches<default_strategy, false> | |
127 | { | |
b32b8144 FG |
128 | template <typename Geometry1, typename Geometry2> |
129 | static inline bool apply(Geometry1 const& geometry1, | |
130 | Geometry2 const& geometry2, | |
131 | default_strategy) | |
132 | { | |
1e59de90 | 133 | typedef typename strategies::relate::services::default_strategy |
b32b8144 FG |
134 | < |
135 | Geometry1, | |
136 | Geometry2 | |
137 | >::type strategy_type; | |
138 | ||
139 | return dispatch::touches | |
140 | < | |
141 | Geometry1, Geometry2 | |
142 | >::apply(geometry1, geometry2, strategy_type()); | |
143 | } | |
144 | }; | |
145 | ||
146 | } // namespace resolve_strategy | |
147 | ||
148 | ||
149 | namespace resolve_variant { | |
150 | ||
151 | template <typename Geometry1, typename Geometry2> | |
152 | struct touches | |
153 | { | |
154 | template <typename Strategy> | |
155 | static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) | |
156 | { | |
157 | concepts::check<Geometry1 const>(); | |
158 | concepts::check<Geometry2 const>(); | |
159 | ||
1e59de90 TL |
160 | return resolve_strategy::touches |
161 | < | |
162 | Strategy | |
163 | >::apply(geometry1, geometry2, strategy); | |
b32b8144 FG |
164 | } |
165 | }; | |
166 | ||
167 | template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2> | |
168 | struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2> | |
169 | { | |
170 | template <typename Strategy> | |
171 | struct visitor: boost::static_visitor<bool> | |
172 | { | |
173 | Geometry2 const& m_geometry2; | |
174 | Strategy const& m_strategy; | |
175 | ||
176 | visitor(Geometry2 const& geometry2, Strategy const& strategy) | |
177 | : m_geometry2(geometry2) | |
178 | , m_strategy(strategy) | |
179 | {} | |
180 | ||
181 | template <typename Geometry1> | |
182 | bool operator()(Geometry1 const& geometry1) const | |
183 | { | |
184 | return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2, m_strategy); | |
185 | } | |
186 | }; | |
187 | ||
188 | template <typename Strategy> | |
189 | static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1, | |
190 | Geometry2 const& geometry2, | |
191 | Strategy const& strategy) | |
192 | { | |
193 | return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1); | |
194 | } | |
195 | }; | |
196 | ||
197 | template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
198 | struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
199 | { | |
200 | template <typename Strategy> | |
201 | struct visitor: boost::static_visitor<bool> | |
202 | { | |
203 | Geometry1 const& m_geometry1; | |
204 | Strategy const& m_strategy; | |
205 | ||
206 | visitor(Geometry1 const& geometry1, Strategy const& strategy) | |
207 | : m_geometry1(geometry1) | |
208 | , m_strategy(strategy) | |
209 | {} | |
210 | ||
211 | template <typename Geometry2> | |
212 | bool operator()(Geometry2 const& geometry2) const | |
213 | { | |
214 | return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2, m_strategy); | |
215 | } | |
216 | }; | |
217 | ||
218 | template <typename Strategy> | |
219 | static inline bool apply(Geometry1 const& geometry1, | |
220 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2, | |
221 | Strategy const& strategy) | |
222 | { | |
223 | return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2); | |
224 | } | |
225 | }; | |
226 | ||
227 | template <BOOST_VARIANT_ENUM_PARAMS(typename T1), | |
228 | BOOST_VARIANT_ENUM_PARAMS(typename T2)> | |
229 | struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, | |
230 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> > | |
231 | { | |
232 | template <typename Strategy> | |
233 | struct visitor: boost::static_visitor<bool> | |
234 | { | |
235 | Strategy const& m_strategy; | |
236 | ||
237 | visitor(Strategy const& strategy) | |
238 | : m_strategy(strategy) | |
239 | {} | |
240 | ||
241 | template <typename Geometry1, typename Geometry2> | |
242 | bool operator()(Geometry1 const& geometry1, | |
243 | Geometry2 const& geometry2) const | |
244 | { | |
245 | return touches<Geometry1, Geometry2>::apply(geometry1, geometry2, m_strategy); | |
246 | } | |
247 | }; | |
248 | ||
249 | template <typename Strategy> | |
250 | static inline bool apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1, | |
251 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2, | |
252 | Strategy const& strategy) | |
253 | { | |
254 | return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2); | |
255 | } | |
256 | }; | |
257 | ||
258 | template <typename Geometry> | |
259 | struct self_touches; | |
260 | ||
261 | template <BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
262 | struct self_touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
263 | { | |
264 | struct visitor: boost::static_visitor<bool> | |
265 | { | |
266 | template <typename Geometry> | |
267 | bool operator()(Geometry const& geometry) const | |
268 | { | |
269 | return self_touches<Geometry>::apply(geometry); | |
270 | } | |
271 | }; | |
272 | ||
273 | static inline bool | |
274 | apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry) | |
275 | { | |
276 | return boost::apply_visitor(visitor(), geometry); | |
277 | } | |
278 | }; | |
279 | ||
280 | } // namespace resolve_variant | |
281 | ||
282 | ||
283 | /*! | |
284 | \brief \brief_check{has at least one touching point (self-tangency)} | |
285 | \note This function can be called for one geometry (self-tangency) and | |
286 | also for two geometries (touch) | |
287 | \ingroup touches | |
288 | \tparam Geometry \tparam_geometry | |
289 | \param geometry \param_geometry | |
290 | \return \return_check{is self-touching} | |
291 | ||
292 | \qbk{distinguish,one geometry} | |
293 | \qbk{[def __one_parameter__]} | |
294 | \qbk{[include reference/algorithms/touches.qbk]} | |
f67539c2 TL |
295 | \qbk{ |
296 | [heading Examples] | |
297 | [touches_one_geometry] | |
298 | [touches_one_geometry_output] | |
299 | } | |
b32b8144 FG |
300 | */ |
301 | template <typename Geometry> | |
302 | inline bool touches(Geometry const& geometry) | |
303 | { | |
304 | return resolve_variant::self_touches<Geometry>::apply(geometry); | |
305 | } | |
306 | ||
307 | ||
308 | /*! | |
309 | \brief \brief_check2{have at least one touching point (tangent - non overlapping)} | |
310 | \ingroup touches | |
311 | \tparam Geometry1 \tparam_geometry | |
312 | \tparam Geometry2 \tparam_geometry | |
313 | \param geometry1 \param_geometry | |
314 | \param geometry2 \param_geometry | |
315 | \return \return_check2{touch each other} | |
316 | ||
317 | \qbk{distinguish,two geometries} | |
318 | \qbk{[include reference/algorithms/touches.qbk]} | |
f67539c2 TL |
319 | \qbk{ |
320 | [heading Examples] | |
321 | [touches_two_geometries] | |
322 | [touches_two_geometries_output] | |
323 | } | |
b32b8144 FG |
324 | */ |
325 | template <typename Geometry1, typename Geometry2> | |
326 | inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2) | |
327 | { | |
328 | return resolve_variant::touches | |
329 | < | |
330 | Geometry1, Geometry2 | |
331 | >::apply(geometry1, geometry2, default_strategy()); | |
332 | } | |
333 | ||
334 | /*! | |
335 | \brief \brief_check2{have at least one touching point (tangent - non overlapping)} | |
336 | \ingroup touches | |
337 | \tparam Geometry1 \tparam_geometry | |
338 | \tparam Geometry2 \tparam_geometry | |
339 | \tparam Strategy \tparam_strategy{Touches} | |
340 | \param geometry1 \param_geometry | |
341 | \param geometry2 \param_geometry | |
342 | \param strategy \param_strategy{touches} | |
343 | \return \return_check2{touch each other} | |
344 | ||
345 | \qbk{distinguish,with strategy} | |
346 | \qbk{[include reference/algorithms/touches.qbk]} | |
347 | */ | |
348 | template <typename Geometry1, typename Geometry2, typename Strategy> | |
349 | inline bool touches(Geometry1 const& geometry1, | |
350 | Geometry2 const& geometry2, | |
351 | Strategy const& strategy) | |
352 | { | |
353 | return resolve_variant::touches | |
354 | < | |
355 | Geometry1, Geometry2 | |
356 | >::apply(geometry1, geometry2, strategy); | |
357 | } | |
358 | ||
359 | ||
360 | }} // namespace boost::geometry | |
361 | ||
362 | #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TOUCHES_INTERFACE_HPP |