diff --git a/include/boost/geometry/index/detail/distance_predicates.hpp b/include/boost/geometry/index/detail/distance_predicates.hpp index 9d86a03f2..805254704 100644 --- a/include/boost/geometry/index/detail/distance_predicates.hpp +++ b/include/boost/geometry/index/detail/distance_predicates.hpp @@ -28,6 +28,194 @@ namespace boost { namespace geometry { namespace index { namespace detail { +// ------------------------------------------------------------------ // +// predicate +// ------------------------------------------------------------------ // + +template +struct nearest +{ + static const bool is_one = false; + + nearest(DistancePredicates const& dpred, unsigned k) + : distance_predicates(dpred) + , count(k) + {} + DistancePredicates const& distance_predicates; + unsigned count; +}; + +template +struct predicate_check, value_tag> +{ + template + static inline bool apply(nearest const&, Value const&, Box const&) + { + return true; + } +}; + +template +struct predicate_check, envelope_tag> +{ + template + static inline bool apply(nearest const&, Value const&, Box const&) + { + return true; + } +}; + +template +struct nearest_one +{ + static const bool is_one = true; + + nearest_one(DistancePredicates const& dpred) + : distance_predicates(dpred) + {} + DistancePredicates const& distance_predicates; +}; + +template +struct predicate_check, value_tag> +{ + template + static inline bool apply(nearest_one const&, Value const&, Box const&) + { + return true; + } +}; + +template +struct predicate_check, envelope_tag> +{ + template + static inline bool apply(nearest_one const&, Value const&, Box const&) + { + return true; + } +}; + +// predicates_is_nearest + +template +struct predicates_is_nearest +{ + static const unsigned value = 0; +}; + +template +struct predicates_is_nearest< nearest > +{ + static const unsigned value = 1; +}; + +template +struct predicates_is_nearest< nearest_one > +{ + static const unsigned value = 1; +}; + +// predicates_count_nearest + +template +struct predicates_count_nearest +{ + static const unsigned value = predicates_is_nearest::value; +}; + +template +struct predicates_count_nearest< std::pair > +{ + static const unsigned value = predicates_is_nearest::value + + predicates_is_nearest::value; +}; + +template +struct predicates_count_nearest_tuple +{ + static const unsigned value = + predicates_is_nearest::type>::value + + predicates_count_nearest_tuple::value; +}; + +template +struct predicates_count_nearest_tuple +{ + static const unsigned value = + predicates_is_nearest::type>::value; +}; + +template +struct predicates_count_nearest< boost::tuple > +{ + static const unsigned value = predicates_count_nearest_tuple< + boost::tuple, + boost::tuples::length< boost::tuple >::value + >::value; +}; + +template +struct predicates_count_nearest< boost::tuples::cons > +{ + static const unsigned value = predicates_count_nearest_tuple< + boost::tuples::cons, + boost::tuples::length< boost::tuples::cons >::value + >::value; +}; + +// predicates_find_nearest + +template +struct predicates_find_nearest +{ + static const unsigned value = predicates_is_nearest::value ? 0 : 1; +}; + +template +struct predicates_find_nearest< std::pair > +{ + static const unsigned value = predicates_is_nearest::value ? 0 : + (predicates_is_nearest::value ? 1 : 2); +}; + +template +struct predicates_find_nearest_tuple +{ + static const bool is_found = predicates_find_nearest_tuple::is_found + || predicates_is_nearest::type>::value; + + static const unsigned value = predicates_find_nearest_tuple::is_found ? + predicates_find_nearest_tuple::value : + (predicates_is_nearest::type>::value ? + N-1 : boost::tuples::length::value); +}; + +template +struct predicates_find_nearest_tuple +{ + static const bool is_found = predicates_is_nearest::type>::value; + static const unsigned value = is_found ? 0 : boost::tuples::length::value; +}; + +template +struct predicates_find_nearest< boost::tuple > +{ + static const unsigned value = predicates_find_nearest_tuple< + boost::tuple, + boost::tuples::length< boost::tuple >::value + >::value; +}; + +template +struct predicates_find_nearest< boost::tuples::cons > +{ + static const unsigned value = predicates_find_nearest_tuple< + boost::tuples::cons, + boost::tuples::length< boost::tuples::cons >::value + >::value; +}; + // ------------------------------------------------------------------ // // relations // ------------------------------------------------------------------ // @@ -364,7 +552,7 @@ struct distances_calc_impl_rel< // distances_calc_impl_tuple -template +template struct distances_calc_impl_tuple { // TODO MPL ASSERT 0 < N diff --git a/include/boost/geometry/index/detail/predicates.hpp b/include/boost/geometry/index/detail/predicates.hpp index e835fd9a6..a8261319a 100644 --- a/include/boost/geometry/index/detail/predicates.hpp +++ b/include/boost/geometry/index/detail/predicates.hpp @@ -438,40 +438,158 @@ struct predicate_check, envelope_tag> } }; +// ------------------------------------------------------------------ // +// predicates_length +// ------------------------------------------------------------------ // + +template +struct predicates_length +{ + static const unsigned value = 1; +}; + +template +struct predicates_length< std::pair > +{ + static const unsigned value = 2; +}; + +template +struct predicates_length< boost::tuple > +{ + static const unsigned value = boost::tuples::length< boost::tuple >::value; +}; + +template +struct predicates_length< boost::tuples::cons > +{ + static const unsigned value = boost::tuples::length< boost::tuples::cons >::value; +}; + +// ------------------------------------------------------------------ // +// predicates_element +// ------------------------------------------------------------------ // + +template +struct predicates_element +{ + BOOST_MPL_ASSERT_MSG((I < 1), INVALID_INDEX, (predicates_element)); + typedef T type; + static type const& get(T const& p) { return p; } +}; + +template +struct predicates_element< I, std::pair > +{ + BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element)); + + typedef F type; + static type const& get(std::pair const& p) { return p.first; } +}; + +template +struct predicates_element< 1, std::pair > +{ + typedef S type; + static type const& get(std::pair const& p) { return p.second; } +}; + +template +struct predicates_element< I, boost::tuple > +{ + typedef boost::tuple predicate_type; + + typedef typename boost::tuples::element::type type; + static type const& get(predicate_type const& p) { return boost::get(p); } +}; + +template +struct predicates_element< I, boost::tuples::cons > +{ + typedef boost::tuples::cons predicate_type; + + typedef typename boost::tuples::element::type type; + static type const& get(predicate_type const& p) { return boost::get(p); } +}; + // ------------------------------------------------------------------ // // predicates_check // ------------------------------------------------------------------ // -template +template +struct predicates_check_pair {}; + +template +struct predicates_check_pair +{ + template + static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) + { + return true; + } +}; + +template +struct predicates_check_pair +{ + template + static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) + { + return predicate_check::apply(p.first, v, i); + } +}; + +template +struct predicates_check_pair +{ + template + static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) + { + return predicate_check::apply(p.second, v, i); + } +}; + +template +struct predicates_check_pair +{ + template + static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i) + { + return predicate_check::apply(p.first, v, i) + && predicate_check::apply(p.second, v, i); + } +}; + +template struct predicates_check_tuple { template static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i) { - return predicates_check_tuple::apply(p, v, i) - && predicate_check< - typename boost::tuples::element::type, - Tag - >::apply(boost::get(p), v, i); + return + predicate_check< + typename boost::tuples::element::type, + Tag + >::apply(boost::get(p), v, i) && + predicates_check_tuple::apply(p, v, i); } }; -template -struct predicates_check_tuple +template +struct predicates_check_tuple { template static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i) { - return predicate_check< - typename boost::tuples::element<0, TuplePredicates>::type, - Tag - >::apply(boost::get<0>(p), v, i); + return true; } }; -template +template struct predicates_check_impl { + BOOST_MPL_ASSERT_MSG((First < 1 && Last <= 1 && First <= Last), INVALID_INDEXES, (predicates_check_impl)); + template static inline bool apply(Predicate const& p, Value const& v, Indexable const& i) { @@ -479,9 +597,11 @@ struct predicates_check_impl } }; -template -struct predicates_check_impl, Tag> +template +struct predicates_check_impl, Tag, First, Last> { + BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl)); + template static inline bool apply(std::pair const& p, Value const& v, Indexable const& i) { @@ -493,30 +613,53 @@ struct predicates_check_impl, Tag> template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, - typename Tag + typename Tag, unsigned First, unsigned Last > struct predicates_check_impl< boost::tuple, - Tag + Tag, First, Last > { typedef boost::tuple predicates_type; + static const unsigned pred_len = boost::tuples::length::value; + BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl)); + template static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i) { return predicates_check_tuple< predicates_type, - Tag, - boost::tuples::length::value + Tag, First, Last >::apply(p, v, i); } }; -template +template +struct predicates_check_impl< + boost::tuples::cons, + Tag, First, Last +> +{ + typedef boost::tuples::cons predicates_type; + + static const unsigned pred_len = boost::tuples::length::value; + BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl)); + + template + static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i) + { + return predicates_check_tuple< + predicates_type, + Tag, First, Last + >::apply(p, v, i); + } +}; + +template inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i) { - return detail::predicates_check_impl + return detail::predicates_check_impl ::apply(p, v, i); } diff --git a/include/boost/geometry/index/detail/rtree/visitors/nearest_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/nearest_query.hpp index d6db7ca26..345246ed5 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/nearest_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/nearest_query.hpp @@ -184,6 +184,8 @@ public: index::detail::value_tag > value_distances_predicates_check; + static const unsigned predicates_len = index::detail::predicates_length::value; + inline nearest_query(parameters_type const& parameters, Translator const& translator, DistancesPredicates const& dist_pred, Predicates const& pred, Result & r) : m_parameters(parameters), m_translator(translator) , m_dist_pred(dist_pred), m_pred(pred) @@ -211,7 +213,7 @@ public: { // if current node meets predicates // 0 - dummy value - if ( index::detail::predicates_check(m_pred, 0, it->first) ) + if ( index::detail::predicates_check(m_pred, 0, it->first) ) { // calculate node's distance(s) for distance predicate node_distances_type node_dist_data = node_distances_calc::apply(m_dist_pred, it->first); @@ -266,7 +268,7 @@ public: it != elements.end(); ++it) { // if value meets predicates - if ( index::detail::predicates_check(m_pred, *it, m_translator(*it)) ) + if ( index::detail::predicates_check(m_pred, *it, m_translator(*it)) ) { // calculate values distance for distance predicate value_distances_type distances = value_distances_calc::apply(m_dist_pred, m_translator(*it)); diff --git a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp index 3ceec4d45..87b0e4904 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/spatial_query.hpp @@ -28,6 +28,8 @@ struct spatial_query typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; + static const unsigned predicates_len = index::detail::predicates_length::value; + inline spatial_query(Translator const& t, Predicates const& p, OutIter out_it) : tr(t), pred(p), out_iter(out_it), found_count(0) {} @@ -43,7 +45,7 @@ struct spatial_query { // if node meets predicates // 0 - dummy value - if ( index::detail::predicates_check(pred, 0, it->first) ) + if ( index::detail::predicates_check(pred, 0, it->first) ) rtree::apply_visitor(*this, *it->second); } } @@ -58,7 +60,7 @@ struct spatial_query it != elements.end(); ++it) { // if value meets predicates - if ( index::detail::predicates_check(pred, *it, tr(*it)) ) + if ( index::detail::predicates_check(pred, *it, tr(*it)) ) { out_iter = *it; ++out_iter; diff --git a/include/boost/geometry/index/detail/tuples.hpp b/include/boost/geometry/index/detail/tuples.hpp index d2100e775..28e347bed 100644 --- a/include/boost/geometry/index/detail/tuples.hpp +++ b/include/boost/geometry/index/detail/tuples.hpp @@ -164,6 +164,36 @@ struct add_unique >::type type; }; +template +struct push_back_impl +{ + typedef + boost::tuples::cons< + typename boost::tuples::element::type, + typename push_back_impl::type + > type; + + static type apply(Tuple const& tup, T const& t) + { + return + type( + boost::get(tup), + push_back_impl::apply(tup, t) + ); + } +}; + +template +struct push_back_impl +{ + typedef boost::tuples::cons type; + + static type apply(Tuple const&, T const& t) + { + return type(t, boost::tuples::null_type()); + } +}; + } // namespace tuples }}}} // namespace boost::geometry::index::detail diff --git a/include/boost/geometry/index/distance_predicates.hpp b/include/boost/geometry/index/distance_predicates.hpp index 45f58b7c5..67d111519 100644 --- a/include/boost/geometry/index/distance_predicates.hpp +++ b/include/boost/geometry/index/distance_predicates.hpp @@ -19,6 +19,22 @@ namespace boost { namespace geometry { namespace index { +// nearest predicate generators + +template inline +detail::nearest +nearest(DistancePredicates const& dpred, unsigned k) +{ + return detail::nearest(dpred, k); +} + +template inline +detail::nearest_one +nearest(DistancePredicates const& dpred) +{ + return detail::nearest_one(dpred); +} + // relations generators /*! diff --git a/include/boost/geometry/index/predicates.hpp b/include/boost/geometry/index/predicates.hpp index 4644c2003..b0cacfa77 100644 --- a/include/boost/geometry/index/predicates.hpp +++ b/include/boost/geometry/index/predicates.hpp @@ -19,6 +19,7 @@ #include #include +#include /*! \defgroup predicates Spatial predicates (boost::geometry::index::) @@ -245,6 +246,43 @@ operator!(not_within const& p) { return within(p.geometry); } + +// operator&& generators + +template inline +boost::tuples::cons< + Pred1, + boost::tuples::cons +> +operator&&(Pred1 const& p1, Pred2 const& p2) +{ + return + boost::tuples::cons< + Pred1, + boost::tuples::cons + >( + p1, + boost::tuples::cons(p2, boost::tuples::null_type()) + ); +} + +template inline +typename tuples::push_back_impl< + boost::tuples::cons, + Pred, + 0, + boost::tuples::length >::value +>::type +operator&&(boost::tuples::cons const& t, Pred const& p) +{ + return + tuples::push_back_impl< + boost::tuples::cons, + Pred, + 0, + boost::tuples::length >::value + >::apply(t, p); +} } // namespace detail diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 5e3e6601f..71ec6dc74 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -630,6 +630,75 @@ public: return result; } + template + size_type query(Predicates const& predicates, OutIter out_it) const + { + static const unsigned nearest_count = detail::predicates_count_nearest::value; + static const bool is_nearest = 0 < nearest_count; + BOOST_MPL_ASSERT_MSG((nearest_count <= 1), PASS_ONLY_ONE_NEAREST_PREDICATE, (Predicates)); + + return query_dispatch(predicates, out_it, boost::mpl::bool_()); + } + + template + size_type query(Predicates const& predicates, value_type & v) const + { + static const unsigned nearest_count = detail::predicates_count_nearest::value; + BOOST_MPL_ASSERT_MSG((nearest_count == 1), PASS_NEAREST_PREDICATE_TO_GET_VALUE_AS_RESULT, (Predicates)); + + return query_dispatch(predicates, v, boost::mpl::bool_()); + } + +private: + + template + size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_ const& /*is_nearest*/) const + { + return spatial_query(predicates, out_it); + } + + template + size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_ const& /*is_nearest*/) const + { + static const unsigned nearest_index = detail::predicates_find_nearest::value; + static const bool is_one = detail::predicates_element::type::is_one; + + return query_dispatch_nearest(predicates, out_it, boost::mpl::bool_()); + } + + template + size_type query_dispatch(Predicates const& predicates, value_type & v, boost::mpl::bool_ const& /*is_nearest*/) const + { + static const unsigned nearest_index = detail::predicates_find_nearest::value; + static const bool is_one = detail::predicates_element::type::is_one; + BOOST_MPL_ASSERT_MSG((is_one == 1), PASS_ONE_VALUE_NEAREST_PREDICATE_TO_GET_VALUE_AS_RESULT, (Predicates)); + + typedef detail::predicates_element element_access; + typename element_access::type const& nearest_pred = element_access::get(predicates); + + return this->raw_nearest_one(nearest_pred.distance_predicates, predicates, v); + } + + template + size_type query_dispatch_nearest(Predicates const& predicates, OutIter out_it, boost::mpl::bool_ const& /*is_one*/) const + { + static const unsigned nearest_index = detail::predicates_find_nearest::value; + typedef detail::predicates_element element_access; + typename element_access::type const& nearest_pred = element_access::get(predicates); + return this->raw_nearest_k(nearest_pred.distance_predicates, nearest_pred.count, predicates, out_it); + } + + template + size_type query_dispatch_nearest(Predicates const& predicates, OutIter out_it, boost::mpl::bool_ const& /*is_one*/) const + { + static const unsigned nearest_index = detail::predicates_find_nearest::value; + typedef detail::predicates_element element_access; + typename element_access::type const& nearest_pred = element_access::get(predicates); + return this->raw_nearest_k(nearest_pred.distance_predicates, 1, predicates, out_it); + } + +public: + /*! \brief Finds values meeting spatial predicates, e.g. intersecting some Box. @@ -661,8 +730,8 @@ public: \li If Value copy constructor or copy assignment throws. \li If OutIter dereference or increment throws. */ - template - inline size_type spatial_query(Predicates const& pred, OutIter out_it) const + template inline + size_type spatial_query(Predicates const& pred, OutIter out_it) const { if ( !m_root ) return 0; diff --git a/test/rtree/test_rtree.hpp b/test/rtree/test_rtree.hpp index 404a913fe..40398196d 100644 --- a/test/rtree/test_rtree.hpp +++ b/test/rtree/test_rtree.hpp @@ -559,10 +559,16 @@ void test_spatial_query(Rtree & rtree, Predicates const& pred, std::vector output2; size_t n2 = spatial_query(rtree, pred, std::back_inserter(output2)); - + BOOST_CHECK( n == n2 ); test_exactly_the_same_outputs(rtree, output, output2); + std::vector output3; + size_t n3 = rtree.query(pred, std::back_inserter(output3)); + + BOOST_CHECK( n == n3 ); + test_exactly_the_same_outputs(rtree, output, output3); + test_exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::spatial_queried(pred)); } @@ -771,6 +777,15 @@ void test_nearest_query(Rtree const& rtree, std::vector const& input, Poi BOOST_CHECK(d1 == d2); } } + + Value output2(generate_value_default::apply()); + size_t n_res2 = rtree.query(bgi::nearest(pt), output2); + + BOOST_CHECK(n == n_res2); + if ( 0 < n_res2 ) + { + BOOST_CHECK(rtree.translator().equals(output, output2)); + } } template @@ -861,6 +876,12 @@ void test_nearest_query_k(Rtree const& rtree, std::vector const& input, P output2.resize(found_count, generate_value_default::apply()); test_exactly_the_same_outputs(rtree, output, output2); + + std::vector output3(k, generate_value_default::apply()); + found_count = rtree.query(bgi::nearest(pt, k), output3.begin()); + output3.resize(found_count, generate_value_default::apply()); + + test_exactly_the_same_outputs(rtree, output, output3); } // rtree nearest not found diff --git a/tests/additional_speed.cpp b/tests/additional_speed.cpp index cd6c20b7c..c4a26c12b 100644 --- a/tests/additional_speed.cpp +++ b/tests/additional_speed.cpp @@ -58,8 +58,8 @@ int main() // typedef bgi::rtree RT; //typedef bgi::rtree > RT; //typedef bgi::rtree RT; - - for ( ;; ) + + for (unsigned i = 0 ; i < 10 ; ++i) { RT t; //RT t(bgi::runtime::linear(32, 8)); @@ -126,6 +126,60 @@ int main() std::cout << time << "s - spatial_query(i, !w, !o) " << queries_count << " found " << temp << '\n'; } + { + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 2 ; ++i ) + { + float x1 = coords[i].first; + float y1 = coords[i].second; + float x2 = coords[i+1].first; + float y2 = coords[i+1].second; + float x3 = coords[i+2].first; + float y3 = coords[i+2].second; + result.clear(); + t.spatial_query( + bgi::intersects(B(P(x1 - 10, y1 - 10), P(x1 + 10, y1 + 10))) + && + !bgi::within(B(P(x2 - 10, y2 - 10), P(x2 + 10, y2 + 10))) + && + !bgi::overlaps(B(P(x3 - 10, y3 - 10), P(x3 + 10, y3 + 10))) + , + std::back_inserter(result) + ); + temp += result.size(); + } + double time = tim.elapsed(); + std::cout << time << "s - spatial_query(i && !w && !o) " << queries_count << " found " << temp << '\n'; + } + + { + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 2 ; ++i ) + { + float x1 = coords[i].first; + float y1 = coords[i].second; + float x2 = coords[i+1].first; + float y2 = coords[i+1].second; + float x3 = coords[i+2].first; + float y3 = coords[i+2].second; + result.clear(); + t.query( + bgi::intersects(B(P(x1 - 10, y1 - 10), P(x1 + 10, y1 + 10))) + && + !bgi::within(B(P(x2 - 10, y2 - 10), P(x2 + 10, y2 + 10))) + && + !bgi::overlaps(B(P(x3 - 10, y3 - 10), P(x3 + 10, y3 + 10))) + , + std::back_inserter(result) + ); + temp += result.size(); + } + double time = tim.elapsed(); + std::cout << time << "s - query(i && !w && !o) " << queries_count << " found " << temp << '\n'; + } + result.clear(); { @@ -177,6 +231,55 @@ int main() std::cout << time << "s - nearest_query(bounded(n, c, f), 5) " << (queries_count / 10) << " found " << temp << '\n'; } + { + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 10 ; ++i ) + { + float x = coords[i].first + 100; + float y = coords[i].second + 100; + temp += t.query(bgi::nearest(P(x, y)), result_one); + } + double time = tim.elapsed(); + std::cout << time << "s - query(nearest(P)) " << (queries_count / 10) << " found " << temp << '\n'; + } + + { + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 10 ; ++i ) + { + float x = coords[i].first + 100; + float y = coords[i].second + 100; + result.clear(); + temp += t.query(bgi::nearest(P(x, y), 5), std::back_inserter(result)); + } + double time = tim.elapsed(); + std::cout << time << "s - query(nearest(P, 5)) " << (queries_count / 10) << " found " << temp << '\n'; + } + + { + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count / 10 ; ++i ) + { + float x = coords[i].first + 100; + float y = coords[i].second + 100; + result.clear(); + temp += t.query(bgi::nearest( + bgi::bounded( + bgi::to_nearest(P(x, y)), + bgi::to_centroid(0), + bgi::to_furthest(100000) + ), + 5), + std::back_inserter(result) + ); + } + double time = tim.elapsed(); + std::cout << time << "s - query(nearest(bounded(n, c, f), 5)) " << (queries_count / 10) << " found " << temp << '\n'; + } + { tim.restart(); for (size_t i = 0 ; i < values_count / 10 ; ++i )