1 // Boost.Geometry Index
4 // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland.
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
10 #ifndef BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
11 #define BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP
13 #include <boost/foreach.hpp>
17 #include <geometry_index_test_common.hpp>
19 #include <boost/geometry/index/rtree.hpp>
21 #include <boost/geometry/geometries/point.hpp>
22 #include <boost/geometry/geometries/box.hpp>
23 #include <boost/geometry/geometries/segment.hpp>
25 #include <boost/geometry/index/detail/rtree/utilities/are_levels_ok.hpp>
26 #include <boost/geometry/index/detail/rtree/utilities/are_boxes_ok.hpp>
28 //#include <boost/geometry/geometries/ring.hpp>
29 //#include <boost/geometry/geometries/polygon.hpp>
33 // Set point's coordinates
35 template <typename Point>
39 template <typename T, typename C>
40 struct outside_point< bg::model::point<T, 2, C> >
42 typedef bg::model::point<T, 2, C> P;
49 template <typename T, typename C>
50 struct outside_point< bg::model::point<T, 3, C> >
52 typedef bg::model::point<T, 3, C> P;
59 // Default value generation
61 template <typename Value>
64 static Value apply(){ return Value(); }
67 // Values, input and rtree generation
69 template <typename Value>
73 template <typename T, typename C>
74 struct value< bg::model::point<T, 2, C> >
76 typedef bg::model::point<T, 2, C> P;
77 static P apply(int x, int y)
83 template <typename T, typename C>
84 struct value< bg::model::box< bg::model::point<T, 2, C> > >
86 typedef bg::model::point<T, 2, C> P;
87 typedef bg::model::box<P> B;
88 static B apply(int x, int y)
90 return B(P(x, y), P(x + 2, y + 3));
94 template <typename T, typename C>
95 struct value< bg::model::segment< bg::model::point<T, 2, C> > >
97 typedef bg::model::point<T, 2, C> P;
98 typedef bg::model::segment<P> S;
99 static S apply(int x, int y)
101 return S(P(x, y), P(x + 2, y + 3));
105 template <typename T, typename C>
106 struct value< std::pair<bg::model::point<T, 2, C>, int> >
108 typedef bg::model::point<T, 2, C> P;
109 typedef std::pair<P, int> R;
110 static R apply(int x, int y)
112 return std::make_pair(P(x, y), x + y * 100);
116 template <typename T, typename C>
117 struct value< std::pair<bg::model::box< bg::model::point<T, 2, C> >, int> >
119 typedef bg::model::point<T, 2, C> P;
120 typedef bg::model::box<P> B;
121 typedef std::pair<B, int> R;
122 static R apply(int x, int y)
124 return std::make_pair(B(P(x, y), P(x + 2, y + 3)), x + y * 100);
128 template <typename T, typename C>
129 struct value< std::pair<bg::model::segment< bg::model::point<T, 2, C> >, int> >
131 typedef bg::model::point<T, 2, C> P;
132 typedef bg::model::segment<P> S;
133 typedef std::pair<S, int> R;
134 static R apply(int x, int y)
136 return std::make_pair(S(P(x, y), P(x + 2, y + 3)), x + y * 100);
140 template <typename T, typename C>
141 struct value< boost::tuple<bg::model::point<T, 2, C>, int, int> >
143 typedef bg::model::point<T, 2, C> P;
144 typedef boost::tuple<P, int, int> R;
145 static R apply(int x, int y)
147 return boost::make_tuple(P(x, y), x + y * 100, 0);
151 template <typename T, typename C>
152 struct value< boost::tuple<bg::model::box< bg::model::point<T, 2, C> >, int, int> >
154 typedef bg::model::point<T, 2, C> P;
155 typedef bg::model::box<P> B;
156 typedef boost::tuple<B, int, int> R;
157 static R apply(int x, int y)
159 return boost::make_tuple(B(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
163 template <typename T, typename C>
164 struct value< boost::tuple<bg::model::segment< bg::model::point<T, 2, C> >, int, int> >
166 typedef bg::model::point<T, 2, C> P;
167 typedef bg::model::segment<P> S;
168 typedef boost::tuple<S, int, int> R;
169 static R apply(int x, int y)
171 return boost::make_tuple(S(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
175 template <typename T, typename C>
176 struct value< bg::model::point<T, 3, C> >
178 typedef bg::model::point<T, 3, C> P;
179 static P apply(int x, int y, int z)
185 template <typename T, typename C>
186 struct value< bg::model::box< bg::model::point<T, 3, C> > >
188 typedef bg::model::point<T, 3, C> P;
189 typedef bg::model::box<P> B;
190 static B apply(int x, int y, int z)
192 return B(P(x, y, z), P(x + 2, y + 3, z + 4));
196 template <typename T, typename C>
197 struct value< std::pair<bg::model::point<T, 3, C>, int> >
199 typedef bg::model::point<T, 3, C> P;
200 typedef std::pair<P, int> R;
201 static R apply(int x, int y, int z)
203 return std::make_pair(P(x, y, z), x + y * 100 + z * 10000);
207 template <typename T, typename C>
208 struct value< std::pair<bg::model::box< bg::model::point<T, 3, C> >, int> >
210 typedef bg::model::point<T, 3, C> P;
211 typedef bg::model::box<P> B;
212 typedef std::pair<B, int> R;
213 static R apply(int x, int y, int z)
215 return std::make_pair(B(P(x, y, z), P(x + 2, y + 3, z + 4)), x + y * 100 + z * 10000);
219 template <typename T, typename C>
220 struct value< boost::tuple<bg::model::point<T, 3, C>, int, int> >
222 typedef bg::model::point<T, 3, C> P;
223 typedef boost::tuple<P, int, int> R;
224 static R apply(int x, int y, int z)
226 return boost::make_tuple(P(x, y, z), x + y * 100 + z * 10000, 0);
230 template <typename T, typename C>
231 struct value< boost::tuple<bg::model::box< bg::model::point<T, 3, C> >, int, int> >
233 typedef bg::model::point<T, 3, C> P;
234 typedef bg::model::box<P> B;
235 typedef boost::tuple<B, int, int> R;
236 static R apply(int x, int y, int z)
238 return boost::make_tuple(B(P(x, y, z), P(x + 2, y + 3, z + 4)), x + y * 100 + z * 10000, 0);
242 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
244 template <typename T, typename C>
245 struct value< std::tuple<bg::model::point<T, 2, C>, int, int> >
247 typedef bg::model::point<T, 2, C> P;
248 typedef std::tuple<P, int, int> R;
249 static R apply(int x, int y)
251 return std::make_tuple(P(x, y), x + y * 100, 0);
255 template <typename T, typename C>
256 struct value< std::tuple<bg::model::box< bg::model::point<T, 2, C> >, int, int> >
258 typedef bg::model::point<T, 2, C> P;
259 typedef bg::model::box<P> B;
260 typedef std::tuple<B, int, int> R;
261 static R apply(int x, int y)
263 return std::make_tuple(B(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
267 template <typename T, typename C>
268 struct value< std::tuple<bg::model::segment< bg::model::point<T, 2, C> >, int, int> >
270 typedef bg::model::point<T, 2, C> P;
271 typedef bg::model::segment<P> S;
272 typedef std::tuple<S, int, int> R;
273 static R apply(int x, int y)
275 return std::make_tuple(S(P(x, y), P(x + 2, y + 3)), x + y * 100, 0);
279 template <typename T, typename C>
280 struct value< std::tuple<bg::model::point<T, 3, C>, int, int> >
282 typedef bg::model::point<T, 3, C> P;
283 typedef std::tuple<P, int, int> R;
284 static R apply(int x, int y, int z)
286 return std::make_tuple(P(x, y, z), x + y * 100 + z * 10000, 0);
290 template <typename T, typename C>
291 struct value< std::tuple<bg::model::box< bg::model::point<T, 3, C> >, int, int> >
293 typedef bg::model::point<T, 3, C> P;
294 typedef bg::model::box<P> B;
295 typedef std::tuple<B, int, int> R;
296 static R apply(int x, int y, int z)
298 return std::make_tuple(B(P(x, y, z), P(x + 2, y + 3, z + 4)), x + y * 100 + z * 10000, 0);
302 #endif // #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
304 } // namespace generate
308 template <typename Indexable>
311 test_object(Indexable const& indexable_) : indexable(indexable_) {}
315 namespace boost { namespace geometry { namespace index {
317 template <typename Indexable>
318 struct indexable< boost::shared_ptr< test_object<Indexable> > >
320 typedef boost::shared_ptr< test_object<Indexable> > value_type;
321 typedef Indexable const& result_type;
323 result_type operator()(value_type const& value) const
325 return value->indexable;
333 template <typename T, typename C>
334 struct value< boost::shared_ptr<test_object<bg::model::point<T, 2, C> > > >
336 typedef bg::model::point<T, 2, C> P;
337 typedef test_object<P> O;
338 typedef boost::shared_ptr<O> R;
340 static R apply(int x, int y)
342 return R(new O(P(x, y)));
346 template <typename T, typename C>
347 struct value< boost::shared_ptr<test_object<bg::model::point<T, 3, C> > > >
349 typedef bg::model::point<T, 3, C> P;
350 typedef test_object<P> O;
351 typedef boost::shared_ptr<O> R;
353 static R apply(int x, int y, int z)
355 return R(new O(P(x, y, z)));
359 template <typename T, typename C>
360 struct value< boost::shared_ptr<test_object<bg::model::box<bg::model::point<T, 2, C> > > > >
362 typedef bg::model::point<T, 2, C> P;
363 typedef bg::model::box<P> B;
364 typedef test_object<B> O;
365 typedef boost::shared_ptr<O> R;
367 static R apply(int x, int y)
369 return R(new O(B(P(x, y), P(x + 2, y + 3))));
373 template <typename T, typename C>
374 struct value< boost::shared_ptr<test_object<bg::model::box<bg::model::point<T, 3, C> > > > >
376 typedef bg::model::point<T, 3, C> P;
377 typedef bg::model::box<P> B;
378 typedef test_object<B> O;
379 typedef boost::shared_ptr<O> R;
381 static R apply(int x, int y, int z)
383 return R(new O(B(P(x, y, z), P(x + 2, y + 3, z + 4))));
387 template <typename T, typename C>
388 struct value< boost::shared_ptr<test_object<bg::model::segment<bg::model::point<T, 2, C> > > > >
390 typedef bg::model::point<T, 2, C> P;
391 typedef bg::model::segment<P> S;
392 typedef test_object<S> O;
393 typedef boost::shared_ptr<O> R;
395 static R apply(int x, int y)
397 return R(new O(S(P(x, y), P(x + 2, y + 3))));
401 } //namespace generate
405 template <typename Indexable>
406 struct counting_value
408 counting_value() { counter()++; }
409 counting_value(Indexable const& i) : indexable(i) { counter()++; }
410 counting_value(counting_value const& c) : indexable(c.indexable) { counter()++; }
411 ~counting_value() { counter()--; }
413 static size_t & counter() { static size_t c = 0; return c; }
417 namespace boost { namespace geometry { namespace index {
419 template <typename Indexable>
420 struct indexable< counting_value<Indexable> >
422 typedef counting_value<Indexable> value_type;
423 typedef Indexable const& result_type;
424 result_type operator()(value_type const& value) const
426 return value.indexable;
430 template <typename Indexable>
431 struct equal_to< counting_value<Indexable> >
433 typedef counting_value<Indexable> value_type;
434 typedef bool result_type;
435 bool operator()(value_type const& v1, value_type const& v2) const
437 return boost::geometry::equals(v1.indexable, v2.indexable);
445 template <typename T, typename C>
446 struct value< counting_value<bg::model::point<T, 2, C> > >
448 typedef bg::model::point<T, 2, C> P;
449 typedef counting_value<P> R;
450 static R apply(int x, int y) { return R(P(x, y)); }
453 template <typename T, typename C>
454 struct value< counting_value<bg::model::point<T, 3, C> > >
456 typedef bg::model::point<T, 3, C> P;
457 typedef counting_value<P> R;
458 static R apply(int x, int y, int z) { return R(P(x, y, z)); }
461 template <typename T, typename C>
462 struct value< counting_value<bg::model::box<bg::model::point<T, 2, C> > > >
464 typedef bg::model::point<T, 2, C> P;
465 typedef bg::model::box<P> B;
466 typedef counting_value<B> R;
467 static R apply(int x, int y) { return R(B(P(x, y), P(x+2, y+3))); }
470 template <typename T, typename C>
471 struct value< counting_value<bg::model::box<bg::model::point<T, 3, C> > > >
473 typedef bg::model::point<T, 3, C> P;
474 typedef bg::model::box<P> B;
475 typedef counting_value<B> R;
476 static R apply(int x, int y, int z) { return R(B(P(x, y, z), P(x+2, y+3, z+4))); }
479 template <typename T, typename C>
480 struct value< counting_value<bg::model::segment<bg::model::point<T, 2, C> > > >
482 typedef bg::model::point<T, 2, C> P;
483 typedef bg::model::segment<P> S;
484 typedef counting_value<S> R;
485 static R apply(int x, int y) { return R(S(P(x, y), P(x+2, y+3))); }
488 } // namespace generate
490 // value without default constructor
492 template <typename Indexable>
493 struct value_no_dctor
495 value_no_dctor(Indexable const& i) : indexable(i) {}
499 namespace boost { namespace geometry { namespace index {
501 template <typename Indexable>
502 struct indexable< value_no_dctor<Indexable> >
504 typedef value_no_dctor<Indexable> value_type;
505 typedef Indexable const& result_type;
506 result_type operator()(value_type const& value) const
508 return value.indexable;
512 template <typename Indexable>
513 struct equal_to< value_no_dctor<Indexable> >
515 typedef value_no_dctor<Indexable> value_type;
516 typedef bool result_type;
517 bool operator()(value_type const& v1, value_type const& v2) const
519 return boost::geometry::equals(v1.indexable, v2.indexable);
527 template <typename Indexable>
528 struct value_default< value_no_dctor<Indexable> >
530 static value_no_dctor<Indexable> apply() { return value_no_dctor<Indexable>(Indexable()); }
533 template <typename T, typename C>
534 struct value< value_no_dctor<bg::model::point<T, 2, C> > >
536 typedef bg::model::point<T, 2, C> P;
537 typedef value_no_dctor<P> R;
538 static R apply(int x, int y) { return R(P(x, y)); }
541 template <typename T, typename C>
542 struct value< value_no_dctor<bg::model::point<T, 3, C> > >
544 typedef bg::model::point<T, 3, C> P;
545 typedef value_no_dctor<P> R;
546 static R apply(int x, int y, int z) { return R(P(x, y, z)); }
549 template <typename T, typename C>
550 struct value< value_no_dctor<bg::model::box<bg::model::point<T, 2, C> > > >
552 typedef bg::model::point<T, 2, C> P;
553 typedef bg::model::box<P> B;
554 typedef value_no_dctor<B> R;
555 static R apply(int x, int y) { return R(B(P(x, y), P(x+2, y+3))); }
558 template <typename T, typename C>
559 struct value< value_no_dctor<bg::model::box<bg::model::point<T, 3, C> > > >
561 typedef bg::model::point<T, 3, C> P;
562 typedef bg::model::box<P> B;
563 typedef value_no_dctor<B> R;
564 static R apply(int x, int y, int z) { return R(B(P(x, y, z), P(x+2, y+3, z+4))); }
567 template <typename T, typename C>
568 struct value< value_no_dctor<bg::model::segment<bg::model::point<T, 2, C> > > >
570 typedef bg::model::point<T, 2, C> P;
571 typedef bg::model::segment<P> S;
572 typedef value_no_dctor<S> R;
573 static R apply(int x, int y) { return R(S(P(x, y), P(x+2, y+3))); }
578 template <size_t Dimension>
585 template <typename Value, typename Box>
586 static void apply(std::vector<Value> & input, Box & qbox, int size = 1)
588 BOOST_GEOMETRY_INDEX_ASSERT(0 < size, "the value must be greather than 0");
590 for ( int i = 0 ; i < 12 * size ; i += 3 )
592 for ( int j = 1 ; j < 25 * size ; j += 4 )
594 input.push_back( generate::value<Value>::apply(i, j) );
598 typedef typename bg::traits::point_type<Box>::type P;
600 qbox = Box(P(3, 0), P(10, 9));
607 template <typename Value, typename Box>
608 static void apply(std::vector<Value> & input, Box & qbox, int size = 1)
610 BOOST_GEOMETRY_INDEX_ASSERT(0 < size, "the value must be greather than 0");
612 for ( int i = 0 ; i < 12 * size ; i += 3 )
614 for ( int j = 1 ; j < 25 * size ; j += 4 )
616 for ( int k = 2 ; k < 12 * size ; k += 5 )
618 input.push_back( generate::value<Value>::apply(i, j, k) );
623 typedef typename bg::traits::point_type<Box>::type P;
625 qbox = Box(P(3, 0, 3), P(10, 9, 11));
629 // generate_value_outside
631 template <typename Value, size_t Dimension>
632 struct value_outside_impl
635 template <typename Value>
636 struct value_outside_impl<Value, 2>
640 //TODO - for size > 1 in generate_input<> this won't be outside
641 return generate::value<Value>::apply(13, 26);
645 template <typename Value>
646 struct value_outside_impl<Value, 3>
650 //TODO - for size > 1 in generate_input<> this won't be outside
651 return generate::value<Value>::apply(13, 26, 13);
655 template <typename Rtree>
656 inline typename Rtree::value_type
659 typedef typename Rtree::value_type V;
660 typedef typename Rtree::indexable_type I;
662 return value_outside_impl<V, bg::dimension<I>::value>::apply();
665 template<typename Rtree, typename Elements, typename Box>
666 void rtree(Rtree & tree, Elements & input, Box & qbox)
668 typedef typename Rtree::indexable_type I;
671 bg::dimension<I>::value
672 >::apply(input, qbox);
674 tree.insert(input.begin(), input.end());
677 } // namespace generate
679 namespace basictest {
681 // low level test functions
683 template <typename Rtree, typename Iter, typename Value>
684 Iter find(Rtree const& rtree, Iter first, Iter last, Value const& value)
686 for ( ; first != last ; ++first )
687 if ( rtree.value_eq()(value, *first) )
692 template <typename Rtree, typename Value>
693 void compare_outputs(Rtree const& rtree, std::vector<Value> const& output, std::vector<Value> const& expected_output)
695 bool are_sizes_ok = (expected_output.size() == output.size());
696 BOOST_CHECK( are_sizes_ok );
699 BOOST_FOREACH(Value const& v, expected_output)
701 BOOST_CHECK(find(rtree, output.begin(), output.end(), v) != output.end() );
706 template <typename Rtree, typename Range1, typename Range2>
707 void exactly_the_same_outputs(Rtree const& rtree, Range1 const& output, Range2 const& expected_output)
709 size_t s1 = std::distance(output.begin(), output.end());
710 size_t s2 = std::distance(expected_output.begin(), expected_output.end());
711 BOOST_CHECK(s1 == s2);
715 typename Range1::const_iterator it1 = output.begin();
716 typename Range2::const_iterator it2 = expected_output.begin();
717 for ( ; it1 != output.end() && it2 != expected_output.end() ; ++it1, ++it2 )
719 if ( !rtree.value_eq()(*it1, *it2) )
721 BOOST_CHECK(false && "rtree.translator().equals(*it1, *it2)");
728 // alternative version of std::copy taking iterators of differnet types
729 template <typename First, typename Last, typename Out>
730 void copy_alt(First first, Last last, Out out)
732 for ( ; first != last ; ++first, ++out )
738 template <typename Rtree, typename Value, typename Predicates>
739 void spatial_query(Rtree & rtree, Predicates const& pred, std::vector<Value> const& expected_output)
741 BOOST_CHECK( bgi::detail::rtree::utilities::are_levels_ok(rtree) );
742 if ( !rtree.empty() )
743 BOOST_CHECK( bgi::detail::rtree::utilities::are_boxes_ok(rtree) );
745 std::vector<Value> output;
746 size_t n = rtree.query(pred, std::back_inserter(output));
748 BOOST_CHECK( expected_output.size() == n );
749 compare_outputs(rtree, output, expected_output);
751 std::vector<Value> output2;
752 size_t n2 = query(rtree, pred, std::back_inserter(output2));
754 BOOST_CHECK( n == n2 );
755 exactly_the_same_outputs(rtree, output, output2);
757 exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::queried(pred));
759 std::vector<Value> output3;
760 std::copy(rtree.qbegin(pred), rtree.qend(), std::back_inserter(output3));
762 compare_outputs(rtree, output3, expected_output);
764 std::vector<Value> output4;
765 std::copy(qbegin(rtree, pred), qend(rtree), std::back_inserter(output4));
767 exactly_the_same_outputs(rtree, output3, output4);
769 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
771 std::vector<Value> output4;
772 std::copy(rtree.qbegin_(pred), rtree.qend_(pred), std::back_inserter(output4));
773 compare_outputs(rtree, output4, expected_output);
775 copy_alt(rtree.qbegin_(pred), rtree.qend_(), std::back_inserter(output4));
776 compare_outputs(rtree, output4, expected_output);
781 // rtree specific queries tests
783 template <typename Rtree, typename Value, typename Box>
784 void intersects(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
786 std::vector<Value> expected_output;
788 BOOST_FOREACH(Value const& v, input)
789 if ( bg::intersects(tree.indexable_get()(v), qbox) )
790 expected_output.push_back(v);
792 //spatial_query(tree, qbox, expected_output);
793 spatial_query(tree, bgi::intersects(qbox), expected_output);
794 spatial_query(tree, !bgi::disjoint(qbox), expected_output);
796 /*typedef bg::traits::point_type<Box>::type P;
797 bg::model::ring<P> qring;
798 bg::convert(qbox, qring);
799 spatial_query(tree, bgi::intersects(qring), expected_output);
800 spatial_query(tree, !bgi::disjoint(qring), expected_output);
801 bg::model::polygon<P> qpoly;
802 bg::convert(qbox, qpoly);
803 spatial_query(tree, bgi::intersects(qpoly), expected_output);
804 spatial_query(tree, !bgi::disjoint(qpoly), expected_output);*/
807 template <typename Rtree, typename Value, typename Box>
808 void disjoint(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
810 std::vector<Value> expected_output;
812 BOOST_FOREACH(Value const& v, input)
813 if ( bg::disjoint(tree.indexable_get()(v), qbox) )
814 expected_output.push_back(v);
816 spatial_query(tree, bgi::disjoint(qbox), expected_output);
817 spatial_query(tree, !bgi::intersects(qbox), expected_output);
819 /*typedef bg::traits::point_type<Box>::type P;
820 bg::model::ring<P> qring;
821 bg::convert(qbox, qring);
822 spatial_query(tree, bgi::disjoint(qring), expected_output);
823 bg::model::polygon<P> qpoly;
824 bg::convert(qbox, qpoly);
825 spatial_query(tree, bgi::disjoint(qpoly), expected_output);*/
828 template <typename Tag>
831 template <typename Rtree, typename Value, typename Box>
832 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
834 std::vector<Value> expected_output;
836 BOOST_FOREACH(Value const& v, input)
837 if ( bg::within(qbox, tree.indexable_get()(v)) )
838 expected_output.push_back(v);
840 spatial_query(tree, bgi::contains(qbox), expected_output);
842 /*typedef bg::traits::point_type<Box>::type P;
843 bg::model::ring<P> qring;
844 bg::convert(qbox, qring);
845 spatial_query(tree, bgi::contains(qring), expected_output);
846 bg::model::polygon<P> qpoly;
847 bg::convert(qbox, qpoly);
848 spatial_query(tree, bgi::contains(qpoly), expected_output);*/
853 struct contains_impl<bg::point_tag>
855 template <typename Rtree, typename Value, typename Box>
856 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
861 struct contains_impl<bg::segment_tag>
863 template <typename Rtree, typename Value, typename Box>
864 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
868 template <typename Rtree, typename Value, typename Box>
869 void contains(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
873 typename Rtree::indexable_type
875 >::apply(tree, input, qbox);
878 template <typename Tag>
879 struct covered_by_impl
881 template <typename Rtree, typename Value, typename Box>
882 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
884 std::vector<Value> expected_output;
886 BOOST_FOREACH(Value const& v, input)
889 bgi::detail::return_ref_or_bounds(
890 tree.indexable_get()(v)),
893 expected_output.push_back(v);
897 spatial_query(tree, bgi::covered_by(qbox), expected_output);
899 /*typedef bg::traits::point_type<Box>::type P;
900 bg::model::ring<P> qring;
901 bg::convert(qbox, qring);
902 spatial_query(tree, bgi::covered_by(qring), expected_output);
903 bg::model::polygon<P> qpoly;
904 bg::convert(qbox, qpoly);
905 spatial_query(tree, bgi::covered_by(qpoly), expected_output);*/
910 struct covered_by_impl<bg::segment_tag>
912 template <typename Rtree, typename Value, typename Box>
913 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
917 template <typename Rtree, typename Value, typename Box>
918 void covered_by(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
922 typename Rtree::indexable_type
924 >::apply(tree, input, qbox);
927 template <typename Tag>
930 template <typename Rtree, typename Value, typename Box>
931 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
933 std::vector<Value> expected_output;
935 BOOST_FOREACH(Value const& v, input)
936 if ( bg::covered_by(qbox, tree.indexable_get()(v)) )
937 expected_output.push_back(v);
939 spatial_query(tree, bgi::covers(qbox), expected_output);
941 /*typedef bg::traits::point_type<Box>::type P;
942 bg::model::ring<P> qring;
943 bg::convert(qbox, qring);
944 spatial_query(tree, bgi::covers(qring), expected_output);
945 bg::model::polygon<P> qpoly;
946 bg::convert(qbox, qpoly);
947 spatial_query(tree, bgi::covers(qpoly), expected_output);*/
952 struct covers_impl<bg::point_tag>
954 template <typename Rtree, typename Value, typename Box>
955 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
960 struct covers_impl<bg::segment_tag>
962 template <typename Rtree, typename Value, typename Box>
963 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
967 template <typename Rtree, typename Value, typename Box>
968 void covers(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
972 typename Rtree::indexable_type
974 >::apply(tree, input, qbox);
977 template <typename Tag>
980 template <typename Rtree, typename Value, typename Box>
981 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
983 std::vector<Value> expected_output;
985 BOOST_FOREACH(Value const& v, input)
986 if ( bg::overlaps(tree.indexable_get()(v), qbox) )
987 expected_output.push_back(v);
989 spatial_query(tree, bgi::overlaps(qbox), expected_output);
991 /*typedef bg::traits::point_type<Box>::type P;
992 bg::model::ring<P> qring;
993 bg::convert(qbox, qring);
994 spatial_query(tree, bgi::overlaps(qring), expected_output);
995 bg::model::polygon<P> qpoly;
996 bg::convert(qbox, qpoly);
997 spatial_query(tree, bgi::overlaps(qpoly), expected_output);*/
1002 struct overlaps_impl<bg::point_tag>
1004 template <typename Rtree, typename Value, typename Box>
1005 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1010 struct overlaps_impl<bg::segment_tag>
1012 template <typename Rtree, typename Value, typename Box>
1013 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1017 template <typename Rtree, typename Value, typename Box>
1018 void overlaps(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1022 typename Rtree::indexable_type
1024 >::apply(tree, input, qbox);
1027 //template <typename Tag, size_t Dimension>
1028 //struct touches_impl
1030 // template <typename Rtree, typename Value, typename Box>
1031 // static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1036 //struct touches_impl<bg::box_tag, 2>
1038 // template <typename Rtree, typename Value, typename Box>
1039 // static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1041 // std::vector<Value> expected_output;
1043 // BOOST_FOREACH(Value const& v, input)
1044 // if ( bg::touches(tree.translator()(v), qbox) )
1045 // expected_output.push_back(v);
1047 // spatial_query(tree, bgi::touches(qbox), expected_output);
1051 //template <typename Rtree, typename Value, typename Box>
1052 //void touches(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1055 // bgi::traits::tag<typename Rtree::indexable_type>::type,
1056 // bgi::traits::dimension<typename Rtree::indexable_type>::value
1057 // >::apply(tree, input, qbox);
1060 template <typename Tag>
1063 template <typename Rtree, typename Value, typename Box>
1064 static void apply(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1066 std::vector<Value> expected_output;
1068 BOOST_FOREACH(Value const& v, input)
1069 if ( bg::within(tree.indexable_get()(v), qbox) )
1070 expected_output.push_back(v);
1072 spatial_query(tree, bgi::within(qbox), expected_output);
1074 /*typedef bg::traits::point_type<Box>::type P;
1075 bg::model::ring<P> qring;
1076 bg::convert(qbox, qring);
1077 spatial_query(tree, bgi::within(qring), expected_output);
1078 bg::model::polygon<P> qpoly;
1079 bg::convert(qbox, qpoly);
1080 spatial_query(tree, bgi::within(qpoly), expected_output);*/
1085 struct within_impl<bg::segment_tag>
1087 template <typename Rtree, typename Value, typename Box>
1088 static void apply(Rtree const& /*tree*/, std::vector<Value> const& /*input*/, Box const& /*qbox*/)
1092 template <typename Rtree, typename Value, typename Box>
1093 void within(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1097 typename Rtree::indexable_type
1099 >::apply(tree, input, qbox);
1102 // rtree nearest queries
1104 template <typename Rtree, typename Point>
1107 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1109 template <typename Value>
1110 bool operator()(std::pair<D, Value> const& p1, std::pair<D, Value> const& p2) const
1112 return p1.first < p2.first;
1116 template <typename Rtree, typename Point>
1117 struct NearestKTransform
1119 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1121 template <typename Value>
1122 Value const& operator()(std::pair<D, Value> const& p) const
1128 template <typename Rtree, typename Value, typename Point, typename Distance>
1129 inline void compare_nearest_outputs(Rtree const& rtree, std::vector<Value> const& output, std::vector<Value> const& expected_output, Point const& pt, Distance greatest_distance)
1132 bool are_sizes_ok = (expected_output.size() == output.size());
1133 BOOST_CHECK( are_sizes_ok );
1136 BOOST_FOREACH(Value const& v, output)
1138 // TODO - perform explicit check here?
1139 // should all objects which are closest be checked and should exactly the same be found?
1141 if ( find(rtree, expected_output.begin(), expected_output.end(), v) == expected_output.end() )
1143 Distance d = bg::comparable_distance(pt, rtree.indexable_get()(v));
1144 BOOST_CHECK(d == greatest_distance);
1150 template <typename Rtree, typename Value, typename Point>
1151 inline void check_sorted_by_distance(Rtree const& rtree, std::vector<Value> const& output, Point const& pt)
1153 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1156 BOOST_FOREACH(Value const& v, output)
1158 D d = bg::comparable_distance(pt, rtree.indexable_get()(v));
1159 BOOST_CHECK(prev_dist <= d);
1164 template <typename Rtree, typename Value, typename Point>
1165 inline void nearest_query_k(Rtree const& rtree, std::vector<Value> const& input, Point const& pt, unsigned int k)
1167 // TODO: Nearest object may not be the same as found by the rtree if distances are equal
1168 // All objects with the same closest distance should be picked
1170 typedef typename bg::default_distance_result<Point, typename Rtree::indexable_type>::type D;
1172 std::vector< std::pair<D, Value> > test_output;
1174 // calculate test output - k closest values pairs
1175 BOOST_FOREACH(Value const& v, input)
1177 D d = bg::comparable_distance(pt, rtree.indexable_get()(v));
1179 if ( test_output.size() < k )
1180 test_output.push_back(std::make_pair(d, v));
1183 std::sort(test_output.begin(), test_output.end(), NearestKLess<Rtree, Point>());
1184 if ( d < test_output.back().first )
1185 test_output.back() = std::make_pair(d, v);
1189 // caluclate biggest distance
1190 std::sort(test_output.begin(), test_output.end(), NearestKLess<Rtree, Point>());
1191 D greatest_distance = 0;
1192 if ( !test_output.empty() )
1193 greatest_distance = test_output.back().first;
1195 // transform test output to vector of values
1196 std::vector<Value> expected_output(test_output.size(), generate::value_default<Value>::apply());
1197 std::transform(test_output.begin(), test_output.end(), expected_output.begin(), NearestKTransform<Rtree, Point>());
1199 // calculate output using rtree
1200 std::vector<Value> output;
1201 rtree.query(bgi::nearest(pt, k), std::back_inserter(output));
1204 compare_nearest_outputs(rtree, output, expected_output, pt, greatest_distance);
1206 exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::queried(bgi::nearest(pt, k)));
1208 std::vector<Value> output2(k, generate::value_default<Value>::apply());
1209 typename Rtree::size_type found_count = rtree.query(bgi::nearest(pt, k), output2.begin());
1210 output2.resize(found_count, generate::value_default<Value>::apply());
1212 exactly_the_same_outputs(rtree, output, output2);
1214 std::vector<Value> output3;
1215 std::copy(rtree.qbegin(bgi::nearest(pt, k)), rtree.qend(), std::back_inserter(output3));
1217 compare_nearest_outputs(rtree, output3, expected_output, pt, greatest_distance);
1218 check_sorted_by_distance(rtree, output3, pt);
1220 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
1222 std::vector<Value> output4;
1223 std::copy(rtree.qbegin_(bgi::nearest(pt, k)), rtree.qend_(bgi::nearest(pt, k)), std::back_inserter(output4));
1224 exactly_the_same_outputs(rtree, output4, output3);
1226 copy_alt(rtree.qbegin_(bgi::nearest(pt, k)), rtree.qend_(), std::back_inserter(output4));
1227 exactly_the_same_outputs(rtree, output4, output3);
1232 // rtree nearest not found
1236 template <typename Value>
1237 bool operator()(Value const& ) const { return false; }
1240 template <typename Rtree, typename Point>
1241 void nearest_query_not_found(Rtree const& rtree, Point const& pt)
1243 typedef typename Rtree::value_type Value;
1245 std::vector<Value> output_v;
1246 size_t n_res = rtree.query(bgi::nearest(pt, 5) && bgi::satisfies(AlwaysFalse()), std::back_inserter(output_v));
1247 BOOST_CHECK(output_v.size() == n_res);
1248 BOOST_CHECK(n_res < 5);
1251 template <typename Value>
1252 bool satisfies_fun(Value const& ) { return true; }
1254 struct satisfies_obj
1256 template <typename Value>
1257 bool operator()(Value const& ) const { return true; }
1260 template <typename Rtree, typename Value>
1261 void satisfies(Rtree const& rtree, std::vector<Value> const& input)
1263 std::vector<Value> result;
1264 rtree.query(bgi::satisfies(satisfies_obj()), std::back_inserter(result));
1265 BOOST_CHECK(result.size() == input.size());
1267 rtree.query(!bgi::satisfies(satisfies_obj()), std::back_inserter(result));
1268 BOOST_CHECK(result.size() == 0);
1271 rtree.query(bgi::satisfies(satisfies_fun<Value>), std::back_inserter(result));
1272 BOOST_CHECK(result.size() == input.size());
1274 rtree.query(!bgi::satisfies(satisfies_fun<Value>), std::back_inserter(result));
1275 BOOST_CHECK(result.size() == 0);
1277 #ifndef BOOST_NO_CXX11_LAMBDAS
1279 rtree.query(bgi::satisfies([](Value const&){ return true; }), std::back_inserter(result));
1280 BOOST_CHECK(result.size() == input.size());
1282 rtree.query(!bgi::satisfies([](Value const&){ return true; }), std::back_inserter(result));
1283 BOOST_CHECK(result.size() == 0);
1287 // rtree copying and moving
1289 template <typename Rtree, typename Box>
1290 void copy_swap_move(Rtree const& tree, Box const& qbox)
1292 typedef typename Rtree::value_type Value;
1293 typedef typename Rtree::parameters_type Params;
1295 size_t s = tree.size();
1296 Params params = tree.parameters();
1298 std::vector<Value> expected_output;
1299 tree.query(bgi::intersects(qbox), std::back_inserter(expected_output));
1304 BOOST_CHECK(tree.empty() == t1.empty());
1305 BOOST_CHECK(tree.size() == t1.size());
1306 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1307 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1309 std::vector<Value> output;
1310 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1311 exactly_the_same_outputs(t1, output, expected_output);
1313 // copying assignment operator
1316 BOOST_CHECK(tree.empty() == t1.empty());
1317 BOOST_CHECK(tree.size() == t1.size());
1318 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1319 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1322 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1323 exactly_the_same_outputs(t1, output, expected_output);
1325 Rtree t2(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1327 BOOST_CHECK(tree.empty() == t2.empty());
1328 BOOST_CHECK(tree.size() == t2.size());
1329 BOOST_CHECK(true == t1.empty());
1330 BOOST_CHECK(0 == t1.size());
1331 // those fails e.g. on darwin 4.2.1 because it can't copy base obejcts properly
1332 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1333 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1334 BOOST_CHECK(t2.parameters().get_max_elements() == params.get_max_elements());
1335 BOOST_CHECK(t2.parameters().get_min_elements() == params.get_min_elements());
1338 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1339 BOOST_CHECK(output.empty());
1342 t2.query(bgi::intersects(qbox), std::back_inserter(output));
1343 exactly_the_same_outputs(t2, output, expected_output);
1345 // those fails e.g. on darwin 4.2.1 because it can't copy base obejcts properly
1346 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1347 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1348 BOOST_CHECK(t2.parameters().get_max_elements() == params.get_max_elements());
1349 BOOST_CHECK(t2.parameters().get_min_elements() == params.get_min_elements());
1351 // moving constructor
1352 Rtree t3(boost::move(t1), tree.get_allocator());
1354 BOOST_CHECK(t3.size() == s);
1355 BOOST_CHECK(t1.size() == 0);
1356 BOOST_CHECK(t3.parameters().get_max_elements() == params.get_max_elements());
1357 BOOST_CHECK(t3.parameters().get_min_elements() == params.get_min_elements());
1360 t3.query(bgi::intersects(qbox), std::back_inserter(output));
1361 exactly_the_same_outputs(t3, output, expected_output);
1363 // moving assignment operator
1364 t1 = boost::move(t3);
1366 BOOST_CHECK(t1.size() == s);
1367 BOOST_CHECK(t3.size() == 0);
1368 BOOST_CHECK(t1.parameters().get_max_elements() == params.get_max_elements());
1369 BOOST_CHECK(t1.parameters().get_min_elements() == params.get_min_elements());
1372 t1.query(bgi::intersects(qbox), std::back_inserter(output));
1373 exactly_the_same_outputs(t1, output, expected_output);
1377 ::boost::ignore_unused_variable_warning(params);
1380 template <typename I, typename O>
1381 inline void my_copy(I first, I last, O out)
1383 for ( ; first != last ; ++first, ++out )
1387 // rtree creation and insertion
1389 template <typename Rtree, typename Value, typename Box>
1390 void create_insert(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1392 std::vector<Value> expected_output;
1393 tree.query(bgi::intersects(qbox), std::back_inserter(expected_output));
1396 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1397 BOOST_FOREACH(Value const& v, input)
1399 BOOST_CHECK(tree.size() == t.size());
1400 std::vector<Value> output;
1401 t.query(bgi::intersects(qbox), std::back_inserter(output));
1402 exactly_the_same_outputs(t, output, expected_output);
1405 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1406 //std::copy(input.begin(), input.end(), bgi::inserter(t));
1407 my_copy(input.begin(), input.end(), bgi::inserter(t)); // to suppress MSVC warnings
1408 BOOST_CHECK(tree.size() == t.size());
1409 std::vector<Value> output;
1410 t.query(bgi::intersects(qbox), std::back_inserter(output));
1411 exactly_the_same_outputs(t, output, expected_output);
1414 Rtree t(input.begin(), input.end(), tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1415 BOOST_CHECK(tree.size() == t.size());
1416 std::vector<Value> output;
1417 t.query(bgi::intersects(qbox), std::back_inserter(output));
1418 compare_outputs(t, output, expected_output);
1421 Rtree t(input, tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1422 BOOST_CHECK(tree.size() == t.size());
1423 std::vector<Value> output;
1424 t.query(bgi::intersects(qbox), std::back_inserter(output));
1425 compare_outputs(t, output, expected_output);
1428 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1429 t.insert(input.begin(), input.end());
1430 BOOST_CHECK(tree.size() == t.size());
1431 std::vector<Value> output;
1432 t.query(bgi::intersects(qbox), std::back_inserter(output));
1433 exactly_the_same_outputs(t, output, expected_output);
1436 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1438 BOOST_CHECK(tree.size() == t.size());
1439 std::vector<Value> output;
1440 t.query(bgi::intersects(qbox), std::back_inserter(output));
1441 exactly_the_same_outputs(t, output, expected_output);
1445 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1446 BOOST_FOREACH(Value const& v, input)
1448 BOOST_CHECK(tree.size() == t.size());
1449 std::vector<Value> output;
1450 bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
1451 exactly_the_same_outputs(t, output, expected_output);
1454 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1455 bgi::insert(t, input.begin(), input.end());
1456 BOOST_CHECK(tree.size() == t.size());
1457 std::vector<Value> output;
1458 bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
1459 exactly_the_same_outputs(t, output, expected_output);
1462 Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator());
1463 bgi::insert(t, input);
1464 BOOST_CHECK(tree.size() == t.size());
1465 std::vector<Value> output;
1466 bgi::query(t, bgi::intersects(qbox), std::back_inserter(output));
1467 exactly_the_same_outputs(t, output, expected_output);
1473 template <typename Rtree, typename Box>
1474 void remove(Rtree const& tree, Box const& qbox)
1476 typedef typename Rtree::value_type Value;
1478 std::vector<Value> values_to_remove;
1479 tree.query(bgi::intersects(qbox), std::back_inserter(values_to_remove));
1480 BOOST_CHECK(0 < values_to_remove.size());
1482 std::vector<Value> expected_output;
1483 tree.query(bgi::disjoint(qbox), std::back_inserter(expected_output));
1484 size_t expected_removed_count = values_to_remove.size();
1485 size_t expected_size_after_remove = tree.size() - values_to_remove.size();
1487 // Add value which is not stored in the Rtree
1488 Value outsider = generate::value_outside<Rtree>();
1489 values_to_remove.push_back(outsider);
1494 BOOST_FOREACH(Value const& v, values_to_remove)
1496 BOOST_CHECK( r == expected_removed_count );
1497 std::vector<Value> output;
1498 t.query(bgi::disjoint(qbox), std::back_inserter(output));
1499 BOOST_CHECK( t.size() == expected_size_after_remove );
1500 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1501 compare_outputs(t, output, expected_output);
1505 size_t r = t.remove(values_to_remove.begin(), values_to_remove.end());
1506 BOOST_CHECK( r == expected_removed_count );
1507 std::vector<Value> output;
1508 t.query(bgi::disjoint(qbox), std::back_inserter(output));
1509 BOOST_CHECK( t.size() == expected_size_after_remove );
1510 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1511 compare_outputs(t, output, expected_output);
1515 size_t r = t.remove(values_to_remove);
1516 BOOST_CHECK( r == expected_removed_count );
1517 std::vector<Value> output;
1518 t.query(bgi::disjoint(qbox), std::back_inserter(output));
1519 BOOST_CHECK( t.size() == expected_size_after_remove );
1520 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1521 compare_outputs(t, output, expected_output);
1527 BOOST_FOREACH(Value const& v, values_to_remove)
1528 r += bgi::remove(t, v);
1529 BOOST_CHECK( r == expected_removed_count );
1530 std::vector<Value> output;
1531 bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
1532 BOOST_CHECK( t.size() == expected_size_after_remove );
1533 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1534 compare_outputs(t, output, expected_output);
1538 size_t r = bgi::remove(t, values_to_remove.begin(), values_to_remove.end());
1539 BOOST_CHECK( r == expected_removed_count );
1540 std::vector<Value> output;
1541 bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
1542 BOOST_CHECK( t.size() == expected_size_after_remove );
1543 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1544 compare_outputs(t, output, expected_output);
1548 size_t r = bgi::remove(t, values_to_remove);
1549 BOOST_CHECK( r == expected_removed_count );
1550 std::vector<Value> output;
1551 bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output));
1552 BOOST_CHECK( t.size() == expected_size_after_remove );
1553 BOOST_CHECK( output.size() == tree.size() - expected_removed_count );
1554 compare_outputs(t, output, expected_output);
1558 template <typename Rtree, typename Value, typename Box>
1559 void clear(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1561 std::vector<Value> values_to_remove;
1562 tree.query(bgi::intersects(qbox), std::back_inserter(values_to_remove));
1563 BOOST_CHECK(0 < values_to_remove.size());
1569 std::vector<Value> expected_output;
1570 t.query(bgi::intersects(qbox), std::back_inserter(expected_output));
1571 size_t s = t.size();
1573 BOOST_CHECK(t.empty());
1574 BOOST_CHECK(t.size() == 0);
1576 BOOST_CHECK(t.size() == s);
1577 std::vector<Value> output;
1578 t.query(bgi::intersects(qbox), std::back_inserter(output));
1579 exactly_the_same_outputs(t, output, expected_output);
1585 template <typename Rtree, typename Value, typename Box>
1586 void queries(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1588 basictest::intersects(tree, input, qbox);
1589 basictest::disjoint(tree, input, qbox);
1590 basictest::covered_by(tree, input, qbox);
1591 basictest::overlaps(tree, input, qbox);
1592 //basictest::touches(tree, input, qbox);
1593 basictest::within(tree, input, qbox);
1594 basictest::contains(tree, input, qbox);
1595 basictest::covers(tree, input, qbox);
1597 typedef typename bg::point_type<Box>::type P;
1599 bg::centroid(qbox, pt);
1601 basictest::nearest_query_k(tree, input, pt, 10);
1602 basictest::nearest_query_not_found(tree, generate::outside_point<P>::apply());
1604 basictest::satisfies(tree, input);
1607 // rtree creation and modification
1609 template <typename Rtree, typename Value, typename Box>
1610 void modifiers(Rtree const& tree, std::vector<Value> const& input, Box const& qbox)
1612 basictest::copy_swap_move(tree, qbox);
1613 basictest::create_insert(tree, input, qbox);
1614 basictest::remove(tree, qbox);
1615 basictest::clear(tree, input, qbox);
1618 } // namespace basictest
1620 template <typename Value, typename Parameters, typename Allocator>
1621 void test_rtree_queries(Parameters const& parameters, Allocator const& allocator)
1623 typedef bgi::indexable<Value> I;
1624 typedef bgi::equal_to<Value> E;
1625 typedef typename Allocator::template rebind<Value>::other A;
1626 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1627 typedef typename Tree::bounds_type B;
1629 Tree tree(parameters, I(), E(), allocator);
1630 std::vector<Value> input;
1633 generate::rtree(tree, input, qbox);
1635 basictest::queries(tree, input, qbox);
1637 Tree empty_tree(parameters, I(), E(), allocator);
1638 std::vector<Value> empty_input;
1640 basictest::queries(empty_tree, empty_input, qbox);
1643 template <typename Value, typename Parameters, typename Allocator>
1644 void test_rtree_modifiers(Parameters const& parameters, Allocator const& allocator)
1646 typedef bgi::indexable<Value> I;
1647 typedef bgi::equal_to<Value> E;
1648 typedef typename Allocator::template rebind<Value>::other A;
1649 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1650 typedef typename Tree::bounds_type B;
1652 Tree tree(parameters, I(), E(), allocator);
1653 std::vector<Value> input;
1656 generate::rtree(tree, input, qbox);
1658 basictest::modifiers(tree, input, qbox);
1660 Tree empty_tree(parameters, I(), E(), allocator);
1661 std::vector<Value> empty_input;
1663 basictest::copy_swap_move(empty_tree, qbox);
1666 // run all tests for a single Algorithm and single rtree
1669 template <typename Value, typename Parameters, typename Allocator>
1670 void test_rtree_by_value(Parameters const& parameters, Allocator const& allocator)
1672 test_rtree_queries<Value>(parameters, allocator);
1673 test_rtree_modifiers<Value>(parameters, allocator);
1676 // rtree inserting and removing of counting_value
1678 template <typename Indexable, typename Parameters, typename Allocator>
1679 void test_count_rtree_values(Parameters const& parameters, Allocator const& allocator)
1681 typedef counting_value<Indexable> Value;
1683 typedef bgi::indexable<Value> I;
1684 typedef bgi::equal_to<Value> E;
1685 typedef typename Allocator::template rebind<Value>::other A;
1686 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1687 typedef typename Tree::bounds_type B;
1689 Tree t(parameters, I(), E(), allocator);
1690 std::vector<Value> input;
1693 generate::rtree(t, input, qbox);
1695 size_t rest_count = input.size();
1697 BOOST_CHECK(t.size() + rest_count == Value::counter());
1699 std::vector<Value> values_to_remove;
1700 t.query(bgi::intersects(qbox), std::back_inserter(values_to_remove));
1702 rest_count += values_to_remove.size();
1704 BOOST_CHECK(t.size() + rest_count == Value::counter());
1706 size_t values_count = Value::counter();
1708 BOOST_FOREACH(Value const& v, values_to_remove)
1710 size_t r = t.remove(v);
1713 BOOST_CHECK(1 == r);
1714 BOOST_CHECK(Value::counter() == values_count);
1715 BOOST_CHECK(t.size() + rest_count == values_count);
1721 template <typename Indexable, typename Parameters, typename Allocator>
1722 void test_rtree_count(Parameters const& parameters, Allocator const& allocator)
1724 typedef std::pair<Indexable, int> Value;
1726 typedef bgi::indexable<Value> I;
1727 typedef bgi::equal_to<Value> E;
1728 typedef typename Allocator::template rebind<Value>::other A;
1729 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1730 typedef typename Tree::bounds_type B;
1732 Tree t(parameters, I(), E(), allocator);
1733 std::vector<Value> input;
1736 generate::rtree(t, input, qbox);
1738 BOOST_CHECK(t.count(input[0]) == 1);
1739 BOOST_CHECK(t.count(input[0].first) == 1);
1743 BOOST_CHECK(t.count(input[0]) == 2);
1744 BOOST_CHECK(t.count(input[0].first) == 2);
1746 t.insert(std::make_pair(input[0].first, -1));
1748 BOOST_CHECK(t.count(input[0]) == 2);
1749 BOOST_CHECK(t.count(input[0].first) == 3);
1754 template <typename Value, typename Parameters, typename Allocator>
1755 void test_rtree_bounds(Parameters const& parameters, Allocator const& allocator)
1757 typedef bgi::indexable<Value> I;
1758 typedef bgi::equal_to<Value> E;
1759 typedef typename Allocator::template rebind<Value>::other A;
1760 typedef bgi::rtree<Value, Parameters, I, E, A> Tree;
1761 typedef typename Tree::bounds_type B;
1762 //typedef typename bg::traits::point_type<B>::type P;
1765 bg::assign_inverse(b);
1767 Tree t(parameters, I(), E(), allocator);
1768 std::vector<Value> input;
1771 BOOST_CHECK(bg::equals(t.bounds(), b));
1773 generate::rtree(t, input, qbox);
1775 BOOST_FOREACH(Value const& v, input)
1776 bg::expand(b, t.indexable_get()(v));
1778 BOOST_CHECK(bg::equals(t.bounds(), b));
1779 BOOST_CHECK(bg::equals(t.bounds(), bgi::bounds(t)));
1781 size_t s = input.size();
1782 while ( s/2 < input.size() && !input.empty() )
1784 t.remove(input.back());
1788 bg::assign_inverse(b);
1789 BOOST_FOREACH(Value const& v, input)
1790 bg::expand(b, t.indexable_get()(v));
1792 BOOST_CHECK(bg::equals(t.bounds(), b));
1795 BOOST_CHECK(bg::equals(t2.bounds(), b));
1798 BOOST_CHECK(bg::equals(t2.bounds(), b));
1800 t2 = boost::move(t);
1801 BOOST_CHECK(bg::equals(t2.bounds(), b));
1805 bg::assign_inverse(b);
1806 BOOST_CHECK(bg::equals(t.bounds(), b));
1809 template <typename Indexable, typename Parameters, typename Allocator>
1810 void test_rtree_additional(Parameters const& parameters, Allocator const& allocator)
1812 test_count_rtree_values<Indexable>(parameters, allocator);
1813 test_rtree_count<Indexable>(parameters, allocator);
1814 test_rtree_bounds<Indexable>(parameters, allocator);
1817 // run all tests for one Algorithm for some number of rtrees
1818 // defined by some number of Values constructed from given Point
1820 template<typename Point, typename Parameters, typename Allocator>
1821 void test_rtree_for_point(Parameters const& parameters, Allocator const& allocator)
1823 typedef std::pair<Point, int> PairP;
1824 typedef boost::tuple<Point, int, int> TupleP;
1825 typedef boost::shared_ptr< test_object<Point> > SharedPtrP;
1826 typedef value_no_dctor<Point> VNoDCtor;
1828 test_rtree_by_value<Point, Parameters>(parameters, allocator);
1829 test_rtree_by_value<PairP, Parameters>(parameters, allocator);
1830 test_rtree_by_value<TupleP, Parameters>(parameters, allocator);
1832 test_rtree_by_value<SharedPtrP, Parameters>(parameters, allocator);
1833 test_rtree_by_value<VNoDCtor, Parameters>(parameters, allocator);
1835 test_rtree_additional<Point>(parameters, allocator);
1837 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1838 typedef std::tuple<Point, int, int> StdTupleP;
1839 test_rtree_by_value<StdTupleP, Parameters>(parameters, allocator);
1843 template<typename Point, typename Parameters, typename Allocator>
1844 void test_rtree_for_box(Parameters const& parameters, Allocator const& allocator)
1846 typedef bg::model::box<Point> Box;
1847 typedef std::pair<Box, int> PairB;
1848 typedef boost::tuple<Box, int, int> TupleB;
1849 typedef value_no_dctor<Box> VNoDCtor;
1851 test_rtree_by_value<Box, Parameters>(parameters, allocator);
1852 test_rtree_by_value<PairB, Parameters>(parameters, allocator);
1853 test_rtree_by_value<TupleB, Parameters>(parameters, allocator);
1855 test_rtree_by_value<VNoDCtor, Parameters>(parameters, allocator);
1857 test_rtree_additional<Box>(parameters, allocator);
1859 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1860 typedef std::tuple<Box, int, int> StdTupleB;
1861 test_rtree_by_value<StdTupleB, Parameters>(parameters, allocator);
1865 template<typename Point, typename Parameters>
1866 void test_rtree_for_point(Parameters const& parameters)
1868 test_rtree_for_point<Point>(parameters, std::allocator<int>());
1871 template<typename Point, typename Parameters>
1872 void test_rtree_for_box(Parameters const& parameters)
1874 test_rtree_for_box<Point>(parameters, std::allocator<int>());
1879 template<typename Indexable, typename Parameters, typename Allocator>
1880 void modifiers(Parameters const& parameters, Allocator const& allocator)
1882 typedef std::pair<Indexable, int> Pair;
1883 typedef boost::tuple<Indexable, int, int> Tuple;
1884 typedef boost::shared_ptr< test_object<Indexable> > SharedPtr;
1885 typedef value_no_dctor<Indexable> VNoDCtor;
1887 test_rtree_modifiers<Indexable>(parameters, allocator);
1888 test_rtree_modifiers<Pair>(parameters, allocator);
1889 test_rtree_modifiers<Tuple>(parameters, allocator);
1891 test_rtree_modifiers<SharedPtr>(parameters, allocator);
1892 test_rtree_modifiers<VNoDCtor>(parameters, allocator);
1894 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1895 typedef std::tuple<Indexable, int, int> StdTuple;
1896 test_rtree_modifiers<StdTuple>(parameters, allocator);
1900 template<typename Indexable, typename Parameters, typename Allocator>
1901 void queries(Parameters const& parameters, Allocator const& allocator)
1903 typedef std::pair<Indexable, int> Pair;
1904 typedef boost::tuple<Indexable, int, int> Tuple;
1905 typedef boost::shared_ptr< test_object<Indexable> > SharedPtr;
1906 typedef value_no_dctor<Indexable> VNoDCtor;
1908 test_rtree_queries<Indexable>(parameters, allocator);
1909 test_rtree_queries<Pair>(parameters, allocator);
1910 test_rtree_queries<Tuple>(parameters, allocator);
1912 test_rtree_queries<SharedPtr>(parameters, allocator);
1913 test_rtree_queries<VNoDCtor>(parameters, allocator);
1915 #if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
1916 typedef std::tuple<Indexable, int, int> StdTuple;
1917 test_rtree_queries<StdTuple>(parameters, allocator);
1921 template<typename Indexable, typename Parameters, typename Allocator>
1922 void additional(Parameters const& parameters, Allocator const& allocator)
1924 test_rtree_additional<Indexable, Parameters>(parameters, allocator);
1927 } // namespace testset
1929 #endif // BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP