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
221 struct distance_brute_force
223 Segment1, Segment2, Strategy,
224 segment_tag, segment_tag, false
225 > : detail::distance_brute_force::distance_from_bg
235 struct distance_brute_force
237 Point, Linear, Strategy,
238 point_tag, linear_tag, false
241 typedef typename distance_result
243 Point, Linear, Strategy
244 >::type distance_type;
246 static inline distance_type apply(Point const& point,
247 Linear const& linear,
248 Strategy const& strategy)
250 return detail::distance_brute_force::one_to_many
252 detail::distance_brute_force::distance_from_bg
254 geometry::segments_begin(linear),
255 geometry::segments_end(linear),
267 struct distance_brute_force
269 Point, MultiPoint, Strategy,
270 point_tag, multi_point_tag, false
273 typedef typename distance_result
275 Point, MultiPoint, Strategy
276 >::type distance_type;
278 static inline distance_type apply(Point const& p,
279 MultiPoint const& mp,
280 Strategy const& strategy)
282 return detail::distance_brute_force::one_to_many
284 detail::distance_brute_force::distance_from_bg
285 >::apply(p, boost::begin(mp), boost::end(mp), strategy);
291 typename MultiPoint1,
292 typename MultiPoint2,
295 struct distance_brute_force
297 MultiPoint1, MultiPoint2, Strategy,
298 multi_point_tag, multi_point_tag, false
301 typedef typename distance_result
303 MultiPoint1, MultiPoint2, Strategy
304 >::type distance_type;
306 static inline distance_type apply(MultiPoint1 const& mp1,
307 MultiPoint2 const& mp2,
308 Strategy const& strategy)
310 return detail::distance_brute_force::one_to_many
315 typename boost::range_value<MultiPoint2>::type,
318 >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
329 struct distance_brute_force
331 MultiPoint, Linear, Strategy,
332 multi_point_tag, linear_tag, false
335 typedef typename distance_result
337 MultiPoint, Linear, Strategy
338 >::type distance_type;
340 static inline distance_type apply(MultiPoint const& mp,
341 Linear const& linear,
342 Strategy const& strategy)
344 return detail::distance_brute_force::one_to_many
349 typename boost::range_value<MultiPoint>::type,
352 >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
363 struct distance_brute_force
365 Linear, MultiPoint, Strategy,
366 linear_tag, multi_point_tag, false
369 typedef typename distance_result
371 Linear, MultiPoint, Strategy
372 >::type distance_type;
374 static inline distance_type apply(Linear const& linear,
375 MultiPoint const& multipoint,
376 Strategy const& strategy)
378 return distance_brute_force
380 MultiPoint, Linear, Strategy,
381 multi_point_tag, linear_tag, false
382 >::apply(multipoint, linear, strategy);
393 struct distance_brute_force
395 MultiPoint, Segment, Strategy,
396 multi_point_tag, segment_tag, false
399 typedef typename distance_result
401 MultiPoint, Segment, Strategy
402 >::type distance_type;
404 static inline distance_type apply(MultiPoint const& mp,
405 Segment const& segment,
406 Strategy const& strategy)
408 return detail::distance_brute_force::one_to_many
410 detail::distance_brute_force::distance_from_bg
411 >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
422 struct distance_brute_force
424 Linear, Segment, Strategy,
425 linear_tag, segment_tag, false
428 typedef typename distance_result
430 Linear, Segment, Strategy
431 >::type distance_type;
433 static inline distance_type apply(Linear const& linear,
434 Segment const& segment,
435 Strategy const& strategy)
437 return detail::distance_brute_force::one_to_many
439 detail::distance_brute_force::distance_from_bg
441 geometry::segments_begin(linear),
442 geometry::segments_end(linear),
454 struct distance_brute_force
456 Linear1, Linear2, Strategy,
457 linear_tag, linear_tag, false
460 typedef typename distance_result
462 Linear1, Linear2, Strategy
463 >::type distance_type;
465 static inline distance_type apply(Linear1 const& linear1,
466 Linear2 const& linear2,
467 Strategy const& strategy)
469 return detail::distance_brute_force::one_to_many
474 typename std::iterator_traits
476 segment_iterator<Linear2 const>
481 geometry::segments_begin(linear2),
482 geometry::segments_end(linear2),
487 } // namespace dispatch
493 template <typename Geometry1, typename Geometry2, typename Strategy>
494 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
495 distance_brute_force(Geometry1 const& geometry1,
496 Geometry2 const& geometry2,
497 Strategy const& strategy)
499 return dispatch::distance_brute_force
501 Geometry1, Geometry2, Strategy
502 >::apply(geometry1, geometry2, strategy);
505 } // namespace unit_test
508 }} // namespace boost::geometry
510 #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP