422 lines
12 KiB
C++
422 lines
12 KiB
C++
|
// Boost.Geometry Index
|
||
|
//
|
||
|
// Spatial query predicates
|
||
|
//
|
||
|
// Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland.
|
||
|
//
|
||
|
// Use, modification and distribution is subject to the Boost Software License,
|
||
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||
|
|
||
|
#ifndef BOOST_GEOMETRY_INDEX_PREDICATES_HPP
|
||
|
#define BOOST_GEOMETRY_INDEX_PREDICATES_HPP
|
||
|
|
||
|
#include <boost/geometry/index/detail/predicates.hpp>
|
||
|
#include <boost/geometry/index/detail/tuples.hpp>
|
||
|
|
||
|
/*!
|
||
|
\defgroup predicates Predicates (boost::geometry::index::)
|
||
|
*/
|
||
|
|
||
|
namespace boost { namespace geometry { namespace index {
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c contains() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::within(Geometry, Indexable)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::contains(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::contains_tag, false>
|
||
|
contains(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::contains_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c covered_by() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::covered_by(Indexable, Geometry)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::covered_by(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::covered_by_tag, false>
|
||
|
covered_by(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::covered_by_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c covers() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::covered_by(Geometry, Indexable)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::covers(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::covers_tag, false>
|
||
|
covers(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::covers_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c disjoint() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::disjoint(Indexable, Geometry)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::disjoint(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::disjoint_tag, false>
|
||
|
disjoint(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::disjoint_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c intersects() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::intersects(Indexable, Geometry)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::intersects(box), std::back_inserter(result));
|
||
|
bgi::query(spatial_index, bgi::intersects(ring), std::back_inserter(result));
|
||
|
bgi::query(spatial_index, bgi::intersects(polygon), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::intersects_tag, false>
|
||
|
intersects(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::intersects_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c overlaps() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::overlaps(Indexable, Geometry)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::overlaps(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::overlaps_tag, false>
|
||
|
overlaps(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::overlaps_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c touches() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::touches(Indexable, Geometry)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::touches_tag, false>
|
||
|
touches(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::touches_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
||
|
|
||
|
/*!
|
||
|
\brief Generate \c within() predicate.
|
||
|
|
||
|
Generate a predicate defining Value and Geometry relationship.
|
||
|
Value will be returned by the query if <tt>bg::within(Indexable, Geometry)</tt>
|
||
|
returns true.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::within(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam Geometry The Geometry type.
|
||
|
|
||
|
\param g The Geometry object.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::spatial_predicate<Geometry, detail::predicates::within_tag, false>
|
||
|
within(Geometry const& g)
|
||
|
{
|
||
|
return detail::predicates::spatial_predicate
|
||
|
<
|
||
|
Geometry,
|
||
|
detail::predicates::within_tag,
|
||
|
false
|
||
|
>(g);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate satisfies() predicate.
|
||
|
|
||
|
A wrapper around user-defined UnaryPredicate checking if Value should be returned by spatial query.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bool is_red(Value const& v) { return v.is_red(); }
|
||
|
|
||
|
struct is_red_o {
|
||
|
template <typename Value> bool operator()(Value const& v) { return v.is_red(); }
|
||
|
}
|
||
|
|
||
|
// ...
|
||
|
|
||
|
rt.query(index::intersects(box) && index::satisfies(is_red),
|
||
|
std::back_inserter(result));
|
||
|
|
||
|
rt.query(index::intersects(box) && index::satisfies(is_red_o()),
|
||
|
std::back_inserter(result));
|
||
|
|
||
|
#ifndef BOOST_NO_CXX11_LAMBDAS
|
||
|
rt.query(index::intersects(box) && index::satisfies([](Value const& v) { return v.is_red(); }),
|
||
|
std::back_inserter(result));
|
||
|
#endif
|
||
|
\endverbatim
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\tparam UnaryPredicate A type of unary predicate function or function object.
|
||
|
|
||
|
\param pred The unary predicate function or function object.
|
||
|
*/
|
||
|
template <typename UnaryPredicate> inline
|
||
|
detail::predicates::satisfies<UnaryPredicate, false>
|
||
|
satisfies(UnaryPredicate const& pred)
|
||
|
{
|
||
|
return detail::predicates::satisfies<UnaryPredicate, false>(pred);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief Generate nearest() predicate.
|
||
|
|
||
|
When nearest predicate is passed to the query, k-nearest neighbour search will be performed.
|
||
|
\c nearest() predicate takes a \c Geometry from which distances to \c Values are calculated
|
||
|
and the maximum number of \c Values that should be returned. Internally
|
||
|
boost::geometry::comparable_distance() is used to perform the calculation.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::nearest(pt, 5), std::back_inserter(result));
|
||
|
bgi::query(spatial_index, bgi::nearest(pt, 5) && bgi::intersects(box), std::back_inserter(result));
|
||
|
bgi::query(spatial_index, bgi::nearest(box, 5), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\warning
|
||
|
Only one \c nearest() predicate may be used in a query.
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\param geometry The geometry from which distance is calculated.
|
||
|
\param k The maximum number of values to return.
|
||
|
*/
|
||
|
template <typename Geometry> inline
|
||
|
detail::predicates::nearest<Geometry>
|
||
|
nearest(Geometry const& geometry, unsigned k)
|
||
|
{
|
||
|
return detail::predicates::nearest<Geometry>(geometry, k);
|
||
|
}
|
||
|
|
||
|
#ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
||
|
|
||
|
/*!
|
||
|
\brief Generate path() predicate.
|
||
|
|
||
|
When path predicate is passed to the query, the returned values are k values along the path closest to
|
||
|
its begin. \c path() predicate takes a \c Segment or a \c Linestring defining the path and the maximum
|
||
|
number of \c Values that should be returned.
|
||
|
|
||
|
\par Example
|
||
|
\verbatim
|
||
|
bgi::query(spatial_index, bgi::path(segment, 5), std::back_inserter(result));
|
||
|
bgi::query(spatial_index, bgi::path(linestring, 5) && bgi::intersects(box), std::back_inserter(result));
|
||
|
\endverbatim
|
||
|
|
||
|
\warning
|
||
|
Only one distance predicate (\c nearest() or \c path()) may be used in a query.
|
||
|
|
||
|
\ingroup predicates
|
||
|
|
||
|
\param linestring The path along which distance is calculated.
|
||
|
\param k The maximum number of values to return.
|
||
|
*/
|
||
|
template <typename SegmentOrLinestring> inline
|
||
|
detail::predicates::path<SegmentOrLinestring>
|
||
|
path(SegmentOrLinestring const& linestring, unsigned k)
|
||
|
{
|
||
|
return detail::predicates::path<SegmentOrLinestring>(linestring, k);
|
||
|
}
|
||
|
|
||
|
#endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL
|
||
|
|
||
|
namespace detail { namespace predicates {
|
||
|
|
||
|
// operator! generators
|
||
|
|
||
|
template <typename Fun, bool Negated> inline
|
||
|
satisfies<Fun, !Negated>
|
||
|
operator!(satisfies<Fun, Negated> const& p)
|
||
|
{
|
||
|
return satisfies<Fun, !Negated>(p);
|
||
|
}
|
||
|
|
||
|
template <typename Geometry, typename Tag, bool Negated> inline
|
||
|
spatial_predicate<Geometry, Tag, !Negated>
|
||
|
operator!(spatial_predicate<Geometry, Tag, Negated> const& p)
|
||
|
{
|
||
|
return spatial_predicate<Geometry, Tag, !Negated>(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)
|
||
|
{
|
||
|
/*typedef typename boost::mpl::if_c<is_predicate<Pred1>::value, Pred1, Pred1 const&>::type stored1;
|
||
|
typedef typename boost::mpl::if_c<is_predicate<Pred2>::value, Pred2, Pred2 const&>::type stored2;*/
|
||
|
namespace bt = boost::tuples;
|
||
|
|
||
|
return
|
||
|
bt::cons< Pred1, bt::cons<Pred2, bt::null_type> >
|
||
|
( p1, bt::cons<Pred2, bt::null_type>(p2, bt::null_type()) );
|
||
|
}
|
||
|
|
||
|
template <typename Head, typename Tail, typename Pred> inline
|
||
|
typename tuples::push_back<
|
||
|
boost::tuples::cons<Head, Tail>, Pred
|
||
|
>::type
|
||
|
operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
|
||
|
{
|
||
|
//typedef typename boost::mpl::if_c<is_predicate<Pred>::value, Pred, Pred const&>::type stored;
|
||
|
namespace bt = boost::tuples;
|
||
|
|
||
|
return
|
||
|
tuples::push_back<
|
||
|
bt::cons<Head, Tail>, Pred
|
||
|
>::apply(t, p);
|
||
|
}
|
||
|
|
||
|
}} // namespace detail::predicates
|
||
|
|
||
|
}}} // namespace boost::geometry::index
|
||
|
|
||
|
#endif // BOOST_GEOMETRY_INDEX_PREDICATES_HPP
|