// Boost.Geometry Index // // Spatial query predicates // // Copyright (c) 2011-2022 Adam Wulkiewicz, Lodz, Poland. // // This file was modified by Oracle on 2019-2021. // Modifications copyright (c) 2019-2021 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // // 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 #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL #ifndef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES #define BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES #endif #endif #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. With this predicate query returns indexed Values that contain passed Geometry. Value is 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::predicates::spatial_predicate 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. With this predicate query returns indexed Values that are covered by passed Geometry. Value is 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::predicates::spatial_predicate 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. With this predicate query returns indexed Values that cover passed Geometry. Value is 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::predicates::spatial_predicate 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. With this predicate query returns indexed Values that are disjoint with passed Geometry. Value is 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::predicates::spatial_predicate 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. With this predicate query returns indexed Values that intersect passed Geometry. Value is 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::predicates::spatial_predicate 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. With this predicate query returns indexed Values that overlap passed Geometry. Value is 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::predicates::spatial_predicate overlaps(Geometry const& g) { return detail::predicates::spatial_predicate < Geometry, detail::predicates::overlaps_tag, false >(g); } #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES /*! \brief Generate \c touches() predicate. Generate a predicate defining Value and Geometry relationship. With this predicate query returns indexed Values that touch passed Geometry. Value is 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::predicates::spatial_predicate touches(Geometry const& g) { return detail::predicates::spatial_predicate < Geometry, detail::predicates::touches_tag, false >(g); } #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES /*! \brief Generate \c within() predicate. Generate a predicate defining Value and Geometry relationship. With this predicate query returns indexed Values that are within passed Geometry. Value is 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::predicates::spatial_predicate 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 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)); rt.query(index::intersects(box) && index::satisfies([](Value const& v) { return v.is_red(); }), std::back_inserter(result)); \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::predicates::satisfies satisfies(UnaryPredicate const& pred) { return detail::predicates::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::predicates::nearest nearest(Geometry const& geometry, std::size_t k) { return detail::predicates::nearest(geometry, k); } #ifdef BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES /*! \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::predicates::path path(SegmentOrLinestring const& linestring, std::size_t k) { return detail::predicates::path(linestring, k); } #endif // BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES namespace detail { namespace predicates { // 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 std::tuple operator&&(Pred1 const& p1, Pred2 const& p2) { /*typedef std::conditional_t::value, Pred1, Pred1 const&> stored1; typedef std::conditional_t::value, Pred2, Pred2 const&> stored2;*/ return std::tuple(p1, p2); } template inline typename geometry::tuples::push_back < std::tuple, Pred >::type operator&&(std::tuple const& t, Pred const& p) { //typedef std::conditional_t::value, Pred, Pred const&> stored; return geometry::tuples::push_back < std::tuple, Pred >::apply(t, p); } }} // namespace detail::predicates }}} // namespace boost::geometry::index #endif // BOOST_GEOMETRY_INDEX_PREDICATES_HPP