annotate DEPENDENCIES/generic/include/boost/geometry/index/rtree.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
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