From 640ae6ced69093e09414ebd1d0190d0d7110aa88 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 26 Nov 2012 22:20:38 +0000 Subject: [PATCH] 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] --- doc/html/geometry_index/r_tree.html | 4 ++ .../r_tree/creation_and_modification.html | 69 ++++++++++++++++--- .../r_tree/spatial_queries.html | 39 +++++++++++ doc/html/index.html | 2 +- doc/rtree/creation.qbk | 50 +++++++++++--- doc/rtree/spatial_query.qbk | 30 ++++++++ .../geometry/extensions/index/inserter.hpp | 10 +-- .../geometry/extensions/index/rtree/rtree.hpp | 2 + test/rtree/test_rtree.hpp | 8 +++ 9 files changed, 184 insertions(+), 30 deletions(-) diff --git a/doc/html/geometry_index/r_tree.html b/doc/html/geometry_index/r_tree.html index cda674285..42ae4edb7 100644 --- a/doc/html/geometry_index/r_tree.html +++ b/doc/html/geometry_index/r_tree.html @@ -46,6 +46,8 @@ and removing of Values
Additional interface
+
Insert + iterator
Spatial queries
@@ -57,6 +59,8 @@ predicates
Value predicate
+
Inserting + query results into the other R-tree
Nearest neighbours queries
diff --git a/doc/html/geometry_index/r_tree/creation_and_modification.html b/doc/html/geometry_index/r_tree/creation_and_modification.html index 07814d84f..a79271bfb 100644 --- a/doc/html/geometry_index/r_tree/creation_and_modification.html +++ b/doc/html/geometry_index/r_tree/creation_and_modification.html @@ -42,6 +42,8 @@ and removing of Values
Additional interface
+
Insert + iterator

@@ -130,10 +132,27 @@ to the Indexable than a copy.

- If comparison of two Values 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 Values is required, the default translator:

+
    +
  • + for Point + and Box + - compares Values 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==(). +
  • +

@@ -269,36 +288,64 @@ 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);

+
+ +

+ There are functions like std::copy(), 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 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));
+
+
diff --git a/doc/html/geometry_index/r_tree/spatial_queries.html b/doc/html/geometry_index/r_tree/spatial_queries.html index 6da37a16f..a26b1bcc2 100644 --- a/doc/html/geometry_index/r_tree/spatial_queries.html +++ b/doc/html/geometry_index/r_tree/spatial_queries.html @@ -35,6 +35,8 @@ predicates
Value predicate
+
Inserting + query results into the other R-tree

Spatial queries returns Values @@ -211,6 +213,43 @@ std::back_inserter(result)); +

+ +

+ 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(/*...*/)));
+
+
diff --git a/doc/html/index.html b/doc/html/index.html index 16d52db19..ea9ad1961 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -56,7 +56,7 @@
- +

Last revised: November 26, 2012 at 17:58:58 GMT

Last revised: November 26, 2012 at 22:11:47 GMT


diff --git a/doc/rtree/creation.qbk b/doc/rtree/creation.qbk index 9a1393065..4a70e0ef3 100644 --- a/doc/rtree/creation.qbk +++ b/doc/rtree/creation.qbk @@ -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` which is generated by +`bgi::inserter()` function. + + namespace bgi = boost::geometry::index; + typedef std::pair __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 /] diff --git a/doc/rtree/spatial_query.qbk b/doc/rtree/spatial_query.qbk index e9802a977..562555444 100644 --- a/doc/rtree/spatial_query.qbk +++ b/doc/rtree/spatial_query.qbk @@ -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 __value__; + typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree; + + RTree rt1; + /* some inserting into the tree */ + + std::vector 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 /] diff --git a/include/boost/geometry/extensions/index/inserter.hpp b/include/boost/geometry/extensions/index/inserter.hpp index 15f4b176b..186d62f9a 100644 --- a/include/boost/geometry/extensions/index/inserter.hpp +++ b/include/boost/geometry/extensions/index/inserter.hpp @@ -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 diff --git a/include/boost/geometry/extensions/index/rtree/rtree.hpp b/include/boost/geometry/extensions/index/rtree/rtree.hpp index 349d0ca77..dc2946fcc 100644 --- a/include/boost/geometry/extensions/index/rtree/rtree.hpp +++ b/include/boost/geometry/extensions/index/rtree/rtree.hpp @@ -45,6 +45,8 @@ #include //#include +#include + // TODO change the name to bounding_tree namespace boost { namespace geometry { namespace index { diff --git a/test/rtree/test_rtree.hpp b/test/rtree/test_rtree.hpp index a40e6f716..4bd8d77a5 100644 --- a/test/rtree/test_rtree.hpp +++ b/test/rtree/test_rtree.hpp @@ -676,6 +676,14 @@ void test_create_insert(bgi::rtree & tree, std::vector 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 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());