1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2014, Oracle and/or its affiliates.
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
11 #ifndef BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
12 #define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
16 #include <boost/mpl/assert.hpp>
17 #include <boost/mpl/or.hpp>
18 #include <boost/range.hpp>
20 #include <boost/geometry/core/reverse_dispatch.hpp>
21 #include <boost/geometry/core/tag.hpp>
22 #include <boost/geometry/core/tag_cast.hpp>
23 #include <boost/geometry/core/tags.hpp>
25 #include <boost/geometry/iterators/segment_iterator.hpp>
27 #include <boost/geometry/algorithms/distance.hpp>
28 #include <boost/geometry/algorithms/intersects.hpp>
29 #include <boost/geometry/algorithms/not_implemented.hpp>
32 namespace boost { namespace geometry
38 namespace detail { namespace distance_brute_force
41 struct distance_from_bg
44 struct use_distance_from_bg
46 typedef typename boost::mpl::or_
48 boost::is_same<typename tag<G>::type, point_tag>,
49 typename boost::mpl::or_
51 boost::is_same<typename tag<G>::type, segment_tag>,
52 boost::is_same<typename tag<G>::type, box_tag>
57 template <typename Geometry1, typename Geometry2, typename Strategy>
59 typename distance_result<Geometry1, Geometry2, Strategy>::type
60 apply(Geometry1 const& geometry1,
61 Geometry2 const& geometry2,
62 Strategy const& strategy)
64 BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry1>::type));
65 BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry2>::type));
67 return geometry::distance(geometry1, geometry2, strategy);
72 template <typename Geometry1, typename Geometry2, typename Strategy>
74 typename distance_result<Geometry1, Geometry2, Strategy>::type
75 bg_distance(Geometry1 const& geometry1,
76 Geometry2 const& geometry2,
77 Strategy const& strategy)
79 return distance_from_bg::apply(geometry1, geometry2, strategy);
83 template <typename Policy>
86 template <typename Geometry, typename Iterator, typename Strategy>
87 static inline typename distance_result
90 typename std::iterator_traits<Iterator>::value_type,
93 apply(Geometry const& geometry, Iterator begin, Iterator end,
94 Strategy const& strategy)
96 typedef typename distance_result
99 typename std::iterator_traits<Iterator>::value_type,
101 >::type distance_type;
104 distance_type d_min(0);
105 for (Iterator it = begin; it != end; ++it, first = false)
107 distance_type d = Policy::apply(geometry, *it, strategy);
109 if ( first || d < d_min )
120 }} // namespace detail::distance_brute_force
131 typename Tag1 = typename tag_cast
133 typename tag<Geometry1>::type,
137 typename Tag2 = typename tag_cast
139 typename tag<Geometry2>::type,
143 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
145 struct distance_brute_force
146 : not_implemented<Geometry1, Geometry2>
158 struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
160 static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
161 apply(Geometry1 const& geometry1,
162 Geometry2 const& geometry2,
163 Strategy const& strategy)
165 return distance_brute_force
167 Geometry2, Geometry1, Strategy
168 >::apply(geometry2, geometry1, strategy);
179 struct distance_brute_force
181 Point1, Point2, Strategy,
182 point_tag, point_tag, false
183 > : detail::distance_brute_force::distance_from_bg
193 struct distance_brute_force
195 Point, Segment, Strategy,
196 point_tag, segment_tag, false
197 > : detail::distance_brute_force::distance_from_bg
207 struct distance_brute_force
209 Point, Box, Strategy,
210 point_tag, box_tag, false
211 > : detail::distance_brute_force::distance_from_bg
220 struct distance_brute_force
222 Box1, Box2, Strategy,
223 box_tag, box_tag, false
224 > : detail::distance_brute_force::distance_from_bg
234 struct distance_brute_force
236 Segment1, Segment2, Strategy,
237 segment_tag, segment_tag, false
238 > : detail::distance_brute_force::distance_from_bg
248 struct distance_brute_force
250 Point, Linear, Strategy,
251 point_tag, linear_tag, false
254 typedef typename distance_result
256 Point, Linear, Strategy
257 >::type distance_type;
259 static inline distance_type apply(Point const& point,
260 Linear const& linear,
261 Strategy const& strategy)
263 return detail::distance_brute_force::one_to_many
265 detail::distance_brute_force::distance_from_bg
267 geometry::segments_begin(linear),
268 geometry::segments_end(linear),
280 struct distance_brute_force
282 Point, MultiPoint, Strategy,
283 point_tag, multi_point_tag, false
286 typedef typename distance_result
288 Point, MultiPoint, Strategy
289 >::type distance_type;
291 static inline distance_type apply(Point const& p,
292 MultiPoint const& mp,
293 Strategy const& strategy)
295 return detail::distance_brute_force::one_to_many
297 detail::distance_brute_force::distance_from_bg
298 >::apply(p, boost::begin(mp), boost::end(mp), strategy);
304 typename MultiPoint1,
305 typename MultiPoint2,
308 struct distance_brute_force
310 MultiPoint1, MultiPoint2, Strategy,
311 multi_point_tag, multi_point_tag, false
314 typedef typename distance_result
316 MultiPoint1, MultiPoint2, Strategy
317 >::type distance_type;
319 static inline distance_type apply(MultiPoint1 const& mp1,
320 MultiPoint2 const& mp2,
321 Strategy const& strategy)
323 return detail::distance_brute_force::one_to_many
328 typename boost::range_value<MultiPoint2>::type,
331 >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
342 struct distance_brute_force
344 MultiPoint, Linear, Strategy,
345 multi_point_tag, linear_tag, false
348 typedef typename distance_result
350 MultiPoint, Linear, Strategy
351 >::type distance_type;
353 static inline distance_type apply(MultiPoint const& mp,
354 Linear const& linear,
355 Strategy const& strategy)
357 return detail::distance_brute_force::one_to_many
362 typename boost::range_value<MultiPoint>::type,
365 >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
376 struct distance_brute_force
378 Linear, MultiPoint, Strategy,
379 linear_tag, multi_point_tag, false
382 typedef typename distance_result
384 Linear, MultiPoint, Strategy
385 >::type distance_type;
387 static inline distance_type apply(Linear const& linear,
388 MultiPoint const& multipoint,
389 Strategy const& strategy)
391 return distance_brute_force
393 MultiPoint, Linear, Strategy,
394 multi_point_tag, linear_tag, false
395 >::apply(multipoint, linear, strategy);
406 struct distance_brute_force
408 MultiPoint, Segment, Strategy,
409 multi_point_tag, segment_tag, false
412 typedef typename distance_result
414 MultiPoint, Segment, Strategy
415 >::type distance_type;
417 static inline distance_type apply(MultiPoint const& mp,
418 Segment const& segment,
419 Strategy const& strategy)
421 return detail::distance_brute_force::one_to_many
423 detail::distance_brute_force::distance_from_bg
424 >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
434 struct distance_brute_force
436 MultiPoint, Box, Strategy,
437 multi_point_tag, box_tag, false
440 typedef typename distance_result
442 MultiPoint, Box, Strategy
443 >::type distance_type;
445 static inline distance_type apply(MultiPoint const& mp,
447 Strategy const& strategy)
449 return detail::distance_brute_force::one_to_many
454 typename boost::range_value<MultiPoint>::type,
457 >::apply(box, boost::begin(mp), boost::end(mp), strategy);
468 struct distance_brute_force
470 Linear, Segment, Strategy,
471 linear_tag, segment_tag, false
474 typedef typename distance_result
476 Linear, Segment, Strategy
477 >::type distance_type;
479 static inline distance_type apply(Linear const& linear,
480 Segment const& segment,
481 Strategy const& strategy)
483 return detail::distance_brute_force::one_to_many
485 detail::distance_brute_force::distance_from_bg
487 geometry::segments_begin(linear),
488 geometry::segments_end(linear),
500 struct distance_brute_force
502 Linear1, Linear2, Strategy,
503 linear_tag, linear_tag, false
506 typedef typename distance_result
508 Linear1, Linear2, Strategy
509 >::type distance_type;
511 static inline distance_type apply(Linear1 const& linear1,
512 Linear2 const& linear2,
513 Strategy const& strategy)
515 return detail::distance_brute_force::one_to_many
520 typename std::iterator_traits
522 segment_iterator<Linear2 const>
527 geometry::segments_begin(linear2),
528 geometry::segments_end(linear2),
533 } // namespace dispatch
539 template <typename Geometry1, typename Geometry2, typename Strategy>
540 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
541 distance_brute_force(Geometry1 const& geometry1,
542 Geometry2 const& geometry2,
543 Strategy const& strategy)
545 return dispatch::distance_brute_force
547 Geometry1, Geometry2, Strategy
548 >::apply(geometry1, geometry2, strategy);
551 } // namespace unit_test
554 }} // namespace boost::geometry
556 #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP