mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Implemented all variants of rtree::query() method. spatial and nearest returning 1 and k values.
[SVN r82600]
This commit is contained in:
@@ -28,6 +28,194 @@
|
||||
|
||||
namespace boost { namespace geometry { namespace index { namespace detail {
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// predicate
|
||||
// ------------------------------------------------------------------ //
|
||||
|
||||
template <typename DistancePredicates>
|
||||
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 <typename DistancePredicates>
|
||||
struct predicate_check<nearest<DistancePredicates>, value_tag>
|
||||
{
|
||||
template <typename Value, typename Box>
|
||||
static inline bool apply(nearest<DistancePredicates> const&, Value const&, Box const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DistancePredicates>
|
||||
struct predicate_check<nearest<DistancePredicates>, envelope_tag>
|
||||
{
|
||||
template <typename Value, typename Box>
|
||||
static inline bool apply(nearest<DistancePredicates> const&, Value const&, Box const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DistancePredicates>
|
||||
struct nearest_one
|
||||
{
|
||||
static const bool is_one = true;
|
||||
|
||||
nearest_one(DistancePredicates const& dpred)
|
||||
: distance_predicates(dpred)
|
||||
{}
|
||||
DistancePredicates const& distance_predicates;
|
||||
};
|
||||
|
||||
template <typename DistancePredicates>
|
||||
struct predicate_check<nearest_one<DistancePredicates>, value_tag>
|
||||
{
|
||||
template <typename Value, typename Box>
|
||||
static inline bool apply(nearest_one<DistancePredicates> const&, Value const&, Box const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DistancePredicates>
|
||||
struct predicate_check<nearest_one<DistancePredicates>, envelope_tag>
|
||||
{
|
||||
template <typename Value, typename Box>
|
||||
static inline bool apply(nearest_one<DistancePredicates> const&, Value const&, Box const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// predicates_is_nearest
|
||||
|
||||
template <typename P>
|
||||
struct predicates_is_nearest
|
||||
{
|
||||
static const unsigned value = 0;
|
||||
};
|
||||
|
||||
template <typename DistancePredicates>
|
||||
struct predicates_is_nearest< nearest<DistancePredicates> >
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
template <typename DistancePredicates>
|
||||
struct predicates_is_nearest< nearest_one<DistancePredicates> >
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
// predicates_count_nearest
|
||||
|
||||
template <typename T>
|
||||
struct predicates_count_nearest
|
||||
{
|
||||
static const unsigned value = predicates_is_nearest<T>::value;
|
||||
};
|
||||
|
||||
template <typename F, typename S>
|
||||
struct predicates_count_nearest< std::pair<F, S> >
|
||||
{
|
||||
static const unsigned value = predicates_is_nearest<F>::value
|
||||
+ predicates_is_nearest<S>::value;
|
||||
};
|
||||
|
||||
template <typename Tuple, unsigned N>
|
||||
struct predicates_count_nearest_tuple
|
||||
{
|
||||
static const unsigned value =
|
||||
predicates_is_nearest<typename boost::tuples::element<N-1, Tuple>::type>::value
|
||||
+ predicates_count_nearest_tuple<Tuple, N-1>::value;
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct predicates_count_nearest_tuple<Tuple, 1>
|
||||
{
|
||||
static const unsigned value =
|
||||
predicates_is_nearest<typename boost::tuples::element<0, Tuple>::type>::value;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
struct predicates_count_nearest< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
||||
{
|
||||
static const unsigned value = predicates_count_nearest_tuple<
|
||||
boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
|
||||
boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
|
||||
>::value;
|
||||
};
|
||||
|
||||
template <typename Head, typename Tail>
|
||||
struct predicates_count_nearest< boost::tuples::cons<Head, Tail> >
|
||||
{
|
||||
static const unsigned value = predicates_count_nearest_tuple<
|
||||
boost::tuples::cons<Head, Tail>,
|
||||
boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
|
||||
>::value;
|
||||
};
|
||||
|
||||
// predicates_find_nearest
|
||||
|
||||
template <typename T>
|
||||
struct predicates_find_nearest
|
||||
{
|
||||
static const unsigned value = predicates_is_nearest<T>::value ? 0 : 1;
|
||||
};
|
||||
|
||||
template <typename F, typename S>
|
||||
struct predicates_find_nearest< std::pair<F, S> >
|
||||
{
|
||||
static const unsigned value = predicates_is_nearest<F>::value ? 0 :
|
||||
(predicates_is_nearest<S>::value ? 1 : 2);
|
||||
};
|
||||
|
||||
template <typename Tuple, unsigned N>
|
||||
struct predicates_find_nearest_tuple
|
||||
{
|
||||
static const bool is_found = predicates_find_nearest_tuple<Tuple, N-1>::is_found
|
||||
|| predicates_is_nearest<typename boost::tuples::element<N-1, Tuple>::type>::value;
|
||||
|
||||
static const unsigned value = predicates_find_nearest_tuple<Tuple, N-1>::is_found ?
|
||||
predicates_find_nearest_tuple<Tuple, N-1>::value :
|
||||
(predicates_is_nearest<typename boost::tuples::element<N-1, Tuple>::type>::value ?
|
||||
N-1 : boost::tuples::length<Tuple>::value);
|
||||
};
|
||||
|
||||
template <typename Tuple>
|
||||
struct predicates_find_nearest_tuple<Tuple, 1>
|
||||
{
|
||||
static const bool is_found = predicates_is_nearest<typename boost::tuples::element<0, Tuple>::type>::value;
|
||||
static const unsigned value = is_found ? 0 : boost::tuples::length<Tuple>::value;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
struct predicates_find_nearest< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
||||
{
|
||||
static const unsigned value = predicates_find_nearest_tuple<
|
||||
boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
|
||||
boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value
|
||||
>::value;
|
||||
};
|
||||
|
||||
template <typename Head, typename Tail>
|
||||
struct predicates_find_nearest< boost::tuples::cons<Head, Tail> >
|
||||
{
|
||||
static const unsigned value = predicates_find_nearest_tuple<
|
||||
boost::tuples::cons<Head, Tail>,
|
||||
boost::tuples::length< boost::tuples::cons<Head, Tail> >::value
|
||||
>::value;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// relations
|
||||
// ------------------------------------------------------------------ //
|
||||
@@ -364,7 +552,7 @@ struct distances_calc_impl_rel<
|
||||
|
||||
// distances_calc_impl_tuple
|
||||
|
||||
template <typename Distances, typename Point, typename Indexable, size_t N>
|
||||
template <typename Distances, typename Point, typename Indexable, unsigned N>
|
||||
struct distances_calc_impl_tuple
|
||||
{
|
||||
// TODO MPL ASSERT 0 < N
|
||||
|
||||
@@ -438,40 +438,158 @@ struct predicate_check<not_within<Geometry>, envelope_tag>
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// predicates_length
|
||||
// ------------------------------------------------------------------ //
|
||||
|
||||
template <typename T>
|
||||
struct predicates_length
|
||||
{
|
||||
static const unsigned value = 1;
|
||||
};
|
||||
|
||||
template <typename F, typename S>
|
||||
struct predicates_length< std::pair<F, S> >
|
||||
{
|
||||
static const unsigned value = 2;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
struct predicates_length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
||||
{
|
||||
static const unsigned value = boost::tuples::length< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >::value;
|
||||
};
|
||||
|
||||
template <typename Head, typename Tail>
|
||||
struct predicates_length< boost::tuples::cons<Head, Tail> >
|
||||
{
|
||||
static const unsigned value = boost::tuples::length< boost::tuples::cons<Head, Tail> >::value;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// predicates_element
|
||||
// ------------------------------------------------------------------ //
|
||||
|
||||
template <unsigned I, typename T>
|
||||
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 <unsigned I, typename F, typename S>
|
||||
struct predicates_element< I, std::pair<F, S> >
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((I < 2), INVALID_INDEX, (predicates_element));
|
||||
|
||||
typedef F type;
|
||||
static type const& get(std::pair<F, S> const& p) { return p.first; }
|
||||
};
|
||||
|
||||
template <typename F, typename S>
|
||||
struct predicates_element< 1, std::pair<F, S> >
|
||||
{
|
||||
typedef S type;
|
||||
static type const& get(std::pair<F, S> const& p) { return p.second; }
|
||||
};
|
||||
|
||||
template <unsigned I, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
struct predicates_element< I, boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
|
||||
{
|
||||
typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicate_type;
|
||||
|
||||
typedef typename boost::tuples::element<I, predicate_type>::type type;
|
||||
static type const& get(predicate_type const& p) { return boost::get<I>(p); }
|
||||
};
|
||||
|
||||
template <unsigned I, typename Head, typename Tail>
|
||||
struct predicates_element< I, boost::tuples::cons<Head, Tail> >
|
||||
{
|
||||
typedef boost::tuples::cons<Head, Tail> predicate_type;
|
||||
|
||||
typedef typename boost::tuples::element<I, predicate_type>::type type;
|
||||
static type const& get(predicate_type const& p) { return boost::get<I>(p); }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// predicates_check
|
||||
// ------------------------------------------------------------------ //
|
||||
|
||||
template <typename TuplePredicates, typename Tag, unsigned int N>
|
||||
template <typename PairPredicates, typename Tag, unsigned First, unsigned Last>
|
||||
struct predicates_check_pair {};
|
||||
|
||||
template <typename PairPredicates, typename Tag, unsigned I>
|
||||
struct predicates_check_pair<PairPredicates, Tag, I, I>
|
||||
{
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PairPredicates, typename Tag>
|
||||
struct predicates_check_pair<PairPredicates, Tag, 0, 1>
|
||||
{
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PairPredicates, typename Tag>
|
||||
struct predicates_check_pair<PairPredicates, Tag, 1, 2>
|
||||
{
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PairPredicates, typename Tag>
|
||||
struct predicates_check_pair<PairPredicates, Tag, 0, 2>
|
||||
{
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(PairPredicates const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return predicate_check<typename PairPredicates::first_type, Tag>::apply(p.first, v, i)
|
||||
&& predicate_check<typename PairPredicates::second_type, Tag>::apply(p.second, v, i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TuplePredicates, typename Tag, unsigned First, unsigned Last>
|
||||
struct predicates_check_tuple
|
||||
{
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return predicates_check_tuple<TuplePredicates, Tag, N - 1>::apply(p, v, i)
|
||||
&& predicate_check<
|
||||
typename boost::tuples::element<N - 1, TuplePredicates>::type,
|
||||
Tag
|
||||
>::apply(boost::get<N - 1>(p), v, i);
|
||||
return
|
||||
predicate_check<
|
||||
typename boost::tuples::element<First, TuplePredicates>::type,
|
||||
Tag
|
||||
>::apply(boost::get<First>(p), v, i) &&
|
||||
predicates_check_tuple<TuplePredicates, Tag, First+1, Last>::apply(p, v, i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TuplePredicates, typename Tag>
|
||||
struct predicates_check_tuple<TuplePredicates, Tag, 1>
|
||||
template <typename TuplePredicates, typename Tag, unsigned First>
|
||||
struct predicates_check_tuple<TuplePredicates, Tag, First, First>
|
||||
{
|
||||
template <typename Value, typename Indexable>
|
||||
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 <typename Predicate, typename Tag>
|
||||
template <typename Predicate, typename Tag, size_t First, size_t Last>
|
||||
struct predicates_check_impl
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((First < 1 && Last <= 1 && First <= Last), INVALID_INDEXES, (predicates_check_impl));
|
||||
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(Predicate const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
@@ -479,9 +597,11 @@ struct predicates_check_impl
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Predicate1, typename Predicate2, typename Tag>
|
||||
struct predicates_check_impl<std::pair<Predicate1, Predicate2>, Tag>
|
||||
template <typename Predicate1, typename Predicate2, typename Tag, size_t First, size_t Last>
|
||||
struct predicates_check_impl<std::pair<Predicate1, Predicate2>, Tag, First, Last>
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((First < 2 && Last <= 2 && First <= Last), INVALID_INDEXES, (predicates_check_impl));
|
||||
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(std::pair<Predicate1, Predicate2> const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
@@ -493,30 +613,53 @@ struct predicates_check_impl<std::pair<Predicate1, Predicate2>, 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<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>,
|
||||
Tag
|
||||
Tag, First, Last
|
||||
>
|
||||
{
|
||||
typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> predicates_type;
|
||||
|
||||
static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
|
||||
BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl));
|
||||
|
||||
template <typename Value, typename Indexable>
|
||||
static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return predicates_check_tuple<
|
||||
predicates_type,
|
||||
Tag,
|
||||
boost::tuples::length<predicates_type>::value
|
||||
Tag, First, Last
|
||||
>::apply(p, v, i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tag, typename Predicates, typename Value, typename Indexable>
|
||||
template <typename Head, typename Tail, typename Tag, unsigned First, unsigned Last>
|
||||
struct predicates_check_impl<
|
||||
boost::tuples::cons<Head, Tail>,
|
||||
Tag, First, Last
|
||||
>
|
||||
{
|
||||
typedef boost::tuples::cons<Head, Tail> predicates_type;
|
||||
|
||||
static const unsigned pred_len = boost::tuples::length<predicates_type>::value;
|
||||
BOOST_MPL_ASSERT_MSG((First < pred_len && Last <= pred_len && First <= Last), INVALID_INDEXES, (predicates_check_impl));
|
||||
|
||||
template <typename Value, typename Indexable>
|
||||
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 <typename Tag, unsigned First, unsigned Last, typename Predicates, typename Value, typename Indexable>
|
||||
inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i)
|
||||
{
|
||||
return detail::predicates_check_impl<Predicates, Tag>
|
||||
return detail::predicates_check_impl<Predicates, Tag, First, Last>
|
||||
::apply(p, v, i);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,8 @@ public:
|
||||
index::detail::value_tag
|
||||
> value_distances_predicates_check;
|
||||
|
||||
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::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<index::detail::envelope_tag>(m_pred, 0, it->first) )
|
||||
if ( index::detail::predicates_check<index::detail::envelope_tag, 0, predicates_len>(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<index::detail::value_tag>(m_pred, *it, m_translator(*it)) )
|
||||
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(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));
|
||||
|
||||
@@ -28,6 +28,8 @@ struct spatial_query
|
||||
typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
|
||||
typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
|
||||
|
||||
static const unsigned predicates_len = index::detail::predicates_length<Predicates>::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<index::detail::envelope_tag>(pred, 0, it->first) )
|
||||
if ( index::detail::predicates_check<index::detail::envelope_tag, 0, predicates_len>(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<index::detail::value_tag>(pred, *it, tr(*it)) )
|
||||
if ( index::detail::predicates_check<index::detail::value_tag, 0, predicates_len>(pred, *it, tr(*it)) )
|
||||
{
|
||||
out_iter = *it;
|
||||
++out_iter;
|
||||
|
||||
@@ -164,6 +164,36 @@ struct add_unique
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename Tuple, typename T, size_t I, size_t N>
|
||||
struct push_back_impl
|
||||
{
|
||||
typedef
|
||||
boost::tuples::cons<
|
||||
typename boost::tuples::element<I, Tuple>::type,
|
||||
typename push_back_impl<Tuple, T, I+1, N>::type
|
||||
> type;
|
||||
|
||||
static type apply(Tuple const& tup, T const& t)
|
||||
{
|
||||
return
|
||||
type(
|
||||
boost::get<I>(tup),
|
||||
push_back_impl<Tuple, T, I+1, N>::apply(tup, t)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tuple, typename T, size_t N>
|
||||
struct push_back_impl<Tuple, T, N, N>
|
||||
{
|
||||
typedef boost::tuples::cons<T, boost::tuples::null_type> type;
|
||||
|
||||
static type apply(Tuple const&, T const& t)
|
||||
{
|
||||
return type(t, boost::tuples::null_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace tuples
|
||||
|
||||
}}}} // namespace boost::geometry::index::detail
|
||||
|
||||
@@ -19,6 +19,22 @@
|
||||
|
||||
namespace boost { namespace geometry { namespace index {
|
||||
|
||||
// nearest predicate generators
|
||||
|
||||
template <typename DistancePredicates> inline
|
||||
detail::nearest<DistancePredicates>
|
||||
nearest(DistancePredicates const& dpred, unsigned k)
|
||||
{
|
||||
return detail::nearest<DistancePredicates>(dpred, k);
|
||||
}
|
||||
|
||||
template <typename DistancePredicates> inline
|
||||
detail::nearest_one<DistancePredicates>
|
||||
nearest(DistancePredicates const& dpred)
|
||||
{
|
||||
return detail::nearest_one<DistancePredicates>(dpred);
|
||||
}
|
||||
|
||||
// relations generators
|
||||
|
||||
/*!
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <boost/geometry/algorithms/covered_by.hpp>
|
||||
|
||||
#include <boost/geometry/index/detail/predicates.hpp>
|
||||
#include <boost/geometry/index/detail/tuples.hpp>
|
||||
|
||||
/*!
|
||||
\defgroup predicates Spatial predicates (boost::geometry::index::)
|
||||
@@ -245,6 +246,43 @@ operator!(not_within<Geometry> const& p)
|
||||
{
|
||||
return within<Geometry>(p.geometry);
|
||||
}
|
||||
|
||||
// operator&& generators
|
||||
|
||||
template <typename Pred1, typename Pred2> inline
|
||||
boost::tuples::cons<
|
||||
Pred1,
|
||||
boost::tuples::cons<Pred2, boost::tuples::null_type>
|
||||
>
|
||||
operator&&(Pred1 const& p1, Pred2 const& p2)
|
||||
{
|
||||
return
|
||||
boost::tuples::cons<
|
||||
Pred1,
|
||||
boost::tuples::cons<Pred2, boost::tuples::null_type>
|
||||
>(
|
||||
p1,
|
||||
boost::tuples::cons<Pred2, boost::tuples::null_type>(p2, boost::tuples::null_type())
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Head, typename Tail, typename Pred> inline
|
||||
typename tuples::push_back_impl<
|
||||
boost::tuples::cons<Head, Tail>,
|
||||
Pred,
|
||||
0,
|
||||
boost::tuples::length<boost::tuples::cons<Head, Tail> >::value
|
||||
>::type
|
||||
operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
|
||||
{
|
||||
return
|
||||
tuples::push_back_impl<
|
||||
boost::tuples::cons<Head, Tail>,
|
||||
Pred,
|
||||
0,
|
||||
boost::tuples::length<boost::tuples::cons<Head, Tail> >::value
|
||||
>::apply(t, p);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
@@ -630,6 +630,75 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Predicates, typename OutIter>
|
||||
size_type query(Predicates const& predicates, OutIter out_it) const
|
||||
{
|
||||
static const unsigned nearest_count = detail::predicates_count_nearest<Predicates>::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_<is_nearest>());
|
||||
}
|
||||
|
||||
template <typename Predicates>
|
||||
size_type query(Predicates const& predicates, value_type & v) const
|
||||
{
|
||||
static const unsigned nearest_count = detail::predicates_count_nearest<Predicates>::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_<true>());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename Predicates, typename OutIter>
|
||||
size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> const& /*is_nearest*/) const
|
||||
{
|
||||
return spatial_query(predicates, out_it);
|
||||
}
|
||||
|
||||
template <typename Predicates, typename OutIter>
|
||||
size_type query_dispatch(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_nearest*/) const
|
||||
{
|
||||
static const unsigned nearest_index = detail::predicates_find_nearest<Predicates>::value;
|
||||
static const bool is_one = detail::predicates_element<nearest_index, Predicates>::type::is_one;
|
||||
|
||||
return query_dispatch_nearest(predicates, out_it, boost::mpl::bool_<is_one>());
|
||||
}
|
||||
|
||||
template <typename Predicates>
|
||||
size_type query_dispatch(Predicates const& predicates, value_type & v, boost::mpl::bool_<true> const& /*is_nearest*/) const
|
||||
{
|
||||
static const unsigned nearest_index = detail::predicates_find_nearest<Predicates>::value;
|
||||
static const bool is_one = detail::predicates_element<nearest_index, Predicates>::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<nearest_index, Predicates> 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 <typename Predicates, typename OutIter>
|
||||
size_type query_dispatch_nearest(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<false> const& /*is_one*/) const
|
||||
{
|
||||
static const unsigned nearest_index = detail::predicates_find_nearest<Predicates>::value;
|
||||
typedef detail::predicates_element<nearest_index, Predicates> 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 <typename Predicates, typename OutIter>
|
||||
size_type query_dispatch_nearest(Predicates const& predicates, OutIter out_it, boost::mpl::bool_<true> const& /*is_one*/) const
|
||||
{
|
||||
static const unsigned nearest_index = detail::predicates_find_nearest<Predicates>::value;
|
||||
typedef detail::predicates_element<nearest_index, Predicates> 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 <typename Predicates, typename OutIter>
|
||||
inline size_type spatial_query(Predicates const& pred, OutIter out_it) const
|
||||
template <typename Predicates, typename OutIter> inline
|
||||
size_type spatial_query(Predicates const& pred, OutIter out_it) const
|
||||
{
|
||||
if ( !m_root )
|
||||
return 0;
|
||||
|
||||
@@ -559,10 +559,16 @@ void test_spatial_query(Rtree & rtree, Predicates const& pred, std::vector<Value
|
||||
|
||||
std::vector<Value> 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<Value> 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<Value> const& input, Poi
|
||||
BOOST_CHECK(d1 == d2);
|
||||
}
|
||||
}
|
||||
|
||||
Value output2(generate_value_default<Value>::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 <typename Rtree, typename Point>
|
||||
@@ -861,6 +876,12 @@ void test_nearest_query_k(Rtree const& rtree, std::vector<Value> const& input, P
|
||||
output2.resize(found_count, generate_value_default<Value>::apply());
|
||||
|
||||
test_exactly_the_same_outputs(rtree, output, output2);
|
||||
|
||||
std::vector<Value> output3(k, generate_value_default<Value>::apply());
|
||||
found_count = rtree.query(bgi::nearest(pt, k), output3.begin());
|
||||
output3.resize(found_count, generate_value_default<Value>::apply());
|
||||
|
||||
test_exactly_the_same_outputs(rtree, output, output3);
|
||||
}
|
||||
|
||||
// rtree nearest not found
|
||||
|
||||
@@ -58,8 +58,8 @@ int main()
|
||||
// typedef bgi::rtree<B, bgi::runtime::quadratic > RT;
|
||||
//typedef bgi::rtree<B, bgi::rstar<32, 8> > RT;
|
||||
//typedef bgi::rtree<B, bgi::runtime::rstar > 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 )
|
||||
|
||||
Reference in New Issue
Block a user