diff --git a/doc/html/geometry_index/r_tree/exception_safety.html b/doc/html/geometry_index/r_tree/exception_safety.html index 04dd96621..08be8978b 100644 --- a/doc/html/geometry_index/r_tree/exception_safety.html +++ b/doc/html/geometry_index/r_tree/exception_safety.html @@ -75,8 +75,8 @@

- rtree(first, - last) + rtree(Iterator, + Iterator)

@@ -191,8 +191,8 @@

- insert(first, - last) + insert(Iterator, + Iterator)

@@ -204,7 +204,7 @@

- insert(range) + insert(Range)

@@ -228,8 +228,8 @@

- remove(first, - last) + remove(Iterator, + Iterator)

@@ -241,7 +241,7 @@

- remove(range) + remove(Range)

@@ -287,6 +287,18 @@ + +

+ count(ValueOrIndexable) +

+ + +

+ nothrow +

+ + +

size() diff --git a/doc/html/index.html b/doc/html/index.html index e369d528c..2084b6801 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -56,7 +56,7 @@ - +

Last revised: December 14, 2012 at 15:00:09 GMT

Last revised: December 14, 2012 at 19:10:44 GMT


diff --git a/doc/rtree/exception_safety.qbk b/doc/rtree/exception_safety.qbk index 2e6cad42f..37b91ced3 100644 --- a/doc/rtree/exception_safety.qbk +++ b/doc/rtree/exception_safety.qbk @@ -20,7 +20,7 @@ In order to be exception-safe the __rtree__ requires: [table [[Operation] [exception-safety]] [[`rtree()`] [ /nothrow/ ]] -[[`rtree(first, last)`] [ *strong* ]] +[[`rtree(Iterator, Iterator)`] [ *strong* ]] [[`~rtree()`] [ /nothrow/ ]] [[][]] [[`rtree(rtree const&)`] [ *strong* ]] @@ -32,15 +32,16 @@ In order to be exception-safe the __rtree__ requires: [[`swap(rtree &)`] [ /nothrow/ ]] [[][]] [[`insert(__value__)`] [ basic ]] -[[`insert(first, last)`] [ basic ]] -[[`insert(range)`] [ basic ]] +[[`insert(Iterator, Iterator)`][ basic ]] +[[`insert(Range)`] [ basic ]] [[`remove(__value__)`] [ basic ]] -[[`remove(first, last)`] [ basic ]] -[[`remove(range)`] [ basic ]] +[[`remove(Iterator, Iterator)`][ basic ]] +[[`remove(Range)`] [ basic ]] [[][]] [[`spatial_query(...)`] [ *strong* ]] [[`nearest_query(...)`] [ *strong* ]] [[][]] +[[`count(ValueOrIndexable)`] [ /nothrow/ ]] [[`size()`] [ /nothrow/ ]] [[`empty()`] [ /nothrow/ ]] [[`clear()`] [ /nothrow/ ]] diff --git a/include/boost/geometry/extensions/index/rtree/rtree.hpp b/include/boost/geometry/extensions/index/rtree/rtree.hpp index 90ac2b5dd..601273803 100644 --- a/include/boost/geometry/extensions/index/rtree/rtree.hpp +++ b/include/boost/geometry/extensions/index/rtree/rtree.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -644,6 +645,30 @@ public: return children_box_v.result; } + /*! + For indexable_type it returns the number of values which indexables equals the parameter. + For value_type it returns the number of values which equals the parameter. + + \note Exception-safety: nothrow. + + \param The value or indexable which will be counted. + + \return The number of values found. + */ + template + size_type count(ValueOrIndexable const& vori) const + { + if ( !m_root ) + return 0; + + detail::rtree::visitors::count + count_v(vori, m_translator); + + detail::rtree::apply_visitor(count_v, *m_root); + + return count_v.found_count; + } + /*! Returns parameters. diff --git a/include/boost/geometry/extensions/index/rtree/visitors/count.hpp b/include/boost/geometry/extensions/index/rtree/visitors/count.hpp new file mode 100644 index 000000000..2b8a324c6 --- /dev/null +++ b/include/boost/geometry/extensions/index/rtree/visitors/count.hpp @@ -0,0 +1,124 @@ +// Boost.Geometry Index +// +// R-tree count visitor implementation +// +// Copyright (c) 2011-2012 Adam Wulkiewicz, Lodz, Poland. +// +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_COUNT_HPP +#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_COUNT_HPP + +#include + +#include + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { namespace visitors { + +template +struct count + : public rtree::visitor::type + , index::nonassignable +{ + typedef typename rtree::node::type node; + typedef typename rtree::internal_node::type internal_node; + typedef typename rtree::leaf::type leaf; + + inline count(Indexable const& i, Translator const& t) + : indexable(i), tr(t), found_count(0) + {} + + inline void operator()(internal_node const& n) + { + typedef typename rtree::elements_type::type elements_type; + elements_type const& elements = rtree::elements(n); + + // traverse nodes meeting predicates + for (typename elements_type::const_iterator it = elements.begin(); + it != elements.end(); ++it) + { + if ( geometry::covered_by(indexable, it->first) ) + rtree::apply_visitor(*this, *it->second); + } + } + + inline void operator()(leaf const& n) + { + typedef typename rtree::elements_type::type elements_type; + elements_type const& elements = rtree::elements(n); + + // get all values meeting predicates + for (typename elements_type::const_iterator it = elements.begin(); + it != elements.end(); ++it) + { + // if value meets predicates + if ( geometry::equals(indexable, tr(*it)) ) + { + ++found_count; + } + } + } + + Indexable const& indexable; + Translator const& tr; + typename Allocators::size_type found_count; +}; + +template +struct count + : public rtree::visitor::type + , index::nonassignable +{ + typedef typename rtree::node::type node; + typedef typename rtree::internal_node::type internal_node; + typedef typename rtree::leaf::type leaf; + + inline count(Value const& v, Translator const& t) + : value(v), tr(t), found_count(0) + {} + + inline void operator()(internal_node const& n) + { + typedef typename rtree::elements_type::type elements_type; + elements_type const& elements = rtree::elements(n); + + // traverse nodes meeting predicates + for (typename elements_type::const_iterator it = elements.begin(); + it != elements.end(); ++it) + { + if ( geometry::covered_by(tr(value), it->first) ) + rtree::apply_visitor(*this, *it->second); + } + } + + inline void operator()(leaf const& n) + { + typedef typename rtree::elements_type::type elements_type; + elements_type const& elements = rtree::elements(n); + + // get all values meeting predicates + for (typename elements_type::const_iterator it = elements.begin(); + it != elements.end(); ++it) + { + // if value meets predicates + if ( tr.equals(value, *it) ) + { + ++found_count; + } + } + } + + Value const& value; + Translator const& tr; + typename Allocators::size_type found_count; +}; + +}}} // namespace detail::rtree::visitors + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_COUNT_HPP diff --git a/test/rtree/test_rtree.hpp b/test/rtree/test_rtree.hpp index 0281fd4b2..07c9bc37e 100644 --- a/test/rtree/test_rtree.hpp +++ b/test/rtree/test_rtree.hpp @@ -1192,7 +1192,7 @@ void test_rtree_by_value(Parameters const& parameters) test_copy_assignment_swap_move(empty_tree, qbox); } -// rtree inserting removing by use of counting_value +// rtree inserting and removing of counting_value template void test_count_rtree_values(Parameters const& parameters) @@ -1207,11 +1207,6 @@ void test_count_rtree_values(Parameters const& parameters) generate_rtree(t, input, qbox); - { - BOOST_FOREACH(Value const& v, input) - t.insert(v); - } - size_t rest_count = input.size(); BOOST_CHECK(t.size() + rest_count == Value::counter()); @@ -1235,6 +1230,35 @@ void test_count_rtree_values(Parameters const& parameters) } } +// rtree count + +template +void test_rtree_count(Parameters const& parameters) +{ + typedef std::pair Value; + typedef bgi::rtree Tree; + typedef typename Tree::box_type B; + + Tree t(parameters); + std::vector input; + B qbox; + + generate_rtree(t, input, qbox); + + BOOST_CHECK(t.count(input[0]) == 1); + BOOST_CHECK(t.count(input[0].first) == 1); + + t.insert(input[0]); + + BOOST_CHECK(t.count(input[0]) == 2); + BOOST_CHECK(t.count(input[0].first) == 2); + + t.insert(std::make_pair(input[0].first, -1)); + + BOOST_CHECK(t.count(input[0]) == 2); + BOOST_CHECK(t.count(input[0].first) == 3); +} + // run all tests for one Algorithm for some number of rtrees // defined by some number of Values constructed from given Point @@ -1254,6 +1278,8 @@ void test_rtree_for_point(Parameters const& parameters = Parameters()) test_rtree_by_value(parameters); test_count_rtree_values(parameters); + + test_rtree_count(parameters); } template @@ -1271,6 +1297,8 @@ void test_rtree_for_box(Parameters const& parameters = Parameters()) test_rtree_by_value(parameters); test_count_rtree_values(parameters); + + test_rtree_count(parameters); } #endif