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