File indexing completed on 2025-01-18 09:35:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP
0012 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_RANGE_TO_RANGE_HPP
0013
0014 #include <cstddef>
0015
0016 #include <iterator>
0017 #include <utility>
0018
0019 #include <boost/geometry/core/assert.hpp>
0020 #include <boost/geometry/core/point_type.hpp>
0021 #include <boost/geometry/strategies/distance.hpp>
0022 #include <boost/geometry/algorithms/dispatch/distance.hpp>
0023 #include <boost/geometry/index/rtree.hpp>
0024
0025
0026 namespace boost { namespace geometry
0027 {
0028
0029 #ifndef DOXYGEN_NO_DETAIL
0030 namespace detail { namespace closest_feature
0031 {
0032
0033
0034
0035
0036
0037 class range_to_range_rtree
0038 {
0039 private:
0040 template
0041 <
0042 typename RTreeRangeIterator,
0043 typename QueryRangeIterator,
0044 typename Strategies,
0045 typename RTreeValueType,
0046 typename Distance
0047 >
0048 static inline void apply(RTreeRangeIterator rtree_first,
0049 RTreeRangeIterator rtree_last,
0050 QueryRangeIterator queries_first,
0051 QueryRangeIterator queries_last,
0052 Strategies const& strategies,
0053 RTreeValueType& rtree_min,
0054 QueryRangeIterator& qit_min,
0055 Distance& dist_min)
0056 {
0057 typedef index::parameters
0058 <
0059 index::linear<8>, Strategies
0060 > index_parameters_type;
0061 typedef index::rtree<RTreeValueType, index_parameters_type> rtree_type;
0062
0063 BOOST_GEOMETRY_ASSERT( rtree_first != rtree_last );
0064 BOOST_GEOMETRY_ASSERT( queries_first != queries_last );
0065
0066 Distance const zero = Distance(0);
0067 dist_min = zero;
0068
0069
0070 rtree_type rt(rtree_first, rtree_last,
0071 index_parameters_type(index::linear<8>(), strategies));
0072
0073 RTreeValueType t_v;
0074 bool first = true;
0075
0076 for (QueryRangeIterator qit = queries_first;
0077 qit != queries_last; ++qit, first = false)
0078 {
0079 std::size_t n = rt.query(index::nearest(*qit, 1), &t_v);
0080
0081 BOOST_GEOMETRY_ASSERT( n > 0 );
0082
0083
0084
0085
0086
0087
0088 boost::ignore_unused(n);
0089
0090 Distance dist = dispatch::distance
0091 <
0092 RTreeValueType,
0093 typename std::iterator_traits
0094 <
0095 QueryRangeIterator
0096 >::value_type,
0097 Strategies
0098 >::apply(t_v, *qit, strategies);
0099
0100 if (first || dist < dist_min)
0101 {
0102 dist_min = dist;
0103 rtree_min = t_v;
0104 qit_min = qit;
0105 if ( math::equals(dist_min, zero) )
0106 {
0107 return;
0108 }
0109 }
0110 }
0111 }
0112
0113 public:
0114 template <typename RTreeRangeIterator, typename QueryRangeIterator>
0115 struct return_type
0116 {
0117 typedef std::pair
0118 <
0119 typename std::iterator_traits<RTreeRangeIterator>::value_type,
0120 QueryRangeIterator
0121 > type;
0122 };
0123
0124
0125 template
0126 <
0127 typename RTreeRangeIterator,
0128 typename QueryRangeIterator,
0129 typename Strategy,
0130 typename Distance
0131 >
0132 static inline typename return_type
0133 <
0134 RTreeRangeIterator, QueryRangeIterator
0135 >::type apply(RTreeRangeIterator rtree_first,
0136 RTreeRangeIterator rtree_last,
0137 QueryRangeIterator queries_first,
0138 QueryRangeIterator queries_last,
0139 Strategy const& strategy,
0140 Distance& dist_min)
0141 {
0142 typedef typename std::iterator_traits
0143 <
0144 RTreeRangeIterator
0145 >::value_type rtree_value_type;
0146
0147 rtree_value_type rtree_min;
0148 QueryRangeIterator qit_min;
0149
0150 apply(rtree_first, rtree_last, queries_first, queries_last,
0151 strategy, rtree_min, qit_min, dist_min);
0152
0153 return std::make_pair(rtree_min, qit_min);
0154 }
0155
0156
0157 template
0158 <
0159 typename RTreeRangeIterator,
0160 typename QueryRangeIterator,
0161 typename Strategy
0162 >
0163 static inline typename return_type
0164 <
0165 RTreeRangeIterator, QueryRangeIterator
0166 >::type apply(RTreeRangeIterator rtree_first,
0167 RTreeRangeIterator rtree_last,
0168 QueryRangeIterator queries_first,
0169 QueryRangeIterator queries_last,
0170 Strategy const& strategy)
0171 {
0172 typedef typename std::iterator_traits
0173 <
0174 RTreeRangeIterator
0175 >::value_type rtree_value_type;
0176
0177 typename strategy::distance::services::return_type
0178 <
0179 Strategy,
0180 typename point_type<rtree_value_type>::type,
0181 typename point_type
0182 <
0183 typename std::iterator_traits
0184 <
0185 QueryRangeIterator
0186 >::value_type
0187 >::type
0188 >::type dist_min;
0189
0190 return apply(rtree_first, rtree_last, queries_first, queries_last,
0191 strategy, dist_min);
0192 }
0193 };
0194
0195
0196 }}
0197 #endif
0198
0199 }}
0200
0201
0202 #endif