Chris@16
|
1 // Boost.Geometry Index
|
Chris@16
|
2 //
|
Chris@16
|
3 // R-tree implementation
|
Chris@16
|
4 //
|
Chris@16
|
5 // Copyright (c) 2008 Federico J. Fernandez.
|
Chris@101
|
6 // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
Chris@16
|
7 //
|
Chris@16
|
8 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
10 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef BOOST_GEOMETRY_INDEX_RTREE_HPP
|
Chris@16
|
13 #define BOOST_GEOMETRY_INDEX_RTREE_HPP
|
Chris@16
|
14
|
Chris@101
|
15 // STD
|
Chris@16
|
16 #include <algorithm>
|
Chris@16
|
17
|
Chris@101
|
18 // Boost
|
Chris@16
|
19 #include <boost/tuple/tuple.hpp>
|
Chris@16
|
20 #include <boost/move/move.hpp>
|
Chris@16
|
21
|
Chris@101
|
22 // Boost.Geometry
|
Chris@101
|
23 #include <boost/geometry/algorithms/detail/comparable_distance/interface.hpp>
|
Chris@101
|
24 #include <boost/geometry/algorithms/centroid.hpp>
|
Chris@101
|
25 #include <boost/geometry/algorithms/covered_by.hpp>
|
Chris@101
|
26 #include <boost/geometry/algorithms/disjoint.hpp>
|
Chris@101
|
27 #include <boost/geometry/algorithms/equals.hpp>
|
Chris@101
|
28 #include <boost/geometry/algorithms/intersects.hpp>
|
Chris@101
|
29 #include <boost/geometry/algorithms/overlaps.hpp>
|
Chris@101
|
30 #include <boost/geometry/algorithms/touches.hpp>
|
Chris@101
|
31 #include <boost/geometry/algorithms/within.hpp>
|
Chris@16
|
32
|
Chris@101
|
33 #include <boost/geometry/geometries/point.hpp>
|
Chris@101
|
34 #include <boost/geometry/geometries/box.hpp>
|
Chris@101
|
35
|
Chris@101
|
36 #include <boost/geometry/strategies/strategies.hpp>
|
Chris@101
|
37
|
Chris@101
|
38 // Boost.Geometry.Index
|
Chris@16
|
39 #include <boost/geometry/index/detail/config_begin.hpp>
|
Chris@16
|
40
|
Chris@16
|
41 #include <boost/geometry/index/detail/assert.hpp>
|
Chris@16
|
42 #include <boost/geometry/index/detail/exception.hpp>
|
Chris@16
|
43
|
Chris@16
|
44 #include <boost/geometry/index/detail/rtree/options.hpp>
|
Chris@16
|
45
|
Chris@16
|
46 #include <boost/geometry/index/indexable.hpp>
|
Chris@16
|
47 #include <boost/geometry/index/equal_to.hpp>
|
Chris@16
|
48
|
Chris@16
|
49 #include <boost/geometry/index/detail/translator.hpp>
|
Chris@16
|
50
|
Chris@16
|
51 #include <boost/geometry/index/predicates.hpp>
|
Chris@16
|
52 #include <boost/geometry/index/distance_predicates.hpp>
|
Chris@16
|
53 #include <boost/geometry/index/detail/rtree/adaptors.hpp>
|
Chris@16
|
54
|
Chris@16
|
55 #include <boost/geometry/index/detail/meta.hpp>
|
Chris@16
|
56 #include <boost/geometry/index/detail/utilities.hpp>
|
Chris@16
|
57 #include <boost/geometry/index/detail/rtree/node/node.hpp>
|
Chris@16
|
58
|
Chris@16
|
59 #include <boost/geometry/index/detail/algorithms/is_valid.hpp>
|
Chris@16
|
60
|
Chris@16
|
61 #include <boost/geometry/index/detail/rtree/visitors/insert.hpp>
|
Chris@16
|
62 #include <boost/geometry/index/detail/rtree/visitors/remove.hpp>
|
Chris@16
|
63 #include <boost/geometry/index/detail/rtree/visitors/copy.hpp>
|
Chris@16
|
64 #include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
|
Chris@16
|
65 #include <boost/geometry/index/detail/rtree/visitors/spatial_query.hpp>
|
Chris@16
|
66 #include <boost/geometry/index/detail/rtree/visitors/distance_query.hpp>
|
Chris@16
|
67 #include <boost/geometry/index/detail/rtree/visitors/count.hpp>
|
Chris@16
|
68 #include <boost/geometry/index/detail/rtree/visitors/children_box.hpp>
|
Chris@16
|
69
|
Chris@16
|
70 #include <boost/geometry/index/detail/rtree/linear/linear.hpp>
|
Chris@16
|
71 #include <boost/geometry/index/detail/rtree/quadratic/quadratic.hpp>
|
Chris@16
|
72 #include <boost/geometry/index/detail/rtree/rstar/rstar.hpp>
|
Chris@16
|
73 //#include <boost/geometry/extensions/index/detail/rtree/kmeans/kmeans.hpp>
|
Chris@16
|
74
|
Chris@16
|
75 #include <boost/geometry/index/detail/rtree/pack_create.hpp>
|
Chris@16
|
76
|
Chris@16
|
77 #include <boost/geometry/index/inserter.hpp>
|
Chris@16
|
78
|
Chris@16
|
79 #include <boost/geometry/index/detail/rtree/utilities/view.hpp>
|
Chris@16
|
80
|
Chris@16
|
81 #include <boost/geometry/index/detail/rtree/query_iterators.hpp>
|
Chris@16
|
82
|
Chris@16
|
83 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
Chris@16
|
84 // serialization
|
Chris@16
|
85 #include <boost/geometry/index/detail/serialization.hpp>
|
Chris@16
|
86 #endif
|
Chris@16
|
87
|
Chris@16
|
88 // TODO change the name to bounding_tree
|
Chris@16
|
89
|
Chris@16
|
90 /*!
|
Chris@16
|
91 \defgroup rtree_functions R-tree free functions (boost::geometry::index::)
|
Chris@16
|
92 */
|
Chris@16
|
93
|
Chris@16
|
94 namespace boost { namespace geometry { namespace index {
|
Chris@16
|
95
|
Chris@16
|
96 /*!
|
Chris@16
|
97 \brief The R-tree spatial index.
|
Chris@16
|
98
|
Chris@101
|
99 This is self-balancing spatial index capable to store various types of Values
|
Chris@101
|
100 and balancing algorithms.
|
Chris@16
|
101
|
Chris@16
|
102 \par Parameters
|
Chris@16
|
103 The user must pass a type defining the Parameters which will
|
Chris@101
|
104 be used in rtree creation process. This type is used e.g. to specify balancing
|
Chris@101
|
105 algorithm with specific parameters like min and max number of elements in node.
|
Chris@16
|
106
|
Chris@16
|
107 \par
|
Chris@16
|
108 Predefined algorithms with compile-time parameters are:
|
Chris@16
|
109 \li <tt>boost::geometry::index::linear</tt>,
|
Chris@16
|
110 \li <tt>boost::geometry::index::quadratic</tt>,
|
Chris@16
|
111 \li <tt>boost::geometry::index::rstar</tt>.
|
Chris@16
|
112
|
Chris@16
|
113 \par
|
Chris@16
|
114 Predefined algorithms with run-time parameters are:
|
Chris@16
|
115 \li \c boost::geometry::index::dynamic_linear,
|
Chris@16
|
116 \li \c boost::geometry::index::dynamic_quadratic,
|
Chris@16
|
117 \li \c boost::geometry::index::dynamic_rstar.
|
Chris@16
|
118
|
Chris@16
|
119 \par IndexableGetter
|
Chris@101
|
120 The object of IndexableGetter type translates from Value to Indexable each time
|
Chris@101
|
121 r-tree requires it. This means that this operation is done for each Value
|
Chris@101
|
122 access. Therefore the IndexableGetter should return the Indexable by
|
Chris@101
|
123 a reference type. The Indexable should not be calculated since it could harm
|
Chris@101
|
124 the performance. The default IndexableGetter can translate all types adapted
|
Chris@101
|
125 to Point, Box or Segment concepts (called Indexables). Furthermore, it can
|
Chris@101
|
126 handle <tt>std::pair<Indexable, T></tt>, <tt>boost::tuple<Indexable, ...></tt>
|
Chris@101
|
127 and <tt>std::tuple<Indexable, ...></tt> when possible. For example, for Value
|
Chris@101
|
128 of type <tt>std::pair<Box, int></tt>, the default IndexableGetter translates
|
Chris@101
|
129 from <tt>std::pair<Box, int> const&</tt> to <tt>Box const&</tt>.
|
Chris@16
|
130
|
Chris@16
|
131 \par EqualTo
|
Chris@101
|
132 The object of EqualTo type compares Values and returns <tt>true</tt> if they
|
Chris@101
|
133 are equal. It's similar to <tt>std::equal_to<></tt>. The default EqualTo
|
Chris@101
|
134 returns the result of <tt>boost::geometry::equals()</tt> for types adapted to
|
Chris@101
|
135 some Geometry concept defined in Boost.Geometry and the result of
|
Chris@101
|
136 <tt>operator==</tt> for other types. Components of Pairs and Tuples are
|
Chris@101
|
137 compared left-to-right.
|
Chris@16
|
138
|
Chris@16
|
139 \tparam Value The type of objects stored in the container.
|
Chris@16
|
140 \tparam Parameters Compile-time parameters.
|
Chris@16
|
141 \tparam IndexableGetter The function object extracting Indexable from Value.
|
Chris@16
|
142 \tparam EqualTo The function object comparing objects of type Value.
|
Chris@101
|
143 \tparam Allocator The allocator used to allocate/deallocate memory,
|
Chris@101
|
144 construct/destroy nodes and Values.
|
Chris@16
|
145 */
|
Chris@16
|
146 template <
|
Chris@16
|
147 typename Value,
|
Chris@16
|
148 typename Parameters,
|
Chris@16
|
149 typename IndexableGetter = index::indexable<Value>,
|
Chris@16
|
150 typename EqualTo = index::equal_to<Value>,
|
Chris@16
|
151 typename Allocator = std::allocator<Value>
|
Chris@16
|
152 >
|
Chris@16
|
153 class rtree
|
Chris@16
|
154 {
|
Chris@16
|
155 BOOST_COPYABLE_AND_MOVABLE(rtree)
|
Chris@16
|
156
|
Chris@16
|
157 public:
|
Chris@16
|
158 /*! \brief The type of Value stored in the container. */
|
Chris@16
|
159 typedef Value value_type;
|
Chris@16
|
160 /*! \brief R-tree parameters type. */
|
Chris@16
|
161 typedef Parameters parameters_type;
|
Chris@16
|
162 /*! \brief The function object extracting Indexable from Value. */
|
Chris@16
|
163 typedef IndexableGetter indexable_getter;
|
Chris@16
|
164 /*! \brief The function object comparing objects of type Value. */
|
Chris@16
|
165 typedef EqualTo value_equal;
|
Chris@16
|
166 /*! \brief The type of allocator used by the container. */
|
Chris@16
|
167 typedef Allocator allocator_type;
|
Chris@16
|
168
|
Chris@16
|
169 // TODO: SHOULD THIS TYPE BE REMOVED?
|
Chris@16
|
170 /*! \brief The Indexable type to which Value is translated. */
|
Chris@16
|
171 typedef typename index::detail::indexable_type<
|
Chris@16
|
172 detail::translator<IndexableGetter, EqualTo>
|
Chris@16
|
173 >::type indexable_type;
|
Chris@16
|
174
|
Chris@16
|
175 /*! \brief The Box type used by the R-tree. */
|
Chris@16
|
176 typedef geometry::model::box<
|
Chris@16
|
177 geometry::model::point<
|
Chris@16
|
178 typename coordinate_type<indexable_type>::type,
|
Chris@16
|
179 dimension<indexable_type>::value,
|
Chris@16
|
180 typename coordinate_system<indexable_type>::type
|
Chris@16
|
181 >
|
Chris@16
|
182 >
|
Chris@16
|
183 bounds_type;
|
Chris@16
|
184
|
Chris@16
|
185 private:
|
Chris@16
|
186
|
Chris@16
|
187 typedef detail::translator<IndexableGetter, EqualTo> translator_type;
|
Chris@16
|
188
|
Chris@16
|
189 typedef bounds_type box_type;
|
Chris@16
|
190 typedef typename detail::rtree::options_type<Parameters>::type options_type;
|
Chris@16
|
191 typedef typename options_type::node_tag node_tag;
|
Chris@16
|
192 typedef detail::rtree::allocators<allocator_type, value_type, typename options_type::parameters_type, box_type, node_tag> allocators_type;
|
Chris@16
|
193
|
Chris@16
|
194 typedef typename detail::rtree::node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type node;
|
Chris@16
|
195 typedef typename detail::rtree::internal_node<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type internal_node;
|
Chris@16
|
196 typedef typename detail::rtree::leaf<value_type, typename options_type::parameters_type, box_type, allocators_type, node_tag>::type leaf;
|
Chris@16
|
197
|
Chris@16
|
198 typedef typename allocators_type::node_pointer node_pointer;
|
Chris@16
|
199 typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
Chris@101
|
200 typedef detail::rtree::subtree_destroyer<value_type, options_type, translator_type, box_type, allocators_type> subtree_destroyer;
|
Chris@16
|
201
|
Chris@16
|
202 friend class detail::rtree::utilities::view<rtree>;
|
Chris@16
|
203 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
Chris@16
|
204 friend class detail::rtree::private_view<rtree>;
|
Chris@16
|
205 friend class detail::rtree::const_private_view<rtree>;
|
Chris@16
|
206 #endif
|
Chris@16
|
207
|
Chris@16
|
208 public:
|
Chris@16
|
209
|
Chris@16
|
210 /*! \brief Type of reference to Value. */
|
Chris@16
|
211 typedef typename allocators_type::reference reference;
|
Chris@16
|
212 /*! \brief Type of reference to const Value. */
|
Chris@16
|
213 typedef typename allocators_type::const_reference const_reference;
|
Chris@16
|
214 /*! \brief Type of pointer to Value. */
|
Chris@16
|
215 typedef typename allocators_type::pointer pointer;
|
Chris@16
|
216 /*! \brief Type of pointer to const Value. */
|
Chris@16
|
217 typedef typename allocators_type::const_pointer const_pointer;
|
Chris@16
|
218 /*! \brief Type of difference type. */
|
Chris@16
|
219 typedef typename allocators_type::difference_type difference_type;
|
Chris@16
|
220 /*! \brief Unsigned integral type used by the container. */
|
Chris@16
|
221 typedef typename allocators_type::size_type size_type;
|
Chris@16
|
222
|
Chris@16
|
223 /*! \brief Type of const query iterator. */
|
Chris@16
|
224 typedef index::detail::rtree::iterators::query_iterator<value_type, allocators_type> const_query_iterator;
|
Chris@16
|
225
|
Chris@16
|
226 public:
|
Chris@16
|
227
|
Chris@16
|
228 /*!
|
Chris@16
|
229 \brief The constructor.
|
Chris@16
|
230
|
Chris@16
|
231 \param parameters The parameters object.
|
Chris@16
|
232 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
233 \param equal The function object comparing Values.
|
Chris@16
|
234
|
Chris@16
|
235 \par Throws
|
Chris@16
|
236 If allocator default constructor throws.
|
Chris@16
|
237 */
|
Chris@16
|
238 inline explicit rtree(parameters_type const& parameters = parameters_type(),
|
Chris@16
|
239 indexable_getter const& getter = indexable_getter(),
|
Chris@16
|
240 value_equal const& equal = value_equal())
|
Chris@16
|
241 : m_members(getter, equal, parameters)
|
Chris@16
|
242 {}
|
Chris@16
|
243
|
Chris@16
|
244 /*!
|
Chris@16
|
245 \brief The constructor.
|
Chris@16
|
246
|
Chris@16
|
247 \param parameters The parameters object.
|
Chris@16
|
248 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
249 \param equal The function object comparing Values.
|
Chris@16
|
250 \param allocator The allocator object.
|
Chris@16
|
251
|
Chris@16
|
252 \par Throws
|
Chris@16
|
253 If allocator copy constructor throws.
|
Chris@16
|
254 */
|
Chris@16
|
255 inline rtree(parameters_type const& parameters,
|
Chris@16
|
256 indexable_getter const& getter,
|
Chris@16
|
257 value_equal const& equal,
|
Chris@16
|
258 allocator_type const& allocator)
|
Chris@16
|
259 : m_members(getter, equal, parameters, allocator)
|
Chris@16
|
260 {}
|
Chris@16
|
261
|
Chris@16
|
262 /*!
|
Chris@16
|
263 \brief The constructor.
|
Chris@16
|
264
|
Chris@16
|
265 The tree is created using packing algorithm.
|
Chris@16
|
266
|
Chris@16
|
267 \param first The beginning of the range of Values.
|
Chris@16
|
268 \param last The end of the range of Values.
|
Chris@16
|
269 \param parameters The parameters object.
|
Chris@16
|
270 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
271 \param equal The function object comparing Values.
|
Chris@16
|
272 \param allocator The allocator object.
|
Chris@16
|
273
|
Chris@16
|
274 \par Throws
|
Chris@16
|
275 \li If allocator copy constructor throws.
|
Chris@16
|
276 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
277 \li If allocation throws or returns invalid value.
|
Chris@16
|
278 */
|
Chris@16
|
279 template<typename Iterator>
|
Chris@16
|
280 inline rtree(Iterator first, Iterator last,
|
Chris@16
|
281 parameters_type const& parameters = parameters_type(),
|
Chris@16
|
282 indexable_getter const& getter = indexable_getter(),
|
Chris@16
|
283 value_equal const& equal = value_equal(),
|
Chris@16
|
284 allocator_type const& allocator = allocator_type())
|
Chris@16
|
285 : m_members(getter, equal, parameters, allocator)
|
Chris@16
|
286 {
|
Chris@16
|
287 typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
|
Chris@16
|
288 size_type vc = 0, ll = 0;
|
Chris@16
|
289 m_members.root = pack::apply(first, last, vc, ll,
|
Chris@16
|
290 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
291 m_members.values_count = vc;
|
Chris@16
|
292 m_members.leafs_level = ll;
|
Chris@16
|
293 }
|
Chris@16
|
294
|
Chris@16
|
295 /*!
|
Chris@16
|
296 \brief The constructor.
|
Chris@16
|
297
|
Chris@16
|
298 The tree is created using packing algorithm.
|
Chris@16
|
299
|
Chris@16
|
300 \param rng The range of Values.
|
Chris@16
|
301 \param parameters The parameters object.
|
Chris@16
|
302 \param getter The function object extracting Indexable from Value.
|
Chris@16
|
303 \param equal The function object comparing Values.
|
Chris@16
|
304 \param allocator The allocator object.
|
Chris@16
|
305
|
Chris@16
|
306 \par Throws
|
Chris@16
|
307 \li If allocator copy constructor throws.
|
Chris@16
|
308 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
309 \li If allocation throws or returns invalid value.
|
Chris@16
|
310 */
|
Chris@16
|
311 template<typename Range>
|
Chris@16
|
312 inline explicit rtree(Range const& rng,
|
Chris@16
|
313 parameters_type const& parameters = parameters_type(),
|
Chris@16
|
314 indexable_getter const& getter = indexable_getter(),
|
Chris@16
|
315 value_equal const& equal = value_equal(),
|
Chris@16
|
316 allocator_type const& allocator = allocator_type())
|
Chris@16
|
317 : m_members(getter, equal, parameters, allocator)
|
Chris@16
|
318 {
|
Chris@16
|
319 typedef detail::rtree::pack<value_type, options_type, translator_type, box_type, allocators_type> pack;
|
Chris@16
|
320 size_type vc = 0, ll = 0;
|
Chris@16
|
321 m_members.root = pack::apply(::boost::begin(rng), ::boost::end(rng), vc, ll,
|
Chris@16
|
322 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
323 m_members.values_count = vc;
|
Chris@16
|
324 m_members.leafs_level = ll;
|
Chris@16
|
325 }
|
Chris@16
|
326
|
Chris@16
|
327 /*!
|
Chris@16
|
328 \brief The destructor.
|
Chris@16
|
329
|
Chris@16
|
330 \par Throws
|
Chris@16
|
331 Nothing.
|
Chris@16
|
332 */
|
Chris@16
|
333 inline ~rtree()
|
Chris@16
|
334 {
|
Chris@16
|
335 this->raw_destroy(*this);
|
Chris@16
|
336 }
|
Chris@16
|
337
|
Chris@16
|
338 /*!
|
Chris@16
|
339 \brief The copy constructor.
|
Chris@16
|
340
|
Chris@16
|
341 It uses parameters, translator and allocator from the source tree.
|
Chris@16
|
342
|
Chris@16
|
343 \param src The rtree which content will be copied.
|
Chris@16
|
344
|
Chris@16
|
345 \par Throws
|
Chris@16
|
346 \li If allocator copy constructor throws.
|
Chris@16
|
347 \li If Value copy constructor throws.
|
Chris@16
|
348 \li If allocation throws or returns invalid value.
|
Chris@16
|
349 */
|
Chris@16
|
350 inline rtree(rtree const& src)
|
Chris@16
|
351 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
352 src.m_members.equal_to(),
|
Chris@16
|
353 src.m_members.parameters(),
|
Chris@16
|
354 allocator_traits_type::select_on_container_copy_construction(src.get_allocator()))
|
Chris@16
|
355 {
|
Chris@16
|
356 this->raw_copy(src, *this, false);
|
Chris@16
|
357 }
|
Chris@16
|
358
|
Chris@16
|
359 /*!
|
Chris@16
|
360 \brief The copy constructor.
|
Chris@16
|
361
|
Chris@16
|
362 It uses Parameters and translator from the source tree.
|
Chris@16
|
363
|
Chris@16
|
364 \param src The rtree which content will be copied.
|
Chris@16
|
365 \param allocator The allocator which will be used.
|
Chris@16
|
366
|
Chris@16
|
367 \par Throws
|
Chris@16
|
368 \li If allocator copy constructor throws.
|
Chris@16
|
369 \li If Value copy constructor throws.
|
Chris@16
|
370 \li If allocation throws or returns invalid value.
|
Chris@16
|
371 */
|
Chris@16
|
372 inline rtree(rtree const& src, allocator_type const& allocator)
|
Chris@16
|
373 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
374 src.m_members.equal_to(),
|
Chris@16
|
375 src.m_members.parameters(), allocator)
|
Chris@16
|
376 {
|
Chris@16
|
377 this->raw_copy(src, *this, false);
|
Chris@16
|
378 }
|
Chris@16
|
379
|
Chris@16
|
380 /*!
|
Chris@16
|
381 \brief The moving constructor.
|
Chris@16
|
382
|
Chris@16
|
383 It uses parameters, translator and allocator from the source tree.
|
Chris@16
|
384
|
Chris@16
|
385 \param src The rtree which content will be moved.
|
Chris@16
|
386
|
Chris@16
|
387 \par Throws
|
Chris@16
|
388 Nothing.
|
Chris@16
|
389 */
|
Chris@16
|
390 inline rtree(BOOST_RV_REF(rtree) src)
|
Chris@16
|
391 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
392 src.m_members.equal_to(),
|
Chris@16
|
393 src.m_members.parameters(),
|
Chris@16
|
394 boost::move(src.m_members.allocators()))
|
Chris@16
|
395 {
|
Chris@16
|
396 boost::swap(m_members.values_count, src.m_members.values_count);
|
Chris@16
|
397 boost::swap(m_members.leafs_level, src.m_members.leafs_level);
|
Chris@16
|
398 boost::swap(m_members.root, src.m_members.root);
|
Chris@16
|
399 }
|
Chris@16
|
400
|
Chris@16
|
401 /*!
|
Chris@16
|
402 \brief The moving constructor.
|
Chris@16
|
403
|
Chris@16
|
404 It uses parameters and translator from the source tree.
|
Chris@16
|
405
|
Chris@16
|
406 \param src The rtree which content will be moved.
|
Chris@16
|
407 \param allocator The allocator.
|
Chris@16
|
408
|
Chris@16
|
409 \par Throws
|
Chris@16
|
410 \li If allocator copy constructor throws.
|
Chris@16
|
411 \li If Value copy constructor throws (only if allocators aren't equal).
|
Chris@16
|
412 \li If allocation throws or returns invalid value (only if allocators aren't equal).
|
Chris@16
|
413 */
|
Chris@16
|
414 inline rtree(BOOST_RV_REF(rtree) src, allocator_type const& allocator)
|
Chris@16
|
415 : m_members(src.m_members.indexable_getter(),
|
Chris@16
|
416 src.m_members.equal_to(),
|
Chris@16
|
417 src.m_members.parameters(),
|
Chris@16
|
418 allocator)
|
Chris@16
|
419 {
|
Chris@16
|
420 if ( src.m_members.allocators() == allocator )
|
Chris@16
|
421 {
|
Chris@16
|
422 boost::swap(m_members.values_count, src.m_members.values_count);
|
Chris@16
|
423 boost::swap(m_members.leafs_level, src.m_members.leafs_level);
|
Chris@16
|
424 boost::swap(m_members.root, src.m_members.root);
|
Chris@16
|
425 }
|
Chris@16
|
426 else
|
Chris@16
|
427 {
|
Chris@16
|
428 this->raw_copy(src, *this, false);
|
Chris@16
|
429 }
|
Chris@16
|
430 }
|
Chris@16
|
431
|
Chris@16
|
432 /*!
|
Chris@16
|
433 \brief The assignment operator.
|
Chris@16
|
434
|
Chris@16
|
435 It uses parameters and translator from the source tree.
|
Chris@16
|
436
|
Chris@16
|
437 \param src The rtree which content will be copied.
|
Chris@16
|
438
|
Chris@16
|
439 \par Throws
|
Chris@16
|
440 \li If Value copy constructor throws.
|
Chris@16
|
441 \li If allocation throws.
|
Chris@16
|
442 \li If allocation throws or returns invalid value.
|
Chris@16
|
443 */
|
Chris@16
|
444 inline rtree & operator=(BOOST_COPY_ASSIGN_REF(rtree) src)
|
Chris@16
|
445 {
|
Chris@16
|
446 if ( &src != this )
|
Chris@16
|
447 {
|
Chris@16
|
448 allocators_type & this_allocs = m_members.allocators();
|
Chris@16
|
449 allocators_type const& src_allocs = src.m_members.allocators();
|
Chris@16
|
450
|
Chris@16
|
451 // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
|
Chris@16
|
452 // (allocators stored as base classes of members_holder)
|
Chris@16
|
453 // copying them changes values_count, in this case it doesn't cause errors since data must be copied
|
Chris@16
|
454
|
Chris@16
|
455 typedef boost::mpl::bool_<
|
Chris@16
|
456 allocator_traits_type::propagate_on_container_copy_assignment::value
|
Chris@16
|
457 > propagate;
|
Chris@16
|
458
|
Chris@16
|
459 if ( propagate::value && !(this_allocs == src_allocs) )
|
Chris@16
|
460 this->raw_destroy(*this);
|
Chris@16
|
461 detail::assign_cond(this_allocs, src_allocs, propagate());
|
Chris@16
|
462
|
Chris@16
|
463 // It uses m_allocators
|
Chris@16
|
464 this->raw_copy(src, *this, true);
|
Chris@16
|
465 }
|
Chris@16
|
466
|
Chris@16
|
467 return *this;
|
Chris@16
|
468 }
|
Chris@16
|
469
|
Chris@16
|
470 /*!
|
Chris@16
|
471 \brief The moving assignment.
|
Chris@16
|
472
|
Chris@16
|
473 It uses parameters and translator from the source tree.
|
Chris@16
|
474
|
Chris@16
|
475 \param src The rtree which content will be moved.
|
Chris@16
|
476
|
Chris@16
|
477 \par Throws
|
Chris@16
|
478 Only if allocators aren't equal.
|
Chris@16
|
479 \li If Value copy constructor throws.
|
Chris@16
|
480 \li If allocation throws or returns invalid value.
|
Chris@16
|
481 */
|
Chris@16
|
482 inline rtree & operator=(BOOST_RV_REF(rtree) src)
|
Chris@16
|
483 {
|
Chris@16
|
484 if ( &src != this )
|
Chris@16
|
485 {
|
Chris@16
|
486 allocators_type & this_allocs = m_members.allocators();
|
Chris@16
|
487 allocators_type & src_allocs = src.m_members.allocators();
|
Chris@16
|
488
|
Chris@16
|
489 if ( this_allocs == src_allocs )
|
Chris@16
|
490 {
|
Chris@16
|
491 this->raw_destroy(*this);
|
Chris@16
|
492
|
Chris@16
|
493 m_members.indexable_getter() = src.m_members.indexable_getter();
|
Chris@16
|
494 m_members.equal_to() = src.m_members.equal_to();
|
Chris@16
|
495 m_members.parameters() = src.m_members.parameters();
|
Chris@16
|
496
|
Chris@16
|
497 boost::swap(m_members.values_count, src.m_members.values_count);
|
Chris@16
|
498 boost::swap(m_members.leafs_level, src.m_members.leafs_level);
|
Chris@16
|
499 boost::swap(m_members.root, src.m_members.root);
|
Chris@16
|
500
|
Chris@16
|
501 // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
|
Chris@16
|
502 // (allocators stored as base classes of members_holder)
|
Chris@16
|
503 // moving them changes values_count
|
Chris@16
|
504
|
Chris@16
|
505 typedef boost::mpl::bool_<
|
Chris@16
|
506 allocator_traits_type::propagate_on_container_move_assignment::value
|
Chris@16
|
507 > propagate;
|
Chris@16
|
508 detail::move_cond(this_allocs, src_allocs, propagate());
|
Chris@16
|
509 }
|
Chris@16
|
510 else
|
Chris@16
|
511 {
|
Chris@16
|
512 // TODO - shouldn't here propagate_on_container_copy_assignment be checked like in operator=(const&)?
|
Chris@16
|
513
|
Chris@16
|
514 // It uses m_allocators
|
Chris@16
|
515 this->raw_copy(src, *this, true);
|
Chris@16
|
516 }
|
Chris@16
|
517 }
|
Chris@16
|
518
|
Chris@16
|
519 return *this;
|
Chris@16
|
520 }
|
Chris@16
|
521
|
Chris@16
|
522 /*!
|
Chris@16
|
523 \brief Swaps contents of two rtrees.
|
Chris@16
|
524
|
Chris@16
|
525 Parameters, translator and allocators are swapped as well.
|
Chris@16
|
526
|
Chris@16
|
527 \param other The rtree which content will be swapped with this rtree content.
|
Chris@16
|
528
|
Chris@16
|
529 \par Throws
|
Chris@16
|
530 If allocators swap throws.
|
Chris@16
|
531 */
|
Chris@16
|
532 void swap(rtree & other)
|
Chris@16
|
533 {
|
Chris@16
|
534 boost::swap(m_members.indexable_getter(), other.m_members.indexable_getter());
|
Chris@16
|
535 boost::swap(m_members.equal_to(), other.m_members.equal_to());
|
Chris@16
|
536 boost::swap(m_members.parameters(), other.m_members.parameters());
|
Chris@16
|
537
|
Chris@16
|
538 // NOTE: if propagate is true for std allocators on darwin 4.2.1, glibc++
|
Chris@16
|
539 // (allocators stored as base classes of members_holder)
|
Chris@16
|
540 // swapping them changes values_count
|
Chris@16
|
541
|
Chris@16
|
542 typedef boost::mpl::bool_<
|
Chris@16
|
543 allocator_traits_type::propagate_on_container_swap::value
|
Chris@16
|
544 > propagate;
|
Chris@16
|
545 detail::swap_cond(m_members.allocators(), other.m_members.allocators(), propagate());
|
Chris@16
|
546
|
Chris@16
|
547 boost::swap(m_members.values_count, other.m_members.values_count);
|
Chris@16
|
548 boost::swap(m_members.leafs_level, other.m_members.leafs_level);
|
Chris@16
|
549 boost::swap(m_members.root, other.m_members.root);
|
Chris@16
|
550 }
|
Chris@16
|
551
|
Chris@16
|
552 /*!
|
Chris@16
|
553 \brief Insert a value to the index.
|
Chris@16
|
554
|
Chris@16
|
555 \param value The value which will be stored in the container.
|
Chris@16
|
556
|
Chris@16
|
557 \par Throws
|
Chris@16
|
558 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
559 \li If allocation throws or returns invalid value.
|
Chris@16
|
560
|
Chris@16
|
561 \warning
|
Chris@16
|
562 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
563 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
564 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
565 some of them may return invalid data.
|
Chris@16
|
566 */
|
Chris@16
|
567 inline void insert(value_type const& value)
|
Chris@16
|
568 {
|
Chris@16
|
569 if ( !m_members.root )
|
Chris@16
|
570 this->raw_create();
|
Chris@16
|
571
|
Chris@16
|
572 this->raw_insert(value);
|
Chris@16
|
573 }
|
Chris@16
|
574
|
Chris@16
|
575 /*!
|
Chris@16
|
576 \brief Insert a range of values to the index.
|
Chris@16
|
577
|
Chris@16
|
578 \param first The beginning of the range of values.
|
Chris@16
|
579 \param last The end of the range of values.
|
Chris@16
|
580
|
Chris@16
|
581 \par Throws
|
Chris@16
|
582 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
583 \li If allocation throws or returns invalid value.
|
Chris@16
|
584
|
Chris@16
|
585 \warning
|
Chris@16
|
586 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
587 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
588 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
589 some of them may return invalid data.
|
Chris@16
|
590 */
|
Chris@16
|
591 template <typename Iterator>
|
Chris@16
|
592 inline void insert(Iterator first, Iterator last)
|
Chris@16
|
593 {
|
Chris@16
|
594 if ( !m_members.root )
|
Chris@16
|
595 this->raw_create();
|
Chris@16
|
596
|
Chris@16
|
597 for ( ; first != last ; ++first )
|
Chris@16
|
598 this->raw_insert(*first);
|
Chris@16
|
599 }
|
Chris@16
|
600
|
Chris@16
|
601 /*!
|
Chris@101
|
602 \brief Insert a value created using convertible object or a range of values to the index.
|
Chris@16
|
603
|
Chris@101
|
604 \param conv_or_rng An object of type convertible to value_type or a range of values.
|
Chris@16
|
605
|
Chris@16
|
606 \par Throws
|
Chris@16
|
607 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
608 \li If allocation throws or returns invalid value.
|
Chris@16
|
609
|
Chris@16
|
610 \warning
|
Chris@16
|
611 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
612 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
613 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
614 some of them may return invalid data.
|
Chris@16
|
615 */
|
Chris@101
|
616 template <typename ConvertibleOrRange>
|
Chris@101
|
617 inline void insert(ConvertibleOrRange const& conv_or_rng)
|
Chris@16
|
618 {
|
Chris@101
|
619 typedef boost::mpl::bool_
|
Chris@101
|
620 <
|
Chris@101
|
621 boost::is_convertible<ConvertibleOrRange, value_type>::value
|
Chris@101
|
622 > is_conv_t;
|
Chris@16
|
623
|
Chris@101
|
624 this->insert_dispatch(conv_or_rng, is_conv_t());
|
Chris@16
|
625 }
|
Chris@16
|
626
|
Chris@16
|
627 /*!
|
Chris@16
|
628 \brief Remove a value from the container.
|
Chris@16
|
629
|
Chris@16
|
630 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
631 this method removes only one value from the container.
|
Chris@16
|
632
|
Chris@16
|
633 \param value The value which will be removed from the container.
|
Chris@16
|
634
|
Chris@16
|
635 \return 1 if the value was removed, 0 otherwise.
|
Chris@16
|
636
|
Chris@16
|
637 \par Throws
|
Chris@16
|
638 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
639 \li If allocation throws or returns invalid value.
|
Chris@16
|
640
|
Chris@16
|
641 \warning
|
Chris@16
|
642 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
643 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
644 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
645 some of them may return invalid data.
|
Chris@16
|
646 */
|
Chris@16
|
647 inline size_type remove(value_type const& value)
|
Chris@16
|
648 {
|
Chris@16
|
649 return this->raw_remove(value);
|
Chris@16
|
650 }
|
Chris@16
|
651
|
Chris@16
|
652 /*!
|
Chris@16
|
653 \brief Remove a range of values from the container.
|
Chris@16
|
654
|
Chris@16
|
655 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
656 it doesn't take iterators pointing to values stored in this container. It removes values equal
|
Chris@16
|
657 to these passed as a range. Furthermore this method removes only one value for each one passed
|
Chris@16
|
658 in the range, not all equal values.
|
Chris@16
|
659
|
Chris@16
|
660 \param first The beginning of the range of values.
|
Chris@16
|
661 \param last The end of the range of values.
|
Chris@16
|
662
|
Chris@16
|
663 \return The number of removed values.
|
Chris@16
|
664
|
Chris@16
|
665 \par Throws
|
Chris@16
|
666 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
667 \li If allocation throws or returns invalid value.
|
Chris@16
|
668
|
Chris@16
|
669 \warning
|
Chris@16
|
670 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
671 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
672 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
673 some of them may return invalid data.
|
Chris@16
|
674 */
|
Chris@16
|
675 template <typename Iterator>
|
Chris@16
|
676 inline size_type remove(Iterator first, Iterator last)
|
Chris@16
|
677 {
|
Chris@16
|
678 size_type result = 0;
|
Chris@16
|
679 for ( ; first != last ; ++first )
|
Chris@16
|
680 result += this->raw_remove(*first);
|
Chris@16
|
681 return result;
|
Chris@16
|
682 }
|
Chris@16
|
683
|
Chris@16
|
684 /*!
|
Chris@101
|
685 \brief Remove value corresponding to an object convertible to it or a range of values from the container.
|
Chris@16
|
686
|
Chris@16
|
687 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
688 it removes values equal to these passed as a range. Furthermore, this method removes only
|
Chris@16
|
689 one value for each one passed in the range, not all equal values.
|
Chris@16
|
690
|
Chris@101
|
691 \param conv_or_rng The object of type convertible to value_type or a range of values.
|
Chris@16
|
692
|
Chris@16
|
693 \return The number of removed values.
|
Chris@16
|
694
|
Chris@16
|
695 \par Throws
|
Chris@16
|
696 \li If Value copy constructor or copy assignment throws.
|
Chris@16
|
697 \li If allocation throws or returns invalid value.
|
Chris@16
|
698
|
Chris@16
|
699 \warning
|
Chris@16
|
700 This operation only guarantees that there will be no memory leaks.
|
Chris@16
|
701 After an exception is thrown the R-tree may be left in an inconsistent state,
|
Chris@16
|
702 elements must not be inserted or removed. Other operations are allowed however
|
Chris@16
|
703 some of them may return invalid data.
|
Chris@16
|
704 */
|
Chris@101
|
705 template <typename ConvertibleOrRange>
|
Chris@101
|
706 inline size_type remove(ConvertibleOrRange const& conv_or_rng)
|
Chris@16
|
707 {
|
Chris@101
|
708 typedef boost::mpl::bool_
|
Chris@101
|
709 <
|
Chris@101
|
710 boost::is_convertible<ConvertibleOrRange, value_type>::value
|
Chris@101
|
711 > is_conv_t;
|
Chris@16
|
712
|
Chris@101
|
713 return this->remove_dispatch(conv_or_rng, is_conv_t());
|
Chris@16
|
714 }
|
Chris@16
|
715
|
Chris@16
|
716 /*!
|
Chris@16
|
717 \brief Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box.
|
Chris@16
|
718
|
Chris@16
|
719 This query function performs spatial and k-nearest neighbor searches. It allows to pass a set of predicates.
|
Chris@16
|
720 Values will be returned only if all predicates are met.
|
Chris@16
|
721
|
Chris@16
|
722 <b>Spatial predicates</b>
|
Chris@16
|
723
|
Chris@16
|
724 Spatial predicates may be generated by one of the functions listed below:
|
Chris@16
|
725 \li \c boost::geometry::index::contains(),
|
Chris@16
|
726 \li \c boost::geometry::index::covered_by(),
|
Chris@16
|
727 \li \c boost::geometry::index::covers(),
|
Chris@16
|
728 \li \c boost::geometry::index::disjoint(),
|
Chris@16
|
729 \li \c boost::geometry::index::intersects(),
|
Chris@16
|
730 \li \c boost::geometry::index::overlaps(),
|
Chris@16
|
731 \li \c boost::geometry::index::within(),
|
Chris@16
|
732
|
Chris@16
|
733 It is possible to negate spatial predicates:
|
Chris@16
|
734 \li <tt>! boost::geometry::index::contains()</tt>,
|
Chris@16
|
735 \li <tt>! boost::geometry::index::covered_by()</tt>,
|
Chris@16
|
736 \li <tt>! boost::geometry::index::covers()</tt>,
|
Chris@16
|
737 \li <tt>! boost::geometry::index::disjoint()</tt>,
|
Chris@16
|
738 \li <tt>! boost::geometry::index::intersects()</tt>,
|
Chris@16
|
739 \li <tt>! boost::geometry::index::overlaps()</tt>,
|
Chris@16
|
740 \li <tt>! boost::geometry::index::within()</tt>
|
Chris@16
|
741
|
Chris@16
|
742 <b>Satisfies predicate</b>
|
Chris@16
|
743
|
Chris@16
|
744 This is a special kind of predicate which allows to pass a user-defined function or function object which checks
|
Chris@16
|
745 if Value should be returned by the query. It's generated by:
|
Chris@16
|
746 \li \c boost::geometry::index::satisfies().
|
Chris@16
|
747
|
Chris@16
|
748 <b>Nearest predicate</b>
|
Chris@16
|
749
|
Chris@16
|
750 If the nearest predicate is passed a k-nearest neighbor search will be performed. This query will result
|
Chris@16
|
751 in returning k values to the output iterator. Only one nearest predicate may be passed to the query.
|
Chris@16
|
752 It may be generated by:
|
Chris@16
|
753 \li \c boost::geometry::index::nearest().
|
Chris@16
|
754
|
Chris@16
|
755 <b>Connecting predicates</b>
|
Chris@16
|
756
|
Chris@16
|
757 Predicates may be passed together connected with \c operator&&().
|
Chris@16
|
758
|
Chris@16
|
759 \par Example
|
Chris@16
|
760 \verbatim
|
Chris@16
|
761 // return elements intersecting box
|
Chris@16
|
762 tree.query(bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
763 // return elements intersecting poly but not within box
|
Chris@16
|
764 tree.query(bgi::intersects(poly) && !bgi::within(box), std::back_inserter(result));
|
Chris@16
|
765 // return elements overlapping box and meeting my_fun unary predicate
|
Chris@16
|
766 tree.query(bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
|
Chris@16
|
767 // return 5 elements nearest to pt and elements are intersecting box
|
Chris@16
|
768 tree.query(bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
769 \endverbatim
|
Chris@16
|
770
|
Chris@16
|
771 \par Throws
|
Chris@16
|
772 If Value copy constructor or copy assignment throws.
|
Chris@16
|
773 If predicates copy throws.
|
Chris@16
|
774
|
Chris@16
|
775 \warning
|
Chris@16
|
776 Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
|
Chris@16
|
777
|
Chris@16
|
778 \param predicates Predicates.
|
Chris@16
|
779 \param out_it The output iterator, e.g. generated by std::back_inserter().
|
Chris@16
|
780
|
Chris@16
|
781 \return The number of values found.
|
Chris@16
|
782 */
|
Chris@16
|
783 template <typename Predicates, typename OutIter>
|
Chris@16
|
784 size_type query(Predicates const& predicates, OutIter out_it) const
|
Chris@16
|
785 {
|
Chris@16
|
786 if ( !m_members.root )
|
Chris@16
|
787 return 0;
|
Chris@16
|
788
|
Chris@16
|
789 static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
|
Chris@16
|
790 static const bool is_distance_predicate = 0 < distance_predicates_count;
|
Chris@16
|
791 BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
|
Chris@16
|
792
|
Chris@16
|
793 return query_dispatch(predicates, out_it, boost::mpl::bool_<is_distance_predicate>());
|
Chris@16
|
794 }
|
Chris@16
|
795
|
Chris@16
|
796 /*!
|
Chris@16
|
797 \brief Returns the query iterator pointing at the begin of the query range.
|
Chris@16
|
798
|
Chris@16
|
799 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
800 about the predicates which may be passed to this method see query().
|
Chris@16
|
801
|
Chris@16
|
802 \par Example
|
Chris@16
|
803 \verbatim
|
Chris@16
|
804 for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
|
Chris@16
|
805 it != tree.qend() ; ++it )
|
Chris@16
|
806 {
|
Chris@16
|
807 // do something with value
|
Chris@16
|
808 if ( has_enough_nearest_values() )
|
Chris@16
|
809 break;
|
Chris@16
|
810 }
|
Chris@16
|
811 \endverbatim
|
Chris@16
|
812
|
Chris@16
|
813 \par Throws
|
Chris@16
|
814 If predicates copy throws.
|
Chris@16
|
815 If allocation throws.
|
Chris@16
|
816
|
Chris@16
|
817 \param predicates Predicates.
|
Chris@16
|
818
|
Chris@16
|
819 \return The iterator pointing at the begin of the query range.
|
Chris@16
|
820 */
|
Chris@16
|
821 template <typename Predicates>
|
Chris@16
|
822 const_query_iterator qbegin(Predicates const& predicates) const
|
Chris@16
|
823 {
|
Chris@16
|
824 return const_query_iterator(qbegin_(predicates));
|
Chris@16
|
825 }
|
Chris@16
|
826
|
Chris@16
|
827 /*!
|
Chris@16
|
828 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
829
|
Chris@16
|
830 This method returns the iterator which may be used to check if the query has ended.
|
Chris@16
|
831
|
Chris@16
|
832 \par Example
|
Chris@16
|
833 \verbatim
|
Chris@16
|
834 for ( Rtree::const_query_iterator it = tree.qbegin(bgi::nearest(pt, 10000)) ;
|
Chris@16
|
835 it != tree.qend() ; ++it )
|
Chris@16
|
836 {
|
Chris@16
|
837 // do something with value
|
Chris@16
|
838 if ( has_enough_nearest_values() )
|
Chris@16
|
839 break;
|
Chris@16
|
840 }
|
Chris@16
|
841 \endverbatim
|
Chris@16
|
842
|
Chris@16
|
843 \par Throws
|
Chris@16
|
844 Nothing
|
Chris@16
|
845
|
Chris@16
|
846 \return The iterator pointing at the end of the query range.
|
Chris@16
|
847 */
|
Chris@16
|
848 const_query_iterator qend() const
|
Chris@16
|
849 {
|
Chris@16
|
850 return const_query_iterator();
|
Chris@16
|
851 }
|
Chris@16
|
852
|
Chris@16
|
853 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
Chris@16
|
854 private:
|
Chris@16
|
855 #endif
|
Chris@16
|
856 /*!
|
Chris@16
|
857 \brief Returns the query iterator pointing at the begin of the query range.
|
Chris@16
|
858
|
Chris@16
|
859 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
860 about the predicates which may be passed to this method see query().
|
Chris@16
|
861
|
Chris@16
|
862 The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
|
Chris@16
|
863 may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
|
Chris@16
|
864 returned by this method you may get the type e.g. by using C++11 decltype or Boost.Typeof library.
|
Chris@16
|
865 This iterator may be compared with iterators returned by both versions of qend() method.
|
Chris@16
|
866
|
Chris@16
|
867 \par Example
|
Chris@16
|
868 \verbatim
|
Chris@16
|
869 // Store the result in the container using std::copy() - it requires both iterators of the same type
|
Chris@16
|
870 std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
|
Chris@16
|
871
|
Chris@16
|
872 // Store the result in the container using std::copy() and type-erased iterators
|
Chris@16
|
873 Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
|
Chris@16
|
874 Rtree::const_query_iterator last = tree.qend();
|
Chris@16
|
875 std::copy(first, last, std::back_inserter(result));
|
Chris@16
|
876
|
Chris@16
|
877 // Boost.Typeof
|
Chris@16
|
878 typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
|
Chris@16
|
879 for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
|
Chris@16
|
880 {
|
Chris@16
|
881 // do something with value
|
Chris@16
|
882 if ( has_enough_nearest_values() )
|
Chris@16
|
883 break;
|
Chris@16
|
884 }
|
Chris@16
|
885 \endverbatim
|
Chris@16
|
886
|
Chris@16
|
887 \par Throws
|
Chris@16
|
888 If predicates copy throws.
|
Chris@16
|
889 If allocation throws.
|
Chris@16
|
890
|
Chris@16
|
891 \param predicates Predicates.
|
Chris@16
|
892
|
Chris@16
|
893 \return The iterator pointing at the begin of the query range.
|
Chris@16
|
894 */
|
Chris@16
|
895 template <typename Predicates>
|
Chris@16
|
896 typename boost::mpl::if_c<
|
Chris@16
|
897 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
898 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
899 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
900 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
901 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
902 >
|
Chris@16
|
903 >::type
|
Chris@16
|
904 qbegin_(Predicates const& predicates) const
|
Chris@16
|
905 {
|
Chris@16
|
906 static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
|
Chris@16
|
907 BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
|
Chris@16
|
908
|
Chris@16
|
909 typedef typename boost::mpl::if_c<
|
Chris@16
|
910 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
911 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
912 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
913 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
914 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
915 >
|
Chris@16
|
916 >::type iterator_type;
|
Chris@16
|
917
|
Chris@16
|
918 if ( !m_members.root )
|
Chris@16
|
919 return iterator_type(m_members.translator(), predicates);
|
Chris@16
|
920
|
Chris@16
|
921 return iterator_type(m_members.root, m_members.translator(), predicates);
|
Chris@16
|
922 }
|
Chris@16
|
923
|
Chris@16
|
924 /*!
|
Chris@16
|
925 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
926
|
Chris@16
|
927 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
928 about the predicates which may be passed to this method see query().
|
Chris@16
|
929
|
Chris@16
|
930 The type of the returned iterator depends on the type of passed Predicates but the iterator of this type
|
Chris@16
|
931 may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator
|
Chris@16
|
932 returned by this method you may get the type e.g. by using C++11 decltype or Boost.Typeof library.
|
Chris@16
|
933
|
Chris@16
|
934 The type of the iterator returned by this method is the same as the one returned by qbegin() to which
|
Chris@16
|
935 the same predicates were passed.
|
Chris@16
|
936
|
Chris@16
|
937 \par Example
|
Chris@16
|
938 \verbatim
|
Chris@16
|
939 // Store the result in the container using std::copy() - it requires both iterators of the same type
|
Chris@16
|
940 std::copy(tree.qbegin(bgi::intersects(box)), tree.qend(bgi::intersects(box)), std::back_inserter(result));
|
Chris@16
|
941 \endverbatim
|
Chris@16
|
942
|
Chris@16
|
943 \par Throws
|
Chris@16
|
944 If predicates copy throws.
|
Chris@16
|
945
|
Chris@16
|
946 \param predicates Predicates.
|
Chris@16
|
947
|
Chris@16
|
948 \return The iterator pointing at the end of the query range.
|
Chris@16
|
949 */
|
Chris@16
|
950 template <typename Predicates>
|
Chris@16
|
951 typename boost::mpl::if_c<
|
Chris@16
|
952 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
953 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
954 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
955 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
956 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
957 >
|
Chris@16
|
958 >::type
|
Chris@16
|
959 qend_(Predicates const& predicates) const
|
Chris@16
|
960 {
|
Chris@16
|
961 static const unsigned distance_predicates_count = detail::predicates_count_distance<Predicates>::value;
|
Chris@16
|
962 BOOST_MPL_ASSERT_MSG((distance_predicates_count <= 1), PASS_ONLY_ONE_DISTANCE_PREDICATE, (Predicates));
|
Chris@16
|
963
|
Chris@16
|
964 typedef typename boost::mpl::if_c<
|
Chris@16
|
965 detail::predicates_count_distance<Predicates>::value == 0,
|
Chris@16
|
966 detail::rtree::iterators::spatial_query_iterator<value_type, options_type, translator_type, box_type, allocators_type, Predicates>,
|
Chris@16
|
967 detail::rtree::iterators::distance_query_iterator<
|
Chris@16
|
968 value_type, options_type, translator_type, box_type, allocators_type, Predicates,
|
Chris@16
|
969 detail::predicates_find_distance<Predicates>::value
|
Chris@16
|
970 >
|
Chris@16
|
971 >::type iterator_type;
|
Chris@16
|
972
|
Chris@16
|
973 return iterator_type(m_members.translator(), predicates);
|
Chris@16
|
974 }
|
Chris@16
|
975
|
Chris@16
|
976 /*!
|
Chris@16
|
977 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
978
|
Chris@16
|
979 This method returns the iterator which may be compared with the iterator returned by qbegin() in order to
|
Chris@16
|
980 check if the query has ended.
|
Chris@16
|
981
|
Chris@16
|
982 The type of the returned iterator is different than the type returned by qbegin() but the iterator of this type
|
Chris@16
|
983 may be assigned to the variable of const_query_iterator type. If you'd like to use the type of the iterator returned by this
|
Chris@16
|
984 method, which most certainly will be faster than the type-erased iterator, you may get the type
|
Chris@16
|
985 e.g. by using C++11 decltype or Boost.Typeof library.
|
Chris@16
|
986
|
Chris@16
|
987 The type of the iterator returned by this method is dfferent than the type returned by qbegin().
|
Chris@16
|
988
|
Chris@16
|
989 \par Example
|
Chris@16
|
990 \verbatim
|
Chris@16
|
991 // Store the result in the container using std::copy() and type-erased iterators
|
Chris@16
|
992 Rtree::const_query_iterator first = tree.qbegin(bgi::intersects(box));
|
Chris@16
|
993 Rtree::const_query_iterator last = tree.qend();
|
Chris@16
|
994 std::copy(first, last, std::back_inserter(result));
|
Chris@16
|
995
|
Chris@16
|
996 // Boost.Typeof
|
Chris@16
|
997 typedef BOOST_TYPEOF(tree.qbegin(bgi::nearest(pt, 10000))) Iter;
|
Chris@16
|
998 for ( Iter it = tree.qbegin(bgi::nearest(pt, 10000)) ; it != tree.qend() ; ++it )
|
Chris@16
|
999 {
|
Chris@16
|
1000 // do something with value
|
Chris@16
|
1001 if ( has_enough_nearest_values() )
|
Chris@16
|
1002 break;
|
Chris@16
|
1003 }
|
Chris@16
|
1004 \endverbatim
|
Chris@16
|
1005
|
Chris@16
|
1006 \par Throws
|
Chris@16
|
1007 Nothing
|
Chris@16
|
1008
|
Chris@16
|
1009 \return The iterator pointing at the end of the query range.
|
Chris@16
|
1010 */
|
Chris@16
|
1011 detail::rtree::iterators::end_query_iterator<value_type, allocators_type>
|
Chris@16
|
1012 qend_() const
|
Chris@16
|
1013 {
|
Chris@16
|
1014 return detail::rtree::iterators::end_query_iterator<value_type, allocators_type>();
|
Chris@16
|
1015 }
|
Chris@16
|
1016
|
Chris@16
|
1017 public:
|
Chris@16
|
1018
|
Chris@16
|
1019 /*!
|
Chris@16
|
1020 \brief Returns the number of stored values.
|
Chris@16
|
1021
|
Chris@16
|
1022 \return The number of stored values.
|
Chris@16
|
1023
|
Chris@16
|
1024 \par Throws
|
Chris@16
|
1025 Nothing.
|
Chris@16
|
1026 */
|
Chris@16
|
1027 inline size_type size() const
|
Chris@16
|
1028 {
|
Chris@16
|
1029 return m_members.values_count;
|
Chris@16
|
1030 }
|
Chris@16
|
1031
|
Chris@16
|
1032 /*!
|
Chris@16
|
1033 \brief Query if the container is empty.
|
Chris@16
|
1034
|
Chris@16
|
1035 \return true if the container is empty.
|
Chris@16
|
1036
|
Chris@16
|
1037 \par Throws
|
Chris@16
|
1038 Nothing.
|
Chris@16
|
1039 */
|
Chris@16
|
1040 inline bool empty() const
|
Chris@16
|
1041 {
|
Chris@16
|
1042 return 0 == m_members.values_count;
|
Chris@16
|
1043 }
|
Chris@16
|
1044
|
Chris@16
|
1045 /*!
|
Chris@16
|
1046 \brief Removes all values stored in the container.
|
Chris@16
|
1047
|
Chris@16
|
1048 \par Throws
|
Chris@16
|
1049 Nothing.
|
Chris@16
|
1050 */
|
Chris@16
|
1051 inline void clear()
|
Chris@16
|
1052 {
|
Chris@16
|
1053 this->raw_destroy(*this);
|
Chris@16
|
1054 }
|
Chris@16
|
1055
|
Chris@16
|
1056 /*!
|
Chris@16
|
1057 \brief Returns the box able to contain all values stored in the container.
|
Chris@16
|
1058
|
Chris@16
|
1059 Returns the box able to contain all values stored in the container.
|
Chris@16
|
1060 If the container is empty the result of \c geometry::assign_inverse() is returned.
|
Chris@16
|
1061
|
Chris@16
|
1062 \return The box able to contain all values stored in the container or an invalid box if
|
Chris@16
|
1063 there are no values in the container.
|
Chris@16
|
1064
|
Chris@16
|
1065 \par Throws
|
Chris@16
|
1066 Nothing.
|
Chris@16
|
1067 */
|
Chris@16
|
1068 inline bounds_type bounds() const
|
Chris@16
|
1069 {
|
Chris@16
|
1070 bounds_type result;
|
Chris@16
|
1071 if ( !m_members.root )
|
Chris@16
|
1072 {
|
Chris@16
|
1073 geometry::assign_inverse(result);
|
Chris@16
|
1074 return result;
|
Chris@16
|
1075 }
|
Chris@16
|
1076
|
Chris@16
|
1077 detail::rtree::visitors::children_box<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1078 box_v(result, m_members.translator());
|
Chris@16
|
1079 detail::rtree::apply_visitor(box_v, *m_members.root);
|
Chris@16
|
1080
|
Chris@16
|
1081 return result;
|
Chris@16
|
1082 }
|
Chris@16
|
1083
|
Chris@16
|
1084 /*!
|
Chris@16
|
1085 \brief Count Values or Indexables stored in the container.
|
Chris@16
|
1086
|
Chris@16
|
1087 For indexable_type it returns the number of values which indexables equals the parameter.
|
Chris@16
|
1088 For value_type it returns the number of values which equals the parameter.
|
Chris@16
|
1089
|
Chris@16
|
1090 \param vori The value or indexable which will be counted.
|
Chris@16
|
1091
|
Chris@16
|
1092 \return The number of values found.
|
Chris@16
|
1093
|
Chris@16
|
1094 \par Throws
|
Chris@16
|
1095 Nothing.
|
Chris@16
|
1096 */
|
Chris@16
|
1097 template <typename ValueOrIndexable>
|
Chris@16
|
1098 size_type count(ValueOrIndexable const& vori) const
|
Chris@16
|
1099 {
|
Chris@101
|
1100 // the input should be convertible to Value or Indexable type
|
Chris@16
|
1101
|
Chris@101
|
1102 enum { as_val = 0, as_ind, dont_know };
|
Chris@101
|
1103 typedef boost::mpl::int_
|
Chris@101
|
1104 <
|
Chris@101
|
1105 boost::is_same<ValueOrIndexable, value_type>::value ?
|
Chris@101
|
1106 as_val :
|
Chris@101
|
1107 boost::is_same<ValueOrIndexable, indexable_type>::value ?
|
Chris@101
|
1108 as_ind :
|
Chris@101
|
1109 boost::is_convertible<ValueOrIndexable, indexable_type>::value ?
|
Chris@101
|
1110 as_ind :
|
Chris@101
|
1111 boost::is_convertible<ValueOrIndexable, value_type>::value ?
|
Chris@101
|
1112 as_val :
|
Chris@101
|
1113 dont_know
|
Chris@101
|
1114 > variant;
|
Chris@16
|
1115
|
Chris@101
|
1116 BOOST_MPL_ASSERT_MSG((variant::value != dont_know),
|
Chris@101
|
1117 PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE,
|
Chris@101
|
1118 (ValueOrIndexable));
|
Chris@16
|
1119
|
Chris@101
|
1120 typedef typename boost::mpl::if_c
|
Chris@101
|
1121 <
|
Chris@101
|
1122 variant::value == as_val,
|
Chris@101
|
1123 value_type,
|
Chris@101
|
1124 indexable_type
|
Chris@101
|
1125 >::type value_or_indexable;
|
Chris@101
|
1126
|
Chris@101
|
1127 // NOTE: If an object of convertible but not the same type is passed
|
Chris@101
|
1128 // into the function, here a temporary will be created.
|
Chris@101
|
1129 return this->template raw_count<value_or_indexable>(vori);
|
Chris@16
|
1130 }
|
Chris@16
|
1131
|
Chris@16
|
1132 /*!
|
Chris@16
|
1133 \brief Returns parameters.
|
Chris@16
|
1134
|
Chris@16
|
1135 \return The parameters object.
|
Chris@16
|
1136
|
Chris@16
|
1137 \par Throws
|
Chris@16
|
1138 Nothing.
|
Chris@16
|
1139 */
|
Chris@16
|
1140 inline parameters_type parameters() const
|
Chris@16
|
1141 {
|
Chris@16
|
1142 return m_members.parameters();
|
Chris@16
|
1143 }
|
Chris@16
|
1144
|
Chris@16
|
1145 /*!
|
Chris@16
|
1146 \brief Returns function retrieving Indexable from Value.
|
Chris@16
|
1147
|
Chris@16
|
1148 \return The indexable_getter object.
|
Chris@16
|
1149
|
Chris@16
|
1150 \par Throws
|
Chris@16
|
1151 Nothing.
|
Chris@16
|
1152 */
|
Chris@16
|
1153 indexable_getter indexable_get() const
|
Chris@16
|
1154 {
|
Chris@16
|
1155 return m_members.indexable_getter();
|
Chris@16
|
1156 }
|
Chris@16
|
1157
|
Chris@16
|
1158 /*!
|
Chris@16
|
1159 \brief Returns function comparing Values
|
Chris@16
|
1160
|
Chris@16
|
1161 \return The value_equal function.
|
Chris@16
|
1162
|
Chris@16
|
1163 \par Throws
|
Chris@16
|
1164 Nothing.
|
Chris@16
|
1165 */
|
Chris@16
|
1166 value_equal value_eq() const
|
Chris@16
|
1167 {
|
Chris@16
|
1168 return m_members.equal_to();
|
Chris@16
|
1169 }
|
Chris@16
|
1170
|
Chris@16
|
1171 /*!
|
Chris@16
|
1172 \brief Returns allocator used by the rtree.
|
Chris@16
|
1173
|
Chris@16
|
1174 \return The allocator.
|
Chris@16
|
1175
|
Chris@16
|
1176 \par Throws
|
Chris@16
|
1177 If allocator copy constructor throws.
|
Chris@16
|
1178 */
|
Chris@16
|
1179 allocator_type get_allocator() const
|
Chris@16
|
1180 {
|
Chris@16
|
1181 return m_members.allocators().allocator();
|
Chris@16
|
1182 }
|
Chris@16
|
1183
|
Chris@16
|
1184 private:
|
Chris@16
|
1185
|
Chris@16
|
1186 /*!
|
Chris@16
|
1187 \brief Returns the translator object.
|
Chris@16
|
1188
|
Chris@16
|
1189 \return The translator object.
|
Chris@16
|
1190
|
Chris@16
|
1191 \par Throws
|
Chris@16
|
1192 Nothing.
|
Chris@16
|
1193 */
|
Chris@16
|
1194 inline translator_type translator() const
|
Chris@16
|
1195 {
|
Chris@16
|
1196 return m_members.translator();
|
Chris@16
|
1197 }
|
Chris@16
|
1198
|
Chris@16
|
1199 /*!
|
Chris@16
|
1200 \brief Apply a visitor to the nodes structure in order to perform some operator.
|
Chris@16
|
1201
|
Chris@16
|
1202 This function is not a part of the 'official' interface. However it makes
|
Chris@16
|
1203 possible e.g. to pass a visitor drawing the tree structure.
|
Chris@16
|
1204
|
Chris@16
|
1205 \param visitor The visitor object.
|
Chris@16
|
1206
|
Chris@16
|
1207 \par Throws
|
Chris@16
|
1208 If Visitor::operator() throws.
|
Chris@16
|
1209 */
|
Chris@16
|
1210 template <typename Visitor>
|
Chris@16
|
1211 inline void apply_visitor(Visitor & visitor) const
|
Chris@16
|
1212 {
|
Chris@16
|
1213 if ( m_members.root )
|
Chris@16
|
1214 detail::rtree::apply_visitor(visitor, *m_members.root);
|
Chris@16
|
1215 }
|
Chris@16
|
1216
|
Chris@16
|
1217 /*!
|
Chris@16
|
1218 \brief Returns the depth of the R-tree.
|
Chris@16
|
1219
|
Chris@16
|
1220 This function is not a part of the 'official' interface.
|
Chris@16
|
1221
|
Chris@16
|
1222 \return The depth of the R-tree.
|
Chris@16
|
1223
|
Chris@16
|
1224 \par Throws
|
Chris@16
|
1225 Nothing.
|
Chris@16
|
1226 */
|
Chris@16
|
1227 inline size_type depth() const
|
Chris@16
|
1228 {
|
Chris@16
|
1229 return m_members.leafs_level;
|
Chris@16
|
1230 }
|
Chris@16
|
1231
|
Chris@16
|
1232 private:
|
Chris@16
|
1233
|
Chris@16
|
1234 /*!
|
Chris@16
|
1235 \pre Root node must exist - m_root != 0.
|
Chris@16
|
1236
|
Chris@16
|
1237 \brief Insert a value to the index.
|
Chris@16
|
1238
|
Chris@16
|
1239 \param value The value which will be stored in the container.
|
Chris@16
|
1240
|
Chris@16
|
1241 \par Exception-safety
|
Chris@16
|
1242 basic
|
Chris@16
|
1243 */
|
Chris@16
|
1244 inline void raw_insert(value_type const& value)
|
Chris@16
|
1245 {
|
Chris@16
|
1246 BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
|
Chris@101
|
1247 // CONSIDER: alternative - ignore invalid indexable or throw an exception
|
Chris@16
|
1248 BOOST_GEOMETRY_INDEX_ASSERT(detail::is_valid(m_members.translator()(value)), "Indexable is invalid");
|
Chris@16
|
1249
|
Chris@16
|
1250 detail::rtree::visitors::insert<
|
Chris@16
|
1251 value_type,
|
Chris@16
|
1252 value_type, options_type, translator_type, box_type, allocators_type,
|
Chris@16
|
1253 typename options_type::insert_tag
|
Chris@16
|
1254 > insert_v(m_members.root, m_members.leafs_level, value,
|
Chris@16
|
1255 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
1256
|
Chris@16
|
1257 detail::rtree::apply_visitor(insert_v, *m_members.root);
|
Chris@16
|
1258
|
Chris@16
|
1259 // TODO
|
Chris@16
|
1260 // Think about this: If exception is thrown, may the root be removed?
|
Chris@16
|
1261 // Or it is just cleared?
|
Chris@16
|
1262
|
Chris@16
|
1263 // TODO
|
Chris@16
|
1264 // If exception is thrown, m_values_count may be invalid
|
Chris@16
|
1265 ++m_members.values_count;
|
Chris@16
|
1266 }
|
Chris@16
|
1267
|
Chris@16
|
1268 /*!
|
Chris@16
|
1269 \brief Remove the value from the container.
|
Chris@16
|
1270
|
Chris@16
|
1271 \param value The value which will be removed from the container.
|
Chris@16
|
1272
|
Chris@16
|
1273 \par Exception-safety
|
Chris@16
|
1274 basic
|
Chris@16
|
1275 */
|
Chris@16
|
1276 inline size_type raw_remove(value_type const& value)
|
Chris@16
|
1277 {
|
Chris@16
|
1278 // TODO: awulkiew - assert for correct value (indexable) ?
|
Chris@16
|
1279 BOOST_GEOMETRY_INDEX_ASSERT(m_members.root, "The root must exist");
|
Chris@16
|
1280
|
Chris@16
|
1281 detail::rtree::visitors::remove<
|
Chris@16
|
1282 value_type, options_type, translator_type, box_type, allocators_type
|
Chris@16
|
1283 > remove_v(m_members.root, m_members.leafs_level, value,
|
Chris@16
|
1284 m_members.parameters(), m_members.translator(), m_members.allocators());
|
Chris@16
|
1285
|
Chris@16
|
1286 detail::rtree::apply_visitor(remove_v, *m_members.root);
|
Chris@16
|
1287
|
Chris@16
|
1288 // If exception is thrown, m_values_count may be invalid
|
Chris@16
|
1289
|
Chris@16
|
1290 if ( remove_v.is_value_removed() )
|
Chris@16
|
1291 {
|
Chris@16
|
1292 BOOST_GEOMETRY_INDEX_ASSERT(0 < m_members.values_count, "unexpected state");
|
Chris@16
|
1293
|
Chris@16
|
1294 --m_members.values_count;
|
Chris@16
|
1295
|
Chris@16
|
1296 return 1;
|
Chris@16
|
1297 }
|
Chris@16
|
1298
|
Chris@16
|
1299 return 0;
|
Chris@16
|
1300 }
|
Chris@16
|
1301
|
Chris@16
|
1302 /*!
|
Chris@16
|
1303 \brief Create an empty R-tree i.e. new empty root node and clear other attributes.
|
Chris@16
|
1304
|
Chris@16
|
1305 \par Exception-safety
|
Chris@16
|
1306 strong
|
Chris@16
|
1307 */
|
Chris@16
|
1308 inline void raw_create()
|
Chris@16
|
1309 {
|
Chris@16
|
1310 BOOST_GEOMETRY_INDEX_ASSERT(0 == m_members.root, "the tree is already created");
|
Chris@16
|
1311
|
Chris@16
|
1312 m_members.root = detail::rtree::create_node<allocators_type, leaf>::apply(m_members.allocators()); // MAY THROW (N: alloc)
|
Chris@16
|
1313 m_members.values_count = 0;
|
Chris@16
|
1314 m_members.leafs_level = 0;
|
Chris@16
|
1315 }
|
Chris@16
|
1316
|
Chris@16
|
1317 /*!
|
Chris@16
|
1318 \brief Destroy the R-tree i.e. all nodes and clear attributes.
|
Chris@16
|
1319
|
Chris@16
|
1320 \param t The container which is going to be destroyed.
|
Chris@16
|
1321
|
Chris@16
|
1322 \par Exception-safety
|
Chris@16
|
1323 nothrow
|
Chris@16
|
1324 */
|
Chris@16
|
1325 inline void raw_destroy(rtree & t)
|
Chris@16
|
1326 {
|
Chris@16
|
1327 if ( t.m_members.root )
|
Chris@16
|
1328 {
|
Chris@16
|
1329 detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1330 del_v(t.m_members.root, t.m_members.allocators());
|
Chris@16
|
1331 detail::rtree::apply_visitor(del_v, *t.m_members.root);
|
Chris@16
|
1332
|
Chris@16
|
1333 t.m_members.root = 0;
|
Chris@16
|
1334 }
|
Chris@16
|
1335 t.m_members.values_count = 0;
|
Chris@16
|
1336 t.m_members.leafs_level = 0;
|
Chris@16
|
1337 }
|
Chris@16
|
1338
|
Chris@16
|
1339 /*!
|
Chris@16
|
1340 \brief Copy the R-tree i.e. whole nodes structure, values and other attributes.
|
Chris@16
|
1341 It uses destination's allocators to create the new structure.
|
Chris@16
|
1342
|
Chris@16
|
1343 \param src The source R-tree.
|
Chris@16
|
1344 \param dst The destination R-tree.
|
Chris@16
|
1345 \param copy_tr_and_params If true, translator and parameters will also be copied.
|
Chris@16
|
1346
|
Chris@16
|
1347 \par Exception-safety
|
Chris@16
|
1348 strong
|
Chris@16
|
1349 */
|
Chris@16
|
1350 inline void raw_copy(rtree const& src, rtree & dst, bool copy_tr_and_params) const
|
Chris@16
|
1351 {
|
Chris@16
|
1352 detail::rtree::visitors::copy<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1353 copy_v(dst.m_members.allocators());
|
Chris@16
|
1354
|
Chris@16
|
1355 if ( src.m_members.root )
|
Chris@16
|
1356 detail::rtree::apply_visitor(copy_v, *src.m_members.root); // MAY THROW (V, E: alloc, copy, N: alloc)
|
Chris@16
|
1357
|
Chris@16
|
1358 if ( copy_tr_and_params )
|
Chris@16
|
1359 {
|
Chris@16
|
1360 dst.m_members.indexable_getter() = src.m_members.indexable_getter();
|
Chris@16
|
1361 dst.m_members.equal_to() = src.m_members.equal_to();
|
Chris@16
|
1362 dst.m_members.parameters() = src.m_members.parameters();
|
Chris@16
|
1363 }
|
Chris@16
|
1364
|
Chris@101
|
1365 // TODO use subtree_destroyer
|
Chris@16
|
1366 if ( dst.m_members.root )
|
Chris@16
|
1367 {
|
Chris@16
|
1368 detail::rtree::visitors::destroy<value_type, options_type, translator_type, box_type, allocators_type>
|
Chris@16
|
1369 del_v(dst.m_members.root, dst.m_members.allocators());
|
Chris@16
|
1370 detail::rtree::apply_visitor(del_v, *dst.m_members.root);
|
Chris@16
|
1371 dst.m_members.root = 0;
|
Chris@16
|
1372 }
|
Chris@16
|
1373
|
Chris@16
|
1374 dst.m_members.root = copy_v.result;
|
Chris@16
|
1375 dst.m_members.values_count = src.m_members.values_count;
|
Chris@16
|
1376 dst.m_members.leafs_level = src.m_members.leafs_level;
|
Chris@16
|
1377 }
|
Chris@16
|
1378
|
Chris@16
|
1379 /*!
|
Chris@101
|
1380 \brief Insert a value corresponding to convertible object into the index.
|
Chris@101
|
1381
|
Chris@101
|
1382 \param val_conv The object convertible to value.
|
Chris@101
|
1383
|
Chris@101
|
1384 \par Exception-safety
|
Chris@101
|
1385 basic
|
Chris@101
|
1386 */
|
Chris@101
|
1387 template <typename ValueConvertible>
|
Chris@101
|
1388 inline void insert_dispatch(ValueConvertible const& val_conv,
|
Chris@101
|
1389 boost::mpl::bool_<true> const& /*is_convertible*/)
|
Chris@101
|
1390 {
|
Chris@101
|
1391 if ( !m_members.root )
|
Chris@101
|
1392 this->raw_create();
|
Chris@101
|
1393
|
Chris@101
|
1394 this->raw_insert(val_conv);
|
Chris@101
|
1395 }
|
Chris@101
|
1396
|
Chris@101
|
1397 /*!
|
Chris@101
|
1398 \brief Insert a range of values into the index.
|
Chris@101
|
1399
|
Chris@101
|
1400 \param rng The range of values.
|
Chris@101
|
1401
|
Chris@101
|
1402 \par Exception-safety
|
Chris@101
|
1403 basic
|
Chris@101
|
1404 */
|
Chris@101
|
1405 template <typename Range>
|
Chris@101
|
1406 inline void insert_dispatch(Range const& rng,
|
Chris@101
|
1407 boost::mpl::bool_<false> const& /*is_convertible*/)
|
Chris@101
|
1408 {
|
Chris@101
|
1409 BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
|
Chris@101
|
1410 PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
|
Chris@101
|
1411 (Range));
|
Chris@101
|
1412
|
Chris@101
|
1413 if ( !m_members.root )
|
Chris@101
|
1414 this->raw_create();
|
Chris@101
|
1415
|
Chris@101
|
1416 typedef typename boost::range_const_iterator<Range>::type It;
|
Chris@101
|
1417 for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
|
Chris@101
|
1418 this->raw_insert(*it);
|
Chris@101
|
1419 }
|
Chris@101
|
1420
|
Chris@101
|
1421 /*!
|
Chris@101
|
1422 \brief Remove a value corresponding to convertible object from the index.
|
Chris@101
|
1423
|
Chris@101
|
1424 \param val_conv The object convertible to value.
|
Chris@101
|
1425
|
Chris@101
|
1426 \par Exception-safety
|
Chris@101
|
1427 basic
|
Chris@101
|
1428 */
|
Chris@101
|
1429 template <typename ValueConvertible>
|
Chris@101
|
1430 inline size_type remove_dispatch(ValueConvertible const& val_conv,
|
Chris@101
|
1431 boost::mpl::bool_<true> const& /*is_convertible*/)
|
Chris@101
|
1432 {
|
Chris@101
|
1433 return this->raw_remove(val_conv);
|
Chris@101
|
1434 }
|
Chris@101
|
1435
|
Chris@101
|
1436 /*!
|
Chris@101
|
1437 \brief Remove a range of values from the index.
|
Chris@101
|
1438
|
Chris@101
|
1439 \param rng The range of values which will be removed from the container.
|
Chris@101
|
1440
|
Chris@101
|
1441 \par Exception-safety
|
Chris@101
|
1442 basic
|
Chris@101
|
1443 */
|
Chris@101
|
1444 template <typename Range>
|
Chris@101
|
1445 inline size_type remove_dispatch(Range const& rng,
|
Chris@101
|
1446 boost::mpl::bool_<false> const& /*is_convertible*/)
|
Chris@101
|
1447 {
|
Chris@101
|
1448 BOOST_MPL_ASSERT_MSG((detail::is_range<Range>::value),
|
Chris@101
|
1449 PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE,
|
Chris@101
|
1450 (Range));
|
Chris@101
|
1451
|
Chris@101
|
1452 size_type result = 0;
|
Chris@101
|
1453 typedef typename boost::range_const_iterator<Range>::type It;
|
Chris@101
|
1454 for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it )
|
Chris@101
|
1455 result += this->raw_remove(*it);
|
Chris@101
|
1456 return result;
|
Chris@101
|
1457 }
|
Chris@101
|
1458
|
Chris@101
|
1459 /*!
|
Chris@16
|
1460 \brief Return values meeting predicates.
|
Chris@16
|
1461
|
Chris@16
|
1462 \par Exception-safety
|
Chris@16
|
1463 strong
|
Chris@16
|
1464 */
|
Chris@16
|
1465 template <typename Predicates, typename OutIter>
|
Chris@16
|
1466 size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> const& /*is_distance_predicate*/) const
|
Chris@16
|
1467 {
|
Chris@16
|
1468 detail::rtree::visitors::spatial_query<value_type, options_type, translator_type, box_type, allocators_type, Predicates, OutIter>
|
Chris@16
|
1469 find_v(m_members.translator(), predicates, out_it);
|
Chris@16
|
1470
|
Chris@16
|
1471 detail::rtree::apply_visitor(find_v, *m_members.root);
|
Chris@16
|
1472
|
Chris@16
|
1473 return find_v.found_count;
|
Chris@16
|
1474 }
|
Chris@16
|
1475
|
Chris@16
|
1476 /*!
|
Chris@16
|
1477 \brief Perform nearest neighbour search.
|
Chris@16
|
1478
|
Chris@16
|
1479 \par Exception-safety
|
Chris@16
|
1480 strong
|
Chris@16
|
1481 */
|
Chris@16
|
1482 template <typename Predicates, typename OutIter>
|
Chris@16
|
1483 size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_distance_predicate*/) const
|
Chris@16
|
1484 {
|
Chris@16
|
1485 static const unsigned distance_predicate_index = detail::predicates_find_distance<Predicates>::value;
|
Chris@16
|
1486 detail::rtree::visitors::distance_query<
|
Chris@16
|
1487 value_type,
|
Chris@16
|
1488 options_type,
|
Chris@16
|
1489 translator_type,
|
Chris@16
|
1490 box_type,
|
Chris@16
|
1491 allocators_type,
|
Chris@16
|
1492 Predicates,
|
Chris@16
|
1493 distance_predicate_index,
|
Chris@16
|
1494 OutIter
|
Chris@16
|
1495 > distance_v(m_members.parameters(), m_members.translator(), predicates, out_it);
|
Chris@16
|
1496
|
Chris@16
|
1497 detail::rtree::apply_visitor(distance_v, *m_members.root);
|
Chris@16
|
1498
|
Chris@16
|
1499 return distance_v.finish();
|
Chris@16
|
1500 }
|
Chris@101
|
1501
|
Chris@101
|
1502 /*!
|
Chris@101
|
1503 \brief Count elements corresponding to value or indexable.
|
Chris@101
|
1504
|
Chris@101
|
1505 \par Exception-safety
|
Chris@101
|
1506 strong
|
Chris@101
|
1507 */
|
Chris@101
|
1508 template <typename ValueOrIndexable>
|
Chris@101
|
1509 size_type raw_count(ValueOrIndexable const& vori) const
|
Chris@101
|
1510 {
|
Chris@101
|
1511 if ( !m_members.root )
|
Chris@101
|
1512 return 0;
|
Chris@101
|
1513
|
Chris@101
|
1514 detail::rtree::visitors::count
|
Chris@101
|
1515 <
|
Chris@101
|
1516 ValueOrIndexable,
|
Chris@101
|
1517 value_type,
|
Chris@101
|
1518 options_type,
|
Chris@101
|
1519 translator_type,
|
Chris@101
|
1520 box_type,
|
Chris@101
|
1521 allocators_type
|
Chris@101
|
1522 > count_v(vori, m_members.translator());
|
Chris@101
|
1523
|
Chris@101
|
1524 detail::rtree::apply_visitor(count_v, *m_members.root);
|
Chris@101
|
1525
|
Chris@101
|
1526 return count_v.found_count;
|
Chris@101
|
1527 }
|
Chris@16
|
1528
|
Chris@16
|
1529 struct members_holder
|
Chris@16
|
1530 : public translator_type
|
Chris@16
|
1531 , public Parameters
|
Chris@16
|
1532 , public allocators_type
|
Chris@16
|
1533 {
|
Chris@16
|
1534 private:
|
Chris@16
|
1535 members_holder(members_holder const&);
|
Chris@16
|
1536 members_holder & operator=(members_holder const&);
|
Chris@16
|
1537
|
Chris@16
|
1538 public:
|
Chris@16
|
1539 template <typename IndGet, typename ValEq, typename Alloc>
|
Chris@16
|
1540 members_holder(IndGet const& ind_get,
|
Chris@16
|
1541 ValEq const& val_eq,
|
Chris@16
|
1542 Parameters const& parameters,
|
Chris@16
|
1543 BOOST_FWD_REF(Alloc) alloc)
|
Chris@16
|
1544 : translator_type(ind_get, val_eq)
|
Chris@16
|
1545 , Parameters(parameters)
|
Chris@16
|
1546 , allocators_type(boost::forward<Alloc>(alloc))
|
Chris@16
|
1547 , values_count(0)
|
Chris@16
|
1548 , leafs_level(0)
|
Chris@16
|
1549 , root(0)
|
Chris@16
|
1550 {}
|
Chris@16
|
1551
|
Chris@16
|
1552 template <typename IndGet, typename ValEq>
|
Chris@16
|
1553 members_holder(IndGet const& ind_get,
|
Chris@16
|
1554 ValEq const& val_eq,
|
Chris@16
|
1555 Parameters const& parameters)
|
Chris@16
|
1556 : translator_type(ind_get, val_eq)
|
Chris@16
|
1557 , Parameters(parameters)
|
Chris@16
|
1558 , allocators_type()
|
Chris@16
|
1559 , values_count(0)
|
Chris@16
|
1560 , leafs_level(0)
|
Chris@16
|
1561 , root(0)
|
Chris@16
|
1562 {}
|
Chris@16
|
1563
|
Chris@16
|
1564 translator_type const& translator() const { return *this; }
|
Chris@16
|
1565
|
Chris@16
|
1566 IndexableGetter const& indexable_getter() const { return *this; }
|
Chris@16
|
1567 IndexableGetter & indexable_getter() { return *this; }
|
Chris@16
|
1568 EqualTo const& equal_to() const { return *this; }
|
Chris@16
|
1569 EqualTo & equal_to() { return *this; }
|
Chris@16
|
1570 Parameters const& parameters() const { return *this; }
|
Chris@16
|
1571 Parameters & parameters() { return *this; }
|
Chris@16
|
1572 allocators_type const& allocators() const { return *this; }
|
Chris@16
|
1573 allocators_type & allocators() { return *this; }
|
Chris@16
|
1574
|
Chris@16
|
1575 size_type values_count;
|
Chris@16
|
1576 size_type leafs_level;
|
Chris@16
|
1577 node_pointer root;
|
Chris@16
|
1578 };
|
Chris@16
|
1579
|
Chris@16
|
1580 members_holder m_members;
|
Chris@16
|
1581 };
|
Chris@16
|
1582
|
Chris@16
|
1583 /*!
|
Chris@16
|
1584 \brief Insert a value to the index.
|
Chris@16
|
1585
|
Chris@16
|
1586 It calls <tt>rtree::insert(value_type const&)</tt>.
|
Chris@16
|
1587
|
Chris@16
|
1588 \ingroup rtree_functions
|
Chris@16
|
1589
|
Chris@16
|
1590 \param tree The spatial index.
|
Chris@16
|
1591 \param v The value which will be stored in the index.
|
Chris@16
|
1592 */
|
Chris@16
|
1593 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@101
|
1594 inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
|
Chris@101
|
1595 Value const& v)
|
Chris@16
|
1596 {
|
Chris@16
|
1597 tree.insert(v);
|
Chris@16
|
1598 }
|
Chris@16
|
1599
|
Chris@16
|
1600 /*!
|
Chris@16
|
1601 \brief Insert a range of values to the index.
|
Chris@16
|
1602
|
Chris@16
|
1603 It calls <tt>rtree::insert(Iterator, Iterator)</tt>.
|
Chris@16
|
1604
|
Chris@16
|
1605 \ingroup rtree_functions
|
Chris@16
|
1606
|
Chris@16
|
1607 \param tree The spatial index.
|
Chris@16
|
1608 \param first The beginning of the range of values.
|
Chris@16
|
1609 \param last The end of the range of values.
|
Chris@16
|
1610 */
|
Chris@101
|
1611 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@101
|
1612 typename Iterator>
|
Chris@101
|
1613 inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
|
Chris@101
|
1614 Iterator first, Iterator last)
|
Chris@16
|
1615 {
|
Chris@16
|
1616 tree.insert(first, last);
|
Chris@16
|
1617 }
|
Chris@16
|
1618
|
Chris@16
|
1619 /*!
|
Chris@101
|
1620 \brief Insert a value created using convertible object or a range of values to the index.
|
Chris@16
|
1621
|
Chris@101
|
1622 It calls <tt>rtree::insert(ConvertibleOrRange const&)</tt>.
|
Chris@16
|
1623
|
Chris@16
|
1624 \ingroup rtree_functions
|
Chris@16
|
1625
|
Chris@101
|
1626 \param tree The spatial index.
|
Chris@101
|
1627 \param conv_or_rng The object of type convertible to value_type or a range of values.
|
Chris@16
|
1628 */
|
Chris@101
|
1629 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@101
|
1630 typename ConvertibleOrRange>
|
Chris@101
|
1631 inline void insert(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
|
Chris@101
|
1632 ConvertibleOrRange const& conv_or_rng)
|
Chris@16
|
1633 {
|
Chris@101
|
1634 tree.insert(conv_or_rng);
|
Chris@16
|
1635 }
|
Chris@16
|
1636
|
Chris@16
|
1637 /*!
|
Chris@16
|
1638 \brief Remove a value from the container.
|
Chris@16
|
1639
|
Chris@16
|
1640 Remove a value from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
1641 this function removes only one value from the container.
|
Chris@16
|
1642
|
Chris@16
|
1643 It calls <tt>rtree::remove(value_type const&)</tt>.
|
Chris@16
|
1644
|
Chris@16
|
1645 \ingroup rtree_functions
|
Chris@16
|
1646
|
Chris@16
|
1647 \param tree The spatial index.
|
Chris@16
|
1648 \param v The value which will be removed from the index.
|
Chris@16
|
1649
|
Chris@16
|
1650 \return 1 if value was removed, 0 otherwise.
|
Chris@16
|
1651 */
|
Chris@16
|
1652 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1653 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@101
|
1654 remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
|
Chris@101
|
1655 Value const& v)
|
Chris@16
|
1656 {
|
Chris@16
|
1657 return tree.remove(v);
|
Chris@16
|
1658 }
|
Chris@16
|
1659
|
Chris@16
|
1660 /*!
|
Chris@16
|
1661 \brief Remove a range of values from the container.
|
Chris@16
|
1662
|
Chris@16
|
1663 Remove a range of values from the container. In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
1664 it doesn't take iterators pointing to values stored in this container. It removes values equal
|
Chris@16
|
1665 to these passed as a range. Furthermore this function removes only one value for each one passed
|
Chris@16
|
1666 in the range, not all equal values.
|
Chris@16
|
1667
|
Chris@16
|
1668 It calls <tt>rtree::remove(Iterator, Iterator)</tt>.
|
Chris@16
|
1669
|
Chris@16
|
1670 \ingroup rtree_functions
|
Chris@16
|
1671
|
Chris@16
|
1672 \param tree The spatial index.
|
Chris@16
|
1673 \param first The beginning of the range of values.
|
Chris@16
|
1674 \param last The end of the range of values.
|
Chris@16
|
1675
|
Chris@16
|
1676 \return The number of removed values.
|
Chris@16
|
1677 */
|
Chris@101
|
1678 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@101
|
1679 typename Iterator>
|
Chris@16
|
1680 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@101
|
1681 remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
|
Chris@101
|
1682 Iterator first, Iterator last)
|
Chris@16
|
1683 {
|
Chris@16
|
1684 return tree.remove(first, last);
|
Chris@16
|
1685 }
|
Chris@16
|
1686
|
Chris@16
|
1687 /*!
|
Chris@101
|
1688 \brief Remove a value corresponding to an object convertible to it or a range of values from the container.
|
Chris@16
|
1689
|
Chris@101
|
1690 Remove a value corresponding to an object convertible to it or a range of values from the container.
|
Chris@101
|
1691 In contrast to the \c std::set or <tt>std::map erase()</tt> method
|
Chris@16
|
1692 it removes values equal to these passed as a range. Furthermore this method removes only
|
Chris@16
|
1693 one value for each one passed in the range, not all equal values.
|
Chris@16
|
1694
|
Chris@101
|
1695 It calls <tt>rtree::remove(ConvertibleOrRange const&)</tt>.
|
Chris@16
|
1696
|
Chris@16
|
1697 \ingroup rtree_functions
|
Chris@16
|
1698
|
Chris@101
|
1699 \param tree The spatial index.
|
Chris@101
|
1700 \param conv_or_rng The object of type convertible to value_type or the range of values.
|
Chris@16
|
1701
|
Chris@16
|
1702 \return The number of removed values.
|
Chris@16
|
1703 */
|
Chris@101
|
1704 template<typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@101
|
1705 typename ConvertibleOrRange>
|
Chris@16
|
1706 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@101
|
1707 remove(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree,
|
Chris@101
|
1708 ConvertibleOrRange const& conv_or_rng)
|
Chris@16
|
1709 {
|
Chris@101
|
1710 return tree.remove(conv_or_rng);
|
Chris@16
|
1711 }
|
Chris@16
|
1712
|
Chris@16
|
1713 /*!
|
Chris@16
|
1714 \brief Finds values meeting passed predicates e.g. nearest to some Point and/or intersecting some Box.
|
Chris@16
|
1715
|
Chris@16
|
1716 This query function performs spatial and k-nearest neighbor searches. It allows to pass a set of predicates.
|
Chris@16
|
1717 Values will be returned only if all predicates are met.
|
Chris@16
|
1718
|
Chris@16
|
1719 <b>Spatial predicates</b>
|
Chris@16
|
1720
|
Chris@16
|
1721 Spatial predicates may be generated by one of the functions listed below:
|
Chris@16
|
1722 \li \c boost::geometry::index::contains(),
|
Chris@16
|
1723 \li \c boost::geometry::index::covered_by(),
|
Chris@16
|
1724 \li \c boost::geometry::index::covers(),
|
Chris@16
|
1725 \li \c boost::geometry::index::disjoint(),
|
Chris@16
|
1726 \li \c boost::geometry::index::intersects(),
|
Chris@16
|
1727 \li \c boost::geometry::index::overlaps(),
|
Chris@16
|
1728 \li \c boost::geometry::index::within(),
|
Chris@16
|
1729
|
Chris@16
|
1730 It is possible to negate spatial predicates:
|
Chris@16
|
1731 \li <tt>! boost::geometry::index::contains()</tt>,
|
Chris@16
|
1732 \li <tt>! boost::geometry::index::covered_by()</tt>,
|
Chris@16
|
1733 \li <tt>! boost::geometry::index::covers()</tt>,
|
Chris@16
|
1734 \li <tt>! boost::geometry::index::disjoint()</tt>,
|
Chris@16
|
1735 \li <tt>! boost::geometry::index::intersects()</tt>,
|
Chris@16
|
1736 \li <tt>! boost::geometry::index::overlaps()</tt>,
|
Chris@16
|
1737 \li <tt>! boost::geometry::index::within()</tt>
|
Chris@16
|
1738
|
Chris@16
|
1739 <b>Satisfies predicate</b>
|
Chris@16
|
1740
|
Chris@16
|
1741 This is a special kind of predicate which allows to pass a user-defined function or function object which checks
|
Chris@16
|
1742 if Value should be returned by the query. It's generated by:
|
Chris@16
|
1743 \li \c boost::geometry::index::satisfies().
|
Chris@16
|
1744
|
Chris@16
|
1745 <b>Nearest predicate</b>
|
Chris@16
|
1746
|
Chris@16
|
1747 If the nearest predicate is passed a k-nearest neighbor search will be performed. This query will result
|
Chris@16
|
1748 in returning k values to the output iterator. Only one nearest predicate may be passed to the query.
|
Chris@16
|
1749 It may be generated by:
|
Chris@16
|
1750 \li \c boost::geometry::index::nearest().
|
Chris@16
|
1751
|
Chris@16
|
1752 <b>Connecting predicates</b>
|
Chris@16
|
1753
|
Chris@16
|
1754 Predicates may be passed together connected with \c operator&&().
|
Chris@16
|
1755
|
Chris@16
|
1756 \par Example
|
Chris@16
|
1757 \verbatim
|
Chris@16
|
1758 // return elements intersecting box
|
Chris@16
|
1759 bgi::query(tree, bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
1760 // return elements intersecting poly but not within box
|
Chris@16
|
1761 bgi::query(tree, bgi::intersects(poly) && !bgi::within(box), std::back_inserter(result));
|
Chris@16
|
1762 // return elements overlapping box and meeting my_fun value predicate
|
Chris@16
|
1763 bgi::query(tree, bgi::overlaps(box) && bgi::satisfies(my_fun), std::back_inserter(result));
|
Chris@16
|
1764 // return 5 elements nearest to pt and elements are intersecting box
|
Chris@16
|
1765 bgi::query(tree, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
|
Chris@16
|
1766 \endverbatim
|
Chris@16
|
1767
|
Chris@16
|
1768 \par Throws
|
Chris@16
|
1769 If Value copy constructor or copy assignment throws.
|
Chris@16
|
1770
|
Chris@16
|
1771 \warning
|
Chris@16
|
1772 Only one \c nearest() perdicate may be passed to the query. Passing more of them results in compile-time error.
|
Chris@16
|
1773
|
Chris@16
|
1774 \ingroup rtree_functions
|
Chris@16
|
1775
|
Chris@16
|
1776 \param tree The rtree.
|
Chris@16
|
1777 \param predicates Predicates.
|
Chris@16
|
1778 \param out_it The output iterator, e.g. generated by std::back_inserter().
|
Chris@16
|
1779
|
Chris@16
|
1780 \return The number of values found.
|
Chris@16
|
1781 */
|
Chris@16
|
1782 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@16
|
1783 typename Predicates, typename OutIter> inline
|
Chris@16
|
1784 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::size_type
|
Chris@16
|
1785 query(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
|
Chris@16
|
1786 Predicates const& predicates,
|
Chris@16
|
1787 OutIter out_it)
|
Chris@16
|
1788 {
|
Chris@16
|
1789 return tree.query(predicates, out_it);
|
Chris@16
|
1790 }
|
Chris@16
|
1791
|
Chris@16
|
1792 /*!
|
Chris@16
|
1793 \brief Returns the query iterator pointing at the begin of the query range.
|
Chris@16
|
1794
|
Chris@16
|
1795 This method returns the iterator which may be used to perform iterative queries. For the information
|
Chris@16
|
1796 about the predicates which may be passed to this method see query().
|
Chris@16
|
1797
|
Chris@16
|
1798 \par Example
|
Chris@16
|
1799 \verbatim
|
Chris@16
|
1800
|
Chris@16
|
1801 for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
|
Chris@16
|
1802 it != qend(tree) ; ++it )
|
Chris@16
|
1803 {
|
Chris@16
|
1804 // do something with value
|
Chris@16
|
1805 if ( has_enough_nearest_values() )
|
Chris@16
|
1806 break;
|
Chris@16
|
1807 }
|
Chris@16
|
1808 \endverbatim
|
Chris@16
|
1809
|
Chris@16
|
1810 \par Throws
|
Chris@16
|
1811 If predicates copy throws.
|
Chris@16
|
1812 If allocation throws.
|
Chris@16
|
1813
|
Chris@16
|
1814 \ingroup rtree_functions
|
Chris@16
|
1815
|
Chris@16
|
1816 \param tree The rtree.
|
Chris@16
|
1817 \param predicates Predicates.
|
Chris@16
|
1818
|
Chris@16
|
1819 \return The iterator pointing at the begin of the query range.
|
Chris@16
|
1820 */
|
Chris@16
|
1821 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator,
|
Chris@16
|
1822 typename Predicates> inline
|
Chris@16
|
1823 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
|
Chris@16
|
1824 qbegin(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree,
|
Chris@16
|
1825 Predicates const& predicates)
|
Chris@16
|
1826 {
|
Chris@16
|
1827 return tree.qbegin(predicates);
|
Chris@16
|
1828 }
|
Chris@16
|
1829
|
Chris@16
|
1830 /*!
|
Chris@16
|
1831 \brief Returns the query iterator pointing at the end of the query range.
|
Chris@16
|
1832
|
Chris@16
|
1833 This method returns the iterator which may be used to check if the query has ended.
|
Chris@16
|
1834
|
Chris@16
|
1835 \par Example
|
Chris@16
|
1836 \verbatim
|
Chris@16
|
1837
|
Chris@16
|
1838 for ( Rtree::const_query_iterator it = qbegin(tree, bgi::nearest(pt, 10000)) ;
|
Chris@16
|
1839 it != qend(tree) ; ++it )
|
Chris@16
|
1840 {
|
Chris@16
|
1841 // do something with value
|
Chris@16
|
1842 if ( has_enough_nearest_values() )
|
Chris@16
|
1843 break;
|
Chris@16
|
1844 }
|
Chris@16
|
1845 \endverbatim
|
Chris@16
|
1846
|
Chris@16
|
1847 \par Throws
|
Chris@16
|
1848 Nothing
|
Chris@16
|
1849
|
Chris@16
|
1850 \ingroup rtree_functions
|
Chris@16
|
1851
|
Chris@16
|
1852 \return The iterator pointing at the end of the query range.
|
Chris@16
|
1853 */
|
Chris@16
|
1854 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator> inline
|
Chris@16
|
1855 typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::const_query_iterator
|
Chris@16
|
1856 qend(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1857 {
|
Chris@16
|
1858 return tree.qend();
|
Chris@16
|
1859 }
|
Chris@16
|
1860
|
Chris@16
|
1861 /*!
|
Chris@16
|
1862 \brief Remove all values from the index.
|
Chris@16
|
1863
|
Chris@16
|
1864 It calls \c rtree::clear().
|
Chris@16
|
1865
|
Chris@16
|
1866 \ingroup rtree_functions
|
Chris@16
|
1867
|
Chris@16
|
1868 \param tree The spatial index.
|
Chris@16
|
1869 */
|
Chris@16
|
1870 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1871 inline void clear(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & tree)
|
Chris@16
|
1872 {
|
Chris@16
|
1873 return tree.clear();
|
Chris@16
|
1874 }
|
Chris@16
|
1875
|
Chris@16
|
1876 /*!
|
Chris@16
|
1877 \brief Get the number of values stored in the index.
|
Chris@16
|
1878
|
Chris@16
|
1879 It calls \c rtree::size().
|
Chris@16
|
1880
|
Chris@16
|
1881 \ingroup rtree_functions
|
Chris@16
|
1882
|
Chris@16
|
1883 \param tree The spatial index.
|
Chris@16
|
1884
|
Chris@16
|
1885 \return The number of values stored in the index.
|
Chris@16
|
1886 */
|
Chris@16
|
1887 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1888 inline size_t size(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1889 {
|
Chris@16
|
1890 return tree.size();
|
Chris@16
|
1891 }
|
Chris@16
|
1892
|
Chris@16
|
1893 /*!
|
Chris@16
|
1894 \brief Query if there are no values stored in the index.
|
Chris@16
|
1895
|
Chris@16
|
1896 It calls \c rtree::empty().
|
Chris@16
|
1897
|
Chris@16
|
1898 \ingroup rtree_functions
|
Chris@16
|
1899
|
Chris@16
|
1900 \param tree The spatial index.
|
Chris@16
|
1901
|
Chris@16
|
1902 \return true if there are no values in the index.
|
Chris@16
|
1903 */
|
Chris@16
|
1904 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1905 inline bool empty(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1906 {
|
Chris@16
|
1907 return tree.bounds();
|
Chris@16
|
1908 }
|
Chris@16
|
1909
|
Chris@16
|
1910 /*!
|
Chris@16
|
1911 \brief Get the box containing all stored values or an invalid box if the index has no values.
|
Chris@16
|
1912
|
Chris@16
|
1913 It calls \c rtree::envelope().
|
Chris@16
|
1914
|
Chris@16
|
1915 \ingroup rtree_functions
|
Chris@16
|
1916
|
Chris@16
|
1917 \param tree The spatial index.
|
Chris@16
|
1918
|
Chris@16
|
1919 \return The box containing all stored values or an invalid box.
|
Chris@16
|
1920 */
|
Chris@16
|
1921 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1922 inline typename rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator>::bounds_type
|
Chris@16
|
1923 bounds(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> const& tree)
|
Chris@16
|
1924 {
|
Chris@16
|
1925 return tree.bounds();
|
Chris@16
|
1926 }
|
Chris@16
|
1927
|
Chris@16
|
1928 /*!
|
Chris@16
|
1929 \brief Exchanges the contents of the container with those of other.
|
Chris@16
|
1930
|
Chris@16
|
1931 It calls \c rtree::swap().
|
Chris@16
|
1932
|
Chris@16
|
1933 \ingroup rtree_functions
|
Chris@16
|
1934
|
Chris@16
|
1935 \param l The first rtree.
|
Chris@16
|
1936 \param r The second rtree.
|
Chris@16
|
1937 */
|
Chris@16
|
1938 template <typename Value, typename Parameters, typename IndexableGetter, typename EqualTo, typename Allocator>
|
Chris@16
|
1939 inline void swap(rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & l,
|
Chris@16
|
1940 rtree<Value, Parameters, IndexableGetter, EqualTo, Allocator> & r)
|
Chris@16
|
1941 {
|
Chris@16
|
1942 return l.swap(r);
|
Chris@16
|
1943 }
|
Chris@16
|
1944
|
Chris@16
|
1945 }}} // namespace boost::geometry::index
|
Chris@16
|
1946
|
Chris@101
|
1947 // TODO: don't include the implementation at the end of the file
|
Chris@101
|
1948 #include <boost/geometry/algorithms/detail/comparable_distance/implementation.hpp>
|
Chris@101
|
1949
|
Chris@16
|
1950 #include <boost/geometry/index/detail/config_end.hpp>
|
Chris@16
|
1951
|
Chris@16
|
1952 #endif // BOOST_GEOMETRY_INDEX_RTREE_HPP
|