• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
11 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
12 
13 #include <iterator>
14 
15 #include <boost/geometry/core/assert.hpp>
16 #include <boost/geometry/core/point_type.hpp>
17 #include <boost/geometry/strategies/distance.hpp>
18 #include <boost/geometry/util/math.hpp>
19 
20 #include <boost/geometry/algorithms/dispatch/distance.hpp>
21 
22 
23 namespace boost { namespace geometry
24 {
25 
26 #ifndef DOXYGEN_NO_DETAIL
27 namespace detail { namespace closest_feature
28 {
29 
30 
31 
32 // returns the range iterator the realizes the closest
33 // distance between the geometry and the element of the range
34 class geometry_to_range
35 {
36 private:
37     template
38     <
39         typename Geometry,
40         typename RangeIterator,
41         typename Strategy,
42         typename Distance
43     >
apply(Geometry const & geometry,RangeIterator first,RangeIterator last,Strategy const & strategy,RangeIterator & it_min,Distance & dist_min)44     static inline void apply(Geometry const& geometry,
45                              RangeIterator first,
46                              RangeIterator last,
47                              Strategy const& strategy,
48                              RangeIterator& it_min,
49                              Distance& dist_min)
50     {
51         BOOST_GEOMETRY_ASSERT( first != last );
52 
53         Distance const zero = Distance(0);
54 
55         // start with first distance
56         it_min = first;
57         dist_min = dispatch::distance
58             <
59                 Geometry,
60                 typename std::iterator_traits<RangeIterator>::value_type,
61                 Strategy
62             >::apply(geometry, *it_min, strategy);
63 
64         // check if other elements in the range are closer
65         for (RangeIterator it = ++first; it != last; ++it)
66         {
67             Distance dist = dispatch::distance
68                 <
69                     Geometry,
70                     typename std::iterator_traits<RangeIterator>::value_type,
71                     Strategy
72                 >::apply(geometry, *it, strategy);
73 
74             if (geometry::math::equals(dist, zero))
75             {
76                 dist_min = dist;
77                 it_min = it;
78                 return;
79             }
80             else if (dist < dist_min)
81             {
82                 dist_min = dist;
83                 it_min = it;
84             }
85         }
86     }
87 
88 public:
89     template
90     <
91         typename Geometry,
92         typename RangeIterator,
93         typename Strategy,
94         typename Distance
95     >
apply(Geometry const & geometry,RangeIterator first,RangeIterator last,Strategy const & strategy,Distance & dist_min)96     static inline RangeIterator apply(Geometry const& geometry,
97                                       RangeIterator first,
98                                       RangeIterator last,
99                                       Strategy const& strategy,
100                                       Distance& dist_min)
101     {
102         RangeIterator it_min;
103         apply(geometry, first, last, strategy, it_min, dist_min);
104 
105         return it_min;
106     }
107 
108 
109     template
110     <
111         typename Geometry,
112         typename RangeIterator,
113         typename Strategy
114     >
apply(Geometry const & geometry,RangeIterator first,RangeIterator last,Strategy const & strategy)115     static inline RangeIterator apply(Geometry const& geometry,
116                                       RangeIterator first,
117                                       RangeIterator last,
118                                       Strategy const& strategy)
119     {
120         typename strategy::distance::services::return_type
121             <
122                 Strategy,
123                 typename point_type<Geometry>::type,
124                 typename point_type
125                     <
126                         typename std::iterator_traits
127                             <
128                                 RangeIterator
129                             >::value_type
130                     >::type
131             >::type dist_min;
132 
133         return apply(geometry, first, last, strategy, dist_min);
134     }
135 };
136 
137 
138 
139 }} // namespace detail::closest_feature
140 #endif // DOXYGEN_NO_DETAIL
141 
142 }} // namespace boost::geometry
143 
144 
145 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
146