[/============================================================================ Boost.Geometry Index Copyright (c) 2011-2012 Adam Wulkiewicz. 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) =============================================================================/] [section Spatial queries] Spatial queries returns `Value`s which meets some predicates. For instance it may be used to retrieve Values intersecting some area or are within some other area. Names of predicates corresponds to names of __boost_geometry__ algorithms. The examples of some basic queries may be found in tables below. The query region and result `Value`s are orange. [table [[intersects(Box) - default] [covered_by(Box)] [disjoint(Box)] [overlaps(Box)] [within(Box)]] [[[$../images/intersects.png]] [[$../images/within.png]] [[$../images/disjoint.png]] [[$../images/overlaps.png]] [[$../images/within.png]]] ] [table [[intersects(Ring)] [intersects(Polygon)] [intersects(MultiPolygon)]] [[[$../images/intersects_ring.png]] [[$../images/intersects_poly.png]] [[$../images/intersects_mpoly.png]]] ] [section Basic queries] There are three ways to perform a spatial query. Following queries returns `__value__`s intersecting some region defined as a box in this example. Method call std::vector<__value__> returned_values; __box__ box_region(...); rt.spatial_query(box_region, std::back_inserter(returned_values)); Function call std::vector<__value__> returned_values; __box__ box_region(...); index::spatial_query(rt, box_region, std::back_inserter(returned_values)); Use of pipe operator generating a range __box__ box_region(...); BOOST_FOREACH(__value__ & v, rt | index::adaptors::spatial_queried(box_region)) ; // do something with v [endsect] [section Spatial predicates] To explicitly define one of the predicates one may pass it to the `spatial_query()` as the first argument. rt.spatial_query(box, std::back_inserter(result)); // default case - intersects rt.spatial_query(index::intersects(box), std::back_inserter(result)); // the same as default rt.spatial_query(index::covered_by(box), std::back_inserter(result)); rt.spatial_query(index::disjont(box), std::back_inserter(result)); rt.spatial_query(index::overlaps(box), std::back_inserter(result)); rt.spatial_query(index::within(box), std::back_inserter(result)); All predicates may be negated, e.g.: rt.spatial_query(!index::intersects(box), std::back_inserter(result)); // the same as rt.spatial_query(index::disjoint(box), std::back_inserter(result)); [endsect] [section Connecting predicates] It's possible to use some number of predicates in one time by passing `std::pair` or `boost::tuple`. These predicates are connected by logical AND. Passing all predicates together not only makes possible to construct advanced queries but is also faster than separate calls because the tree is traversed only once. Traversing is continued and `Value`s are returned only if all predicates are met. Predicates are checked left-to-right so placing most restictive predicates first should accelerate the search. rt.spatial_query( std::make_pair( index::intersects(box1), !index::within(box2) ), std::back_inserter(result)); rt.spatial_query( boost::make_tuple( index::intersects(box1), !index::within(box2), index::overlaps(box3) ), std::back_inserter(result)); [endsect] [section Value predicate] There is also a unique predicate `index::value(...)` taking user-defined function/functor which checks if `__value__` should be returned by the query. bool fun(__value__ const& v) { return v.is_red(); } // ... rt.spatial_query( boost::make_pair( index::intersects(box), index::value(fun) ), std::back_inserter(result)); [endsect] [section Inserting query results into the other R-tree] There are several ways of inserting Values returned by a query to the other R-tree container. The most basic way is creating a temporary container for Values and insert them later. namespace bgi = boost::geometry::index; typedef std::pair __value__; typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree; RTree rt1; /* some inserting into the tree */ std::vector result; rt1.spatial_query(Box(/*...*/), std::back_inserter(result)); RTree rt2(result.begin(), result.end()); However there are better ways. One of these methods is mentioned in the "Creation and modification" section. The insert iterator may be passed directly to the query, which will be the fastest way of inserting query results because temporary container won't be used. RTree rt3; rt1.spatial_query(Box(/*...*/), bgi::inserter(rt3)); If you like Boost.Range you'll appreciate the third option. You may pass the result Range directly to the constructor. RTree rt4(rt1 | bgi::adaptors::spatial_queried(Box(/*...*/))); [endsect] [endsect] [/ Spatial queries /]