Inserter included in the rtree.hpp

Added docs regarding inserter and creation of the rtree from the query results.
Added info about comparison of tuples in default translator.
Merged from index_dev.

[SVN r81582]
This commit is contained in:
Adam Wulkiewicz
2012-11-26 22:20:38 +00:00
parent 6f5b384b93
commit 640ae6ced6
9 changed files with 184 additions and 30 deletions

View File

@@ -46,6 +46,8 @@
and removing of Values</a></span></dt>
<dt><span class="section"><a href="r_tree/creation_and_modification.html#geometry_index.r_tree.creation_and_modification.additional_interface">Additional
interface</a></span></dt>
<dt><span class="section"><a href="r_tree/creation_and_modification.html#geometry_index.r_tree.creation_and_modification.insert_iterator">Insert
iterator</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="r_tree/spatial_queries.html">Spatial queries</a></span></dt>
<dd><dl>
@@ -57,6 +59,8 @@
predicates</a></span></dt>
<dt><span class="section"><a href="r_tree/spatial_queries.html#geometry_index.r_tree.spatial_queries.value_predicate">Value
predicate</a></span></dt>
<dt><span class="section"><a href="r_tree/spatial_queries.html#geometry_index.r_tree.spatial_queries.inserting_query_results_into_the_other_r_tree">Inserting
query results into the other R-tree</a></span></dt>
</dl></dd>
<dt><span class="section"><a href="r_tree/nearest_neighbours_queries.html">Nearest
neighbours queries</a></span></dt>

View File

@@ -42,6 +42,8 @@
and removing of Values</a></span></dt>
<dt><span class="section"><a href="creation_and_modification.html#geometry_index.r_tree.creation_and_modification.additional_interface">Additional
interface</a></span></dt>
<dt><span class="section"><a href="creation_and_modification.html#geometry_index.r_tree.creation_and_modification.insert_iterator">Insert
iterator</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
@@ -130,10 +132,27 @@
to the <code class="computeroutput">Indexable</code> than a copy.
</p>
<p>
If comparison of two <code class="computeroutput">Value</code>s is required, the default translator
compares both components of the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;...&gt;</span></code>. If the second one is a <code class="computeroutput"><span class="identifier">Geometry</span></code>, <code class="computeroutput"><span class="identifier">geometry</span><span class="special">::</span><span class="identifier">equals</span><span class="special">()</span></code> function is used. For other types it
uses <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code>.
If comparison of two <code class="computeroutput">Value</code>s is required, the default translator:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
for <code class="computeroutput"><a href="http://www.boost.org/libs/geometry/doc/html/geometry/reference/concepts/concept_point.html" target="_top">Point</a></code>
and <code class="computeroutput"><a href="http://www.boost.org/libs/geometry/doc/html/geometry/reference/concepts/concept_box.html" target="_top">Box</a></code>
- compares <code class="computeroutput">Value</code>s with geometry::equals().
</li>
<li class="listitem">
for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;...&gt;</span></code>
- compares both components of the <code class="computeroutput">Value</code>. The first one
is compared with <code class="computeroutput"><span class="identifier">geometry</span><span class="special">::</span><span class="identifier">equals</span><span class="special">()</span></code>. If the second one is a <code class="computeroutput"><span class="identifier">Geometry</span></code>, <code class="computeroutput"><span class="identifier">geometry</span><span class="special">::</span><span class="identifier">equals</span><span class="special">()</span></code> function is used. For other types
it uses <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code>.
</li>
<li class="listitem">
for <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;...&gt;</span></code>
- compares all components of the <code class="computeroutput">Value</code>. If the component
is a <code class="computeroutput"><span class="identifier">Geometry</span></code>, <code class="computeroutput"><span class="identifier">geometry</span><span class="special">::</span><span class="identifier">equals</span><span class="special">()</span></code>
function is used. For other types it uses <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code>.
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
@@ -269,36 +288,64 @@
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>Value<span class="special">&gt;</span> <span class="identifier">values</span><span class="special">;</span>
<span class="comment">/* vector filling code, here */</span>
<span class="comment">// create a RTree with default constructor and insert values with RTree::insert(Value const&amp;)</span>
<span class="comment">// create R-tree with default constructor and insert values with insert(Value const&amp;)</span>
<span class="identifier">RTree</span> <span class="identifier">rt1</span><span class="special">;</span>
<span class="identifier">BOOST_FOREACH</span><span class="special">(</span>Value <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">values</span><span class="special">)</span>
<span class="identifier">rt1</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="comment">// create a RTree with default constructor and insert values with RTree::insert(Iter, Iter)</span>
<span class="comment">// create R-tree with default constructor and insert values with insert(Iter, Iter)</span>
<span class="identifier">RTree</span> <span class="identifier">rt2</span><span class="special">;</span>
<span class="identifier">rt2</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="comment">// create a RTree with default constructor and insert values with RTree::insert(Range)</span>
<span class="comment">// create R-tree with default constructor and insert values with insert(Range)</span>
<span class="identifier">RTree</span> <span class="identifier">rt3</span><span class="special">;</span>
<span class="identifier">rt3</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">values</span><span class="special">);</span>
<span class="comment">// create a RTree with constructor taking Iterators</span>
<span class="comment">// create R-tree with constructor taking Iterators</span>
<span class="identifier">RTree</span> <span class="identifier">rt4</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="comment">// create a RTree with constructor taking Range</span>
<span class="comment">// create R-tree with constructor taking Range</span>
<span class="identifier">RTree</span> <span class="identifier">rt5</span><span class="special">(</span><span class="identifier">values</span><span class="special">);</span>
<span class="comment">// remove values with RTree::remove(Value const&amp;)</span>
<span class="comment">// remove values with remove(Value const&amp;)</span>
<span class="identifier">BOOST_FOREACH</span><span class="special">(</span>Value <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">values</span><span class="special">)</span>
<span class="identifier">rt1</span><span class="special">.</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="comment">// remove values with RTree::remove(Iter, Iter)</span>
<span class="comment">// remove values with remove(Iter, Iter)</span>
<span class="identifier">rt2</span><span class="special">.</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="comment">// remove values with RTree::remove(Range)</span>
<span class="comment">// remove values with remove(Range)</span>
<span class="identifier">rt3</span><span class="special">.</span><span class="identifier">remove</span><span class="special">(</span><span class="identifier">values</span><span class="special">);</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="geometry_index.r_tree.creation_and_modification.insert_iterator"></a><a class="link" href="creation_and_modification.html#geometry_index.r_tree.creation_and_modification.insert_iterator" title="Insert iterator">Insert
iterator</a>
</h4></div></div></div>
<p>
There are functions like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">()</span></code>, or R-tree's queries that copy values
to an output iterator. In order to insert values to a container in this
kind of function insert iterators may be used. Geometry.Index provide its
own <code class="computeroutput"><span class="identifier">bgi</span><span class="special">::</span><span class="identifier">insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;</span></code>
which is generated by <code class="computeroutput"><span class="identifier">bgi</span><span class="special">::</span><span class="identifier">inserter</span><span class="special">()</span></code> function.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bgi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">geometry</span><span class="special">::</span><span class="identifier">index</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">Box</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span> Value<span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">rtree</span><span class="special">&lt;</span> Value<span class="special">,</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">linear</span><span class="special">&lt;</span><span class="number">32</span><span class="special">,</span> <span class="number">8</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">RTree</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>Value<span class="special">&gt;</span> <span class="identifier">values</span><span class="special">;</span>
<span class="comment">/* vector filling code, here */</span>
<span class="comment">// create R-tree and insert values from the vector</span>
<span class="identifier">RTree</span> <span class="identifier">rt1</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span><span class="identifier">values</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">values</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">inserter</span><span class="special">(</span><span class="identifier">rt1</span><span class="special">));</span>
<span class="comment">// create R-tree and insert values returned by a query</span>
<span class="identifier">RTree</span> <span class="identifier">rt2</span><span class="special">;</span>
<span class="identifier">rt1</span><span class="special">.</span><span class="identifier">spatial_query</span><span class="special">(</span><span class="identifier">Box</span><span class="special">(/*...*/),</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">inserter</span><span class="special">(</span><span class="identifier">rt2</span><span class="special">));</span>
</pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>

View File

@@ -35,6 +35,8 @@
predicates</a></span></dt>
<dt><span class="section"><a href="spatial_queries.html#geometry_index.r_tree.spatial_queries.value_predicate">Value
predicate</a></span></dt>
<dt><span class="section"><a href="spatial_queries.html#geometry_index.r_tree.spatial_queries.inserting_query_results_into_the_other_r_tree">Inserting
query results into the other R-tree</a></span></dt>
</dl></div>
<p>
Spatial queries returns <code class="computeroutput"><span class="identifier">Value</span></code>s
@@ -211,6 +213,43 @@
<span class="identifier">std</span><span class="special">::</span><span class="identifier">back_inserter</span><span class="special">(</span><span class="identifier">result</span><span class="special">));</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="geometry_index.r_tree.spatial_queries.inserting_query_results_into_the_other_r_tree"></a><a class="link" href="spatial_queries.html#geometry_index.r_tree.spatial_queries.inserting_query_results_into_the_other_r_tree" title="Inserting query results into the other R-tree">Inserting
query results into the other R-tree</a>
</h4></div></div></div>
<p>
There are several ways of inserting Values returned by a query to the other
R-tree container. The most basic way is creating a temporary container
for Values and insert them later.
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bgi</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">geometry</span><span class="special">::</span><span class="identifier">index</span><span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">Box</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span> Value<span class="special">;</span>
<span class="keyword">typedef</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">rtree</span><span class="special">&lt;</span> Value<span class="special">,</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">linear</span><span class="special">&lt;</span><span class="number">32</span><span class="special">,</span> <span class="number">8</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">RTree</span><span class="special">;</span>
<span class="identifier">RTree</span> <span class="identifier">rt1</span><span class="special">;</span>
<span class="comment">/* some inserting into the tree */</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">Value</span><span class="special">&gt;</span> <span class="identifier">result</span><span class="special">;</span>
<span class="identifier">rt1</span><span class="special">.</span><span class="identifier">spatial_query</span><span class="special">(</span><span class="identifier">Box</span><span class="special">(/*...*/),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">back_inserter</span><span class="special">(</span><span class="identifier">result</span><span class="special">));</span>
<span class="identifier">RTree</span> <span class="identifier">rt2</span><span class="special">(</span><span class="identifier">result</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
</pre>
<p>
However there are better ways. One of these methods is mentioned in the
"Creation and modification" section. The insert iterator may
be passed directly to the query, which will be the fastest way of inserting
query results because temporary container won't be used.
</p>
<pre class="programlisting"><span class="identifier">RTree</span> <span class="identifier">rt3</span><span class="special">;</span>
<span class="identifier">rt1</span><span class="special">.</span><span class="identifier">spatial_query</span><span class="special">(</span><span class="identifier">Box</span><span class="special">(/*...*/),</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">inserter</span><span class="special">(</span><span class="identifier">rt3</span><span class="special">));</span>
</pre>
<p>
If you like Boost.Range you'll appreciate the third option. You may pass
the result Range directly to the constructor.
</p>
<pre class="programlisting"><span class="identifier">RTree</span> <span class="identifier">rt4</span><span class="special">(</span><span class="identifier">rt1</span> <span class="special">|</span> <span class="identifier">bgi</span><span class="special">::</span><span class="identifier">adaptors</span><span class="special">::</span><span class="identifier">spatial_queried</span><span class="special">(</span><span class="identifier">Box</span><span class="special">(/*...*/)));</span>
</pre>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>

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: November 26, 2012 at 17:58:58 GMT</small></p></td>
<td align="left"><p><small>Last revised: November 26, 2012 at 22:11:47 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@@ -51,9 +51,13 @@ A `__translator__` is a type which knows how to handle `__value__`s. It has two
A `__translator__` translates the `__value__` each time the __rtree__ needs it. For this reason
it should rather return const reference to the `__indexable__` than a copy.
If comparison of two `__value__`s is required, the default translator compares
both components of the `std::pair<...>`. If the second one is a `Geometry`,
`geometry::equals()` function is used. For other types it uses `operator==()`.
If comparison of two `__value__`s is required, the default translator:
* for `__point__` and `__box__` - compares `__value__`s with geometry::equals().
* for `std::pair<...>` - compares both components of the `__value__`. The first one is compared with `geometry::equals()`.
If the second one is a `Geometry`, `geometry::equals()` function is used. For other types it uses `operator==()`.
* for `boost::tuple<...>` - compares all components of the `__value__`. If the component is a `Geometry`, `geometry::equals()`
function is used. For other types it uses `operator==()`.
[endsect]
@@ -165,35 +169,59 @@ The __rtree__ allows creation, inserting and removing of Values from a range. Th
std::vector<__value__> values;
/* vector filling code, here */
// create a RTree with default constructor and insert values with RTree::insert(Value const&)
// create R-tree with default constructor and insert values with insert(Value const&)
RTree rt1;
BOOST_FOREACH(__value__ const& v, values)
rt1.insert(v);
// create a RTree with default constructor and insert values with RTree::insert(Iter, Iter)
// create R-tree with default constructor and insert values with insert(Iter, Iter)
RTree rt2;
rt2.insert(values.begin(), values.end());
// create a RTree with default constructor and insert values with RTree::insert(Range)
// create R-tree with default constructor and insert values with insert(Range)
RTree rt3;
rt3.insert(values);
// create a RTree with constructor taking Iterators
// create R-tree with constructor taking Iterators
RTree rt4(values.begin(), values.end());
// create a RTree with constructor taking Range
// create R-tree with constructor taking Range
RTree rt5(values);
// remove values with RTree::remove(Value const&)
// remove values with remove(Value const&)
BOOST_FOREACH(__value__ const& v, values)
rt1.remove(v);
// remove values with RTree::remove(Iter, Iter)
// remove values with remove(Iter, Iter)
rt2.remove(values.begin(), values.end());
// remove values with RTree::remove(Range)
// remove values with remove(Range)
rt3.remove(values);
[endsect]
[section Insert iterator]
There are functions like `std::copy()`, or __rtree__'s queries that copy values to an output iterator.
In order to insert values to a container in this kind of function insert iterators may be used.
Geometry.Index provide its own `bgi::insert_iterator<Container>` which is generated by
`bgi::inserter()` function.
namespace bgi = boost::geometry::index;
typedef std::pair<Box, int> __value__;
typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree;
std::vector<__value__> values;
/* vector filling code, here */
// create R-tree and insert values from the vector
RTree rt1;
std::copy(values.begin(), values.end(), bgi::inserter(rt1));
// create R-tree and insert values returned by a query
RTree rt2;
rt1.spatial_query(Box(/*...*/), bgi::inserter(rt2));
[endsect]
[endsect] [/ Creation and modification /]

View File

@@ -104,4 +104,34 @@ which checks if `__value__` should be returned by the query.
[endsect]
[section Inserting query results into the other R-tree]
There are several ways of inserting Values returned by a query to the other R-tree container.
The most basic way is creating a temporary container for Values and insert them later.
namespace bgi = boost::geometry::index;
typedef std::pair<Box, int> __value__;
typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree;
RTree rt1;
/* some inserting into the tree */
std::vector<Value> result;
rt1.spatial_query(Box(/*...*/), std::back_inserter(result));
RTree rt2(result.begin(), result.end());
However there are better ways. One of these methods is mentioned in the "Creation and modification" section.
The insert iterator may be passed directly to the query, which will be the fastest way of inserting
query results because temporary container won't be used.
RTree rt3;
rt1.spatial_query(Box(/*...*/), bgi::inserter(rt3));
If you like Boost.Range you'll appreciate the third option. You may pass the result Range directly to the
constructor.
RTree rt4(rt1 | bgi::adaptors::spatial_queried(Box(/*...*/)));
[endsect]
[endsect] [/ Spatial queries /]

View File

@@ -22,17 +22,13 @@ class insert_iterator :
public:
typedef Container container_type;
inline explicit insert_iterator()
// : container(0)
{}
inline explicit insert_iterator(Container & c)
: container(&c)
: container(c)
{}
insert_iterator & operator=(typename Container::value_type const& value)
{
index::insert(*container, value);
container.insert(value);
return *this;
}
@@ -52,7 +48,7 @@ public:
}
private:
Container * container;
Container & container;
};
template <typename Container>

View File

@@ -45,6 +45,8 @@
#include <boost/geometry/extensions/index/rtree/rstar/rstar.hpp>
//#include <boost/geometry/extensions/index/rtree/kmeans/kmeans.hpp>
#include <boost/geometry/extensions/index/inserter.hpp>
// TODO change the name to bounding_tree
namespace boost { namespace geometry { namespace index {

View File

@@ -676,6 +676,14 @@ void test_create_insert(bgi::rtree<Value, Algo> & tree, std::vector<Value> const
t.spatial_query(qbox, std::back_inserter(output));
test_exactly_the_same_outputs(t, output, expected_output);
}
{
T t(tree.parameters());
std::copy(input.begin(), input.end(), bgi::inserter(t));
BOOST_CHECK(tree.size() == t.size());
std::vector<Value> output;
t.spatial_query(qbox, std::back_inserter(output));
test_exactly_the_same_outputs(t, output, expected_output);
}
{
T t(input.begin(), input.end(), tree.parameters());
BOOST_CHECK(tree.size() == t.size());