1 // Boost.Geometry Index 2 // 3 // R-tree count visitor implementation 4 // 5 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. 6 // 7 // Use, modification and distribution is subject to the Boost Software License, 8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP 12 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP 13 14 namespace boost { namespace geometry { namespace index { 15 16 namespace detail { namespace rtree { namespace visitors { 17 18 template <typename Indexable, typename Value> 19 struct count_helper 20 { 21 template <typename Translator> indexableboost::geometry::index::detail::rtree::visitors::count_helper22 static inline typename Translator::result_type indexable(Indexable const& i, Translator const&) 23 { 24 return i; 25 } 26 template <typename Translator> equalsboost::geometry::index::detail::rtree::visitors::count_helper27 static inline bool equals(Indexable const& i, Value const& v, Translator const& tr) 28 { 29 return geometry::equals(i, tr(v)); 30 } 31 }; 32 33 template <typename Value> 34 struct count_helper<Value, Value> 35 { 36 template <typename Translator> indexableboost::geometry::index::detail::rtree::visitors::count_helper37 static inline typename Translator::result_type indexable(Value const& v, Translator const& tr) 38 { 39 return tr(v); 40 } 41 template <typename Translator> equalsboost::geometry::index::detail::rtree::visitors::count_helper42 static inline bool equals(Value const& v1, Value const& v2, Translator const& tr) 43 { 44 return tr.equals(v1, v2); 45 } 46 }; 47 48 template <typename ValueOrIndexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators> 49 struct count 50 : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type 51 { 52 typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node; 53 typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node; 54 typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf; 55 56 typedef count_helper<ValueOrIndexable, Value> count_help; 57 countboost::geometry::index::detail::rtree::visitors::count58 inline count(ValueOrIndexable const& vori, Translator const& t) 59 : value_or_indexable(vori), tr(t), found_count(0) 60 {} 61 operator ()boost::geometry::index::detail::rtree::visitors::count62 inline void operator()(internal_node const& n) 63 { 64 typedef typename rtree::elements_type<internal_node>::type elements_type; 65 elements_type const& elements = rtree::elements(n); 66 67 // traverse nodes meeting predicates 68 for (typename elements_type::const_iterator it = elements.begin(); 69 it != elements.end(); ++it) 70 { 71 if ( geometry::covered_by( 72 return_ref_or_bounds( 73 count_help::indexable(value_or_indexable, tr)), 74 it->first) ) 75 { 76 rtree::apply_visitor(*this, *it->second); 77 } 78 } 79 } 80 operator ()boost::geometry::index::detail::rtree::visitors::count81 inline void operator()(leaf const& n) 82 { 83 typedef typename rtree::elements_type<leaf>::type elements_type; 84 elements_type const& elements = rtree::elements(n); 85 86 // get all values meeting predicates 87 for (typename elements_type::const_iterator it = elements.begin(); 88 it != elements.end(); ++it) 89 { 90 // if value meets predicates 91 if ( count_help::equals(value_or_indexable, *it, tr) ) 92 { 93 ++found_count; 94 } 95 } 96 } 97 98 ValueOrIndexable const& value_or_indexable; 99 Translator const& tr; 100 typename Allocators::size_type found_count; 101 }; 102 103 }}} // namespace detail::rtree::visitors 104 105 }}} // namespace boost::geometry::index 106 107 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_VISITORS_COUNT_HPP 108