1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2014, Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 
7 // Licensed under the Boost Software License version 1.0.
8 // http://www.boost.org/users/license.html
9 
10 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
12 
13 #include <iterator>
14 #include <utility>
15 
16 #include <boost/geometry/core/assert.hpp>
17 #include <boost/geometry/core/point_type.hpp>
18 
19 #include <boost/geometry/iterators/has_one_element.hpp>
20 
21 #include <boost/geometry/strategies/distance.hpp>
22 
23 #include <boost/geometry/algorithms/dispatch/distance.hpp>
24 
25 #include <boost/geometry/algorithms/detail/closest_feature/range_to_range.hpp>
26 #include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
27 #include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
28 
29 
30 namespace boost { namespace geometry
31 {
32 
33 
34 #ifndef DOXYGEN_NO_DETAIL
35 namespace detail { namespace distance
36 {
37 
38 
39 template
40 <
41     typename PointOrSegmentIterator,
42     typename Geometry,
43     typename Strategy
44 >
45 class point_or_segment_range_to_geometry_rtree
46 {
47 private:
48     typedef typename std::iterator_traits
49         <
50             PointOrSegmentIterator
51         >::value_type point_or_segment_type;
52 
53     typedef iterator_selector<Geometry const> selector_type;
54 
55     typedef detail::closest_feature::range_to_range_rtree range_to_range;
56 
57 public:
58     typedef typename strategy::distance::services::return_type
59         <
60             Strategy,
61             typename point_type<point_or_segment_type>::type,
62             typename point_type<Geometry>::type
63         >::type return_type;
64 
apply(PointOrSegmentIterator first,PointOrSegmentIterator last,Geometry const & geometry,Strategy const & strategy)65     static inline return_type apply(PointOrSegmentIterator first,
66                                     PointOrSegmentIterator last,
67                                     Geometry const& geometry,
68                                     Strategy const& strategy)
69     {
70         namespace sds = strategy::distance::services;
71 
72         BOOST_GEOMETRY_ASSERT( first != last );
73 
74         if ( geometry::has_one_element(first, last) )
75         {
76             return dispatch::distance
77                 <
78                     point_or_segment_type, Geometry, Strategy
79                 >::apply(*first, geometry, strategy);
80         }
81 
82         typename sds::return_type
83             <
84                 typename sds::comparable_type<Strategy>::type,
85                 typename point_type<point_or_segment_type>::type,
86                 typename point_type<Geometry>::type
87             >::type cd_min;
88 
89         std::pair
90             <
91                 point_or_segment_type,
92                 typename selector_type::iterator_type
93             > closest_features
94             = range_to_range::apply(first,
95                                     last,
96                                     selector_type::begin(geometry),
97                                     selector_type::end(geometry),
98                                     sds::get_comparable
99                                         <
100                                             Strategy
101                                         >::apply(strategy),
102                                     cd_min);
103 
104         return
105             is_comparable<Strategy>::value
106             ?
107             cd_min
108             :
109             dispatch::distance
110                 <
111                     point_or_segment_type,
112                     typename std::iterator_traits
113                         <
114                             typename selector_type::iterator_type
115                         >::value_type,
116                     Strategy
117                 >::apply(closest_features.first,
118                          *closest_features.second,
119                          strategy);
120     }
121 };
122 
123 
124 }} // namespace detail::distance
125 #endif // DOXYGEN_NO_DETAIL
126 
127 
128 }} // namespace boost::geometry
129 
130 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_RANGE_TO_GEOMETRY_RTREE_HPP
131