]>
Commit | Line | Data |
---|---|---|
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. | |
8 | // Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates. | |
9 | ||
10 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
11 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
12 | ||
13 | // Use, modification and distribution is subject to the Boost Software License, | |
14 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
15 | // http://www.boost.org/LICENSE_1_0.txt) | |
16 | ||
17 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
18 | ||
19 | #ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP | |
20 | #define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP | |
21 | ||
22 | ||
23 | #include <cstddef> | |
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/not_implemented.hpp> | |
30 | #include <boost/geometry/algorithms/within.hpp> | |
31 | ||
32 | #include <boost/geometry/strategies/cartesian/point_in_box.hpp> | |
33 | #include <boost/geometry/strategies/cartesian/box_in_box.hpp> | |
34 | #include <boost/geometry/strategies/default_strategy.hpp> | |
35 | ||
36 | namespace boost { namespace geometry | |
37 | { | |
38 | ||
39 | #ifndef DOXYGEN_NO_DETAIL | |
40 | namespace detail { namespace covered_by { | |
41 | ||
42 | struct use_point_in_geometry | |
43 | { | |
44 | template <typename Geometry1, typename Geometry2, typename Strategy> | |
45 | static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) | |
46 | { | |
47 | return detail::within::point_in_geometry(geometry1, geometry2, strategy) >= 0; | |
48 | } | |
49 | }; | |
50 | ||
51 | struct use_relate | |
52 | { | |
53 | template <typename Geometry1, typename Geometry2, typename Strategy> | |
54 | static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/) | |
55 | { | |
56 | return Strategy::apply(geometry1, geometry2); | |
57 | } | |
58 | }; | |
59 | ||
60 | }} // namespace detail::covered_by | |
61 | #endif // DOXYGEN_NO_DETAIL | |
62 | ||
63 | #ifndef DOXYGEN_NO_DISPATCH | |
64 | namespace dispatch | |
65 | { | |
66 | ||
67 | template | |
68 | < | |
69 | typename Geometry1, | |
70 | typename Geometry2, | |
71 | typename Tag1 = typename tag<Geometry1>::type, | |
72 | typename Tag2 = typename tag<Geometry2>::type | |
73 | > | |
74 | struct covered_by | |
75 | : not_implemented<Tag1, Tag2> | |
76 | {}; | |
77 | ||
78 | ||
79 | template <typename Point, typename Box> | |
80 | struct covered_by<Point, Box, point_tag, box_tag> | |
81 | { | |
82 | template <typename Strategy> | |
83 | static inline bool apply(Point const& point, Box const& box, Strategy const& strategy) | |
84 | { | |
85 | ::boost::ignore_unused_variable_warning(strategy); | |
86 | return strategy.apply(point, box); | |
87 | } | |
88 | }; | |
89 | ||
90 | template <typename Box1, typename Box2> | |
91 | struct covered_by<Box1, Box2, box_tag, box_tag> | |
92 | { | |
93 | template <typename Strategy> | |
94 | static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy) | |
95 | { | |
96 | assert_dimension_equal<Box1, Box2>(); | |
97 | ::boost::ignore_unused_variable_warning(strategy); | |
98 | return strategy.apply(box1, box2); | |
99 | } | |
100 | }; | |
101 | ||
102 | ||
103 | // P/P | |
104 | ||
105 | template <typename Point1, typename Point2> | |
106 | struct covered_by<Point1, Point2, point_tag, point_tag> | |
107 | : public detail::covered_by::use_point_in_geometry | |
108 | {}; | |
109 | ||
110 | template <typename Point, typename MultiPoint> | |
111 | struct covered_by<Point, MultiPoint, point_tag, multi_point_tag> | |
112 | : public detail::covered_by::use_point_in_geometry | |
113 | {}; | |
114 | ||
115 | // P/L | |
116 | ||
117 | template <typename Point, typename Segment> | |
118 | struct covered_by<Point, Segment, point_tag, segment_tag> | |
119 | : public detail::covered_by::use_point_in_geometry | |
120 | {}; | |
121 | ||
122 | template <typename Point, typename Linestring> | |
123 | struct covered_by<Point, Linestring, point_tag, linestring_tag> | |
124 | : public detail::covered_by::use_point_in_geometry | |
125 | {}; | |
126 | ||
127 | template <typename Point, typename MultiLinestring> | |
128 | struct covered_by<Point, MultiLinestring, point_tag, multi_linestring_tag> | |
129 | : public detail::covered_by::use_point_in_geometry | |
130 | {}; | |
131 | ||
132 | // P/A | |
133 | ||
134 | template <typename Point, typename Ring> | |
135 | struct covered_by<Point, Ring, point_tag, ring_tag> | |
136 | : public detail::covered_by::use_point_in_geometry | |
137 | {}; | |
138 | ||
139 | template <typename Point, typename Polygon> | |
140 | struct covered_by<Point, Polygon, point_tag, polygon_tag> | |
141 | : public detail::covered_by::use_point_in_geometry | |
142 | {}; | |
143 | ||
144 | template <typename Point, typename MultiPolygon> | |
145 | struct covered_by<Point, MultiPolygon, point_tag, multi_polygon_tag> | |
146 | : public detail::covered_by::use_point_in_geometry | |
147 | {}; | |
148 | ||
149 | // L/L | |
150 | ||
151 | template <typename Linestring1, typename Linestring2> | |
152 | struct covered_by<Linestring1, Linestring2, linestring_tag, linestring_tag> | |
153 | : public detail::covered_by::use_relate | |
154 | {}; | |
155 | ||
156 | template <typename Linestring, typename MultiLinestring> | |
157 | struct covered_by<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag> | |
158 | : public detail::covered_by::use_relate | |
159 | {}; | |
160 | ||
161 | template <typename MultiLinestring, typename Linestring> | |
162 | struct covered_by<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag> | |
163 | : public detail::covered_by::use_relate | |
164 | {}; | |
165 | ||
166 | template <typename MultiLinestring1, typename MultiLinestring2> | |
167 | struct covered_by<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag> | |
168 | : public detail::covered_by::use_relate | |
169 | {}; | |
170 | ||
171 | // L/A | |
172 | ||
173 | template <typename Linestring, typename Ring> | |
174 | struct covered_by<Linestring, Ring, linestring_tag, ring_tag> | |
175 | : public detail::covered_by::use_relate | |
176 | {}; | |
177 | ||
178 | template <typename MultiLinestring, typename Ring> | |
179 | struct covered_by<MultiLinestring, Ring, multi_linestring_tag, ring_tag> | |
180 | : public detail::covered_by::use_relate | |
181 | {}; | |
182 | ||
183 | template <typename Linestring, typename Polygon> | |
184 | struct covered_by<Linestring, Polygon, linestring_tag, polygon_tag> | |
185 | : public detail::covered_by::use_relate | |
186 | {}; | |
187 | ||
188 | template <typename MultiLinestring, typename Polygon> | |
189 | struct covered_by<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag> | |
190 | : public detail::covered_by::use_relate | |
191 | {}; | |
192 | ||
193 | template <typename Linestring, typename MultiPolygon> | |
194 | struct covered_by<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag> | |
195 | : public detail::covered_by::use_relate | |
196 | {}; | |
197 | ||
198 | template <typename MultiLinestring, typename MultiPolygon> | |
199 | struct covered_by<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag> | |
200 | : public detail::covered_by::use_relate | |
201 | {}; | |
202 | ||
203 | // A/A | |
204 | ||
205 | template <typename Ring1, typename Ring2> | |
206 | struct covered_by<Ring1, Ring2, ring_tag, ring_tag> | |
207 | : public detail::covered_by::use_relate | |
208 | {}; | |
209 | ||
210 | template <typename Ring, typename Polygon> | |
211 | struct covered_by<Ring, Polygon, ring_tag, polygon_tag> | |
212 | : public detail::covered_by::use_relate | |
213 | {}; | |
214 | ||
215 | template <typename Polygon, typename Ring> | |
216 | struct covered_by<Polygon, Ring, polygon_tag, ring_tag> | |
217 | : public detail::covered_by::use_relate | |
218 | {}; | |
219 | ||
220 | template <typename Polygon1, typename Polygon2> | |
221 | struct covered_by<Polygon1, Polygon2, polygon_tag, polygon_tag> | |
222 | : public detail::covered_by::use_relate | |
223 | {}; | |
224 | ||
225 | template <typename Ring, typename MultiPolygon> | |
226 | struct covered_by<Ring, MultiPolygon, ring_tag, multi_polygon_tag> | |
227 | : public detail::covered_by::use_relate | |
228 | {}; | |
229 | ||
230 | template <typename MultiPolygon, typename Ring> | |
231 | struct covered_by<MultiPolygon, Ring, multi_polygon_tag, ring_tag> | |
232 | : public detail::covered_by::use_relate | |
233 | {}; | |
234 | ||
235 | template <typename Polygon, typename MultiPolygon> | |
236 | struct covered_by<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag> | |
237 | : public detail::covered_by::use_relate | |
238 | {}; | |
239 | ||
240 | template <typename MultiPolygon, typename Polygon> | |
241 | struct covered_by<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag> | |
242 | : public detail::covered_by::use_relate | |
243 | {}; | |
244 | ||
245 | template <typename MultiPolygon1, typename MultiPolygon2> | |
246 | struct covered_by<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag> | |
247 | : public detail::covered_by::use_relate | |
248 | {}; | |
249 | ||
250 | } // namespace dispatch | |
251 | #endif // DOXYGEN_NO_DISPATCH | |
252 | ||
253 | ||
254 | namespace resolve_strategy { | |
255 | ||
256 | struct covered_by | |
257 | { | |
258 | template <typename Geometry1, typename Geometry2, typename Strategy> | |
259 | static inline bool apply(Geometry1 const& geometry1, | |
260 | Geometry2 const& geometry2, | |
261 | Strategy const& strategy) | |
262 | { | |
263 | concepts::within::check | |
264 | < | |
265 | typename tag<Geometry1>::type, | |
266 | typename tag<Geometry2>::type, | |
267 | typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type, | |
268 | Strategy | |
269 | >(); | |
270 | concepts::check<Geometry1 const>(); | |
271 | concepts::check<Geometry2 const>(); | |
272 | assert_dimension_equal<Geometry1, Geometry2>(); | |
273 | ||
274 | return dispatch::covered_by<Geometry1, Geometry2>::apply(geometry1, | |
275 | geometry2, | |
276 | strategy); | |
277 | } | |
278 | ||
279 | template <typename Geometry1, typename Geometry2> | |
280 | static inline bool apply(Geometry1 const& geometry1, | |
281 | Geometry2 const& geometry2, | |
282 | default_strategy) | |
283 | { | |
284 | typedef typename point_type<Geometry1>::type point_type1; | |
285 | typedef typename point_type<Geometry2>::type point_type2; | |
286 | ||
287 | typedef typename strategy::covered_by::services::default_strategy | |
288 | < | |
289 | typename tag<Geometry1>::type, | |
290 | typename tag<Geometry2>::type, | |
291 | typename tag<Geometry1>::type, | |
292 | typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type, | |
293 | typename tag_cast | |
294 | < | |
295 | typename cs_tag<point_type1>::type, spherical_tag | |
296 | >::type, | |
297 | typename tag_cast | |
298 | < | |
299 | typename cs_tag<point_type2>::type, spherical_tag | |
300 | >::type, | |
301 | Geometry1, | |
302 | Geometry2 | |
303 | >::type strategy_type; | |
304 | ||
305 | return covered_by::apply(geometry1, geometry2, strategy_type()); | |
306 | } | |
307 | }; | |
308 | ||
309 | } // namespace resolve_strategy | |
310 | ||
311 | ||
312 | namespace resolve_variant { | |
313 | ||
314 | template <typename Geometry1, typename Geometry2> | |
315 | struct covered_by | |
316 | { | |
317 | template <typename Strategy> | |
318 | static inline bool apply(Geometry1 const& geometry1, | |
319 | Geometry2 const& geometry2, | |
320 | Strategy const& strategy) | |
321 | { | |
322 | return resolve_strategy::covered_by | |
323 | ::apply(geometry1, geometry2, strategy); | |
324 | } | |
325 | }; | |
326 | ||
327 | template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2> | |
328 | struct covered_by<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2> | |
329 | { | |
330 | template <typename Strategy> | |
331 | struct visitor: boost::static_visitor<bool> | |
332 | { | |
333 | Geometry2 const& m_geometry2; | |
334 | Strategy const& m_strategy; | |
335 | ||
336 | visitor(Geometry2 const& geometry2, Strategy const& strategy) | |
337 | : m_geometry2(geometry2), m_strategy(strategy) {} | |
338 | ||
339 | template <typename Geometry1> | |
340 | bool operator()(Geometry1 const& geometry1) const | |
341 | { | |
342 | return covered_by<Geometry1, Geometry2> | |
343 | ::apply(geometry1, m_geometry2, m_strategy); | |
344 | } | |
345 | }; | |
346 | ||
347 | template <typename Strategy> | |
348 | static inline bool | |
349 | apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1, | |
350 | Geometry2 const& geometry2, | |
351 | Strategy const& strategy) | |
352 | { | |
353 | return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1); | |
354 | } | |
355 | }; | |
356 | ||
357 | template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
358 | struct covered_by<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
359 | { | |
360 | template <typename Strategy> | |
361 | struct visitor: boost::static_visitor<bool> | |
362 | { | |
363 | Geometry1 const& m_geometry1; | |
364 | Strategy const& m_strategy; | |
365 | ||
366 | visitor(Geometry1 const& geometry1, Strategy const& strategy) | |
367 | : m_geometry1(geometry1), m_strategy(strategy) {} | |
368 | ||
369 | template <typename Geometry2> | |
370 | bool operator()(Geometry2 const& geometry2) const | |
371 | { | |
372 | return covered_by<Geometry1, Geometry2> | |
373 | ::apply(m_geometry1, geometry2, m_strategy); | |
374 | } | |
375 | }; | |
376 | ||
377 | template <typename Strategy> | |
378 | static inline bool | |
379 | apply(Geometry1 const& geometry1, | |
380 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2, | |
381 | Strategy const& strategy) | |
382 | { | |
383 | return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2); | |
384 | } | |
385 | }; | |
386 | ||
387 | template < | |
388 | BOOST_VARIANT_ENUM_PARAMS(typename T1), | |
389 | BOOST_VARIANT_ENUM_PARAMS(typename T2) | |
390 | > | |
391 | struct covered_by< | |
392 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, | |
393 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> | |
394 | > | |
395 | { | |
396 | template <typename Strategy> | |
397 | struct visitor: boost::static_visitor<bool> | |
398 | { | |
399 | Strategy const& m_strategy; | |
400 | ||
401 | visitor(Strategy const& strategy): m_strategy(strategy) {} | |
402 | ||
403 | template <typename Geometry1, typename Geometry2> | |
404 | bool operator()(Geometry1 const& geometry1, | |
405 | Geometry2 const& geometry2) const | |
406 | { | |
407 | return covered_by<Geometry1, Geometry2> | |
408 | ::apply(geometry1, geometry2, m_strategy); | |
409 | } | |
410 | }; | |
411 | ||
412 | template <typename Strategy> | |
413 | static inline bool | |
414 | apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1, | |
415 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2, | |
416 | Strategy const& strategy) | |
417 | { | |
418 | return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2); | |
419 | } | |
420 | }; | |
421 | ||
422 | } // namespace resolve_variant | |
423 | ||
424 | ||
425 | /*! | |
426 | \brief \brief_check12{is inside or on border} | |
427 | \ingroup covered_by | |
428 | \details \details_check12{covered_by, is inside or on border}. | |
429 | \tparam Geometry1 \tparam_geometry | |
430 | \tparam Geometry2 \tparam_geometry | |
431 | \param geometry1 \param_geometry which might be inside or on the border of the second geometry | |
432 | \param geometry2 \param_geometry which might cover the first geometry | |
433 | \return true if geometry1 is inside of or on the border of geometry2, | |
434 | else false | |
435 | \note The default strategy is used for covered_by detection | |
436 | ||
437 | \qbk{[include reference/algorithms/covered_by.qbk]} | |
438 | ||
439 | */ | |
440 | template<typename Geometry1, typename Geometry2> | |
441 | inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2) | |
442 | { | |
443 | return resolve_variant::covered_by<Geometry1, Geometry2> | |
444 | ::apply(geometry1, geometry2, default_strategy()); | |
445 | } | |
446 | ||
447 | /*! | |
448 | \brief \brief_check12{is inside or on border} \brief_strategy | |
449 | \ingroup covered_by | |
450 | \details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons | |
451 | \tparam Geometry1 \tparam_geometry | |
452 | \tparam Geometry2 \tparam_geometry | |
453 | \param geometry1 \param_geometry which might be inside or on the border of the second geometry | |
454 | \param geometry2 \param_geometry which might cover the first geometry | |
455 | \param strategy strategy to be used | |
456 | \return true if geometry1 is inside of or on the border of geometry2, | |
457 | else false | |
458 | ||
459 | \qbk{distinguish,with strategy} | |
460 | \qbk{[include reference/algorithms/covered_by.qbk]} | |
461 | ||
462 | */ | |
463 | template<typename Geometry1, typename Geometry2, typename Strategy> | |
464 | inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2, | |
465 | Strategy const& strategy) | |
466 | { | |
467 | return resolve_variant::covered_by<Geometry1, Geometry2> | |
468 | ::apply(geometry1, geometry2, strategy); | |
469 | } | |
470 | ||
471 | }} // namespace boost::geometry | |
472 | ||
473 | #endif // BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP |