mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-12 12:12:10 +00:00
143 lines
5.0 KiB
Plaintext
143 lines
5.0 KiB
Plaintext
[/============================================================================
|
|
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<Pred1, Pred2>`
|
|
or `boost::tuple<Pred1, Pred2, Pred3, ...>`. 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<Box, int> __value__;
|
|
typedef bgi::rtree< __value__, bgi::linear<32, 8> > RTree;
|
|
|
|
RTree rt1;
|
|
/* some inserting into the tree */
|
|
|
|
std::vector<Value> 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 /]
|