// Boost.Geometry Index // // Spatial query predicates // // Copyright (c) 2011-2014 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 #include #include #include #include /*! \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 bg::within(Geometry, Indexable) 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 inline detail::spatial_predicate contains(Geometry const& g) { return detail::spatial_predicate(g); } /*! \brief Generate \c covered_by() predicate. Generate a predicate defining Value and Geometry relationship. Value will be returned by the query if bg::covered_by(Indexable, Geometry) 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 inline detail::spatial_predicate covered_by(Geometry const& g) { return detail::spatial_predicate(g); } /*! \brief Generate \c covers() predicate. Generate a predicate defining Value and Geometry relationship. Value will be returned by the query if bg::covered_by(Geometry, Indexable) 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 inline detail::spatial_predicate covers(Geometry const& g) { return detail::spatial_predicate(g); } /*! \brief Generate \c disjoint() predicate. Generate a predicate defining Value and Geometry relationship. Value will be returned by the query if bg::disjoint(Indexable, Geometry) 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 inline detail::spatial_predicate disjoint(Geometry const& g) { return detail::spatial_predicate(g); } /*! \brief Generate \c intersects() predicate. Generate a predicate defining Value and Geometry relationship. Value will be returned by the query if bg::intersects(Indexable, Geometry) 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 inline detail::spatial_predicate intersects(Geometry const& g) { return detail::spatial_predicate(g); } /*! \brief Generate \c overlaps() predicate. Generate a predicate defining Value and Geometry relationship. Value will be returned by the query if bg::overlaps(Indexable, Geometry) 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 inline detail::spatial_predicate overlaps(Geometry const& g) { return detail::spatial_predicate(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 bg::touches(Indexable, Geometry) returns true. \ingroup predicates \tparam Geometry The Geometry type. \param g The Geometry object. */ template inline detail::spatial_predicate touches(Geometry const& g) { return detail::spatial_predicate(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 bg::within(Indexable, Geometry) 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 inline detail::spatial_predicate within(Geometry const& g) { return detail::spatial_predicate(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 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 inline detail::satisfies satisfies(UnaryPredicate const& pred) { return detail::satisfies(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 inline detail::nearest nearest(Geometry const& geometry, unsigned k) { return detail::nearest(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 inline detail::path path(SegmentOrLinestring const& linestring, unsigned k) { return detail::path(linestring, k); } #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL namespace detail { // operator! generators template inline satisfies operator!(satisfies const& p) { return satisfies(p); } template inline spatial_predicate operator!(spatial_predicate const& p) { return spatial_predicate(p.geometry); } // operator&& generators template inline boost::tuples::cons< Pred1, boost::tuples::cons > operator&&(Pred1 const& p1, Pred2 const& p2) { /*typedef typename boost::mpl::if_c::value, Pred1, Pred1 const&>::type stored1; typedef typename boost::mpl::if_c::value, Pred2, Pred2 const&>::type stored2;*/ namespace bt = boost::tuples; return bt::cons< Pred1, bt::cons > ( p1, bt::cons(p2, bt::null_type()) ); } template inline typename tuples::push_back< boost::tuples::cons, Pred >::type operator&&(boost::tuples::cons const& t, Pred const& p) { //typedef typename boost::mpl::if_c::value, Pred, Pred const&>::type stored; namespace bt = boost::tuples; return tuples::push_back< bt::cons, Pred >::apply(t, p); } } // namespace detail }}} // namespace boost::geometry::index #endif // BOOST_GEOMETRY_INDEX_PREDICATES_HPP