Added rtree::count() method. Docs modified.

[SVN r81947]
This commit is contained in:
Adam Wulkiewicz
2012-12-14 19:15:34 +00:00
parent cce223726a
commit 627452da2a
6 changed files with 210 additions and 20 deletions

View File

@@ -75,8 +75,8 @@
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">rtree</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span>
<span class="identifier">last</span><span class="special">)</span></code>
<code class="computeroutput"><span class="identifier">rtree</span><span class="special">(</span><span class="identifier">Iterator</span><span class="special">,</span>
<span class="identifier">Iterator</span><span class="special">)</span></code>
</p>
</td>
<td>
@@ -191,8 +191,8 @@
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">insert</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span>
<span class="identifier">last</span><span class="special">)</span></code>
<code class="computeroutput"><span class="identifier">insert</span><span class="special">(</span><span class="identifier">Iterator</span><span class="special">,</span>
<span class="identifier">Iterator</span><span class="special">)</span></code>
</p>
</td>
<td>
@@ -204,7 +204,7 @@
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">insert</span><span class="special">(</span><span class="identifier">range</span><span class="special">)</span></code>
<code class="computeroutput"><span class="identifier">insert</span><span class="special">(</span><span class="identifier">Range</span><span class="special">)</span></code>
</p>
</td>
<td>
@@ -228,8 +228,8 @@
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">remove</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span>
<span class="identifier">last</span><span class="special">)</span></code>
<code class="computeroutput"><span class="identifier">remove</span><span class="special">(</span><span class="identifier">Iterator</span><span class="special">,</span>
<span class="identifier">Iterator</span><span class="special">)</span></code>
</p>
</td>
<td>
@@ -241,7 +241,7 @@
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">remove</span><span class="special">(</span><span class="identifier">range</span><span class="special">)</span></code>
<code class="computeroutput"><span class="identifier">remove</span><span class="special">(</span><span class="identifier">Range</span><span class="special">)</span></code>
</p>
</td>
<td>
@@ -287,6 +287,18 @@
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">count</span><span class="special">(</span><span class="identifier">ValueOrIndexable</span><span class="special">)</span></code>
</p>
</td>
<td>
<p>
<span class="emphasis"><em>nothrow</em></span>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">size</span><span class="special">()</span></code>

View File

@@ -56,7 +56,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: December 14, 2012 at 15:00:09 GMT</small></p></td>
<td align="left"><p><small>Last revised: December 14, 2012 at 19:10:44 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@@ -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/ ]]

View File

@@ -39,6 +39,7 @@
#include <boost/geometry/extensions/index/rtree/visitors/spatial_query.hpp>
#include <boost/geometry/extensions/index/rtree/visitors/nearest_query.hpp>
#include <boost/geometry/extensions/index/rtree/visitors/children_box.hpp>
#include <boost/geometry/extensions/index/rtree/visitors/count.hpp>
#include <boost/geometry/extensions/index/rtree/linear/linear.hpp>
#include <boost/geometry/extensions/index/rtree/quadratic/quadratic.hpp>
@@ -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 <typename ValueOrIndexable>
size_type count(ValueOrIndexable const& vori) const
{
if ( !m_root )
return 0;
detail::rtree::visitors::count<ValueOrIndexable, value_type, options_type, translator_type, box_type, allocators_type>
count_v(vori, m_translator);
detail::rtree::apply_visitor(count_v, *m_root);
return count_v.found_count;
}
/*!
Returns parameters.

View File

@@ -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 <boost/geometry/extensions/index/rtree/predicates.hpp>
#include <boost/geometry/extensions/index/rtree/node/node.hpp>
namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace visitors {
template <typename Indexable, typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct count
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
, index::nonassignable
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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<internal_node>::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<leaf>::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 <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
struct count<Value, Value, Options, Translator, Box, Allocators>
: public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
, index::nonassignable
{
typedef typename rtree::node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type node;
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::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<internal_node>::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<leaf>::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

View File

@@ -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 <typename Indexable, typename Parameters>
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 <typename Indexable, typename Parameters>
void test_rtree_count(Parameters const& parameters)
{
typedef std::pair<Indexable, int> Value;
typedef bgi::rtree<Value, Parameters> Tree;
typedef typename Tree::box_type B;
Tree t(parameters);
std::vector<Value> 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<VNoDCtor, Parameters>(parameters);
test_count_rtree_values<Point>(parameters);
test_rtree_count<Point>(parameters);
}
template<typename Point, typename Parameters>
@@ -1271,6 +1297,8 @@ void test_rtree_for_box(Parameters const& parameters = Parameters())
test_rtree_by_value<VNoDCtor, Parameters>(parameters);
test_count_rtree_values<Box>(parameters);
test_rtree_count<Box>(parameters);
}
#endif