How to query if a box is within an rtree
Вопрос
Why does my query to find if a box
is within an rtree
return an empty result?
объяснение
Take the linestring
LINESTRING(1 1, 2 2)
and two polygons
POLYGON((0 0,0 1,1 1,1 0,0 0))
POLYGON((0 0,0 3,3 3,3 0,0 0))
я могу использовать boost::geometry::witin()
to query if the linestring is within either polygon (and it works)
However, if I create an rtree
of the polygons, and put a box
вокруг linestring
, querying if the box
является within
rtree
returns an empty result.
пример
Here's an example showing both the working bg::within(line, polygon)
, and the non-working rtree.query(bgi::within( line_box1 ), ...)
void rtree_within() {
typedef bgm::point< double, 2, bg::cs::cartesian > point;
typedef bgm::box<point> box;
typedef bgm::linestring<point> line;
typedef bgm::polygon<point> polygon;
typedef std::pair<box, unsigned> value;
bgi::rtree<value, bgi::quadratic<16> > rtree;
std::vector<value> result_s;
polygon poly1;
polygon poly2;
line line1;
bg::read_wkt("POLYGON((0 0,0 1,1 1,1 0,0 0))", poly1);
bg::read_wkt("POLYGON((0 0,0 3,3 3,3 0,0 0))", poly2);
bg::read_wkt("LINESTRING(1 1, 2 2)", line1);
std::cout << "line2 in poly1: " << bg::within(line1, poly1) << std::endl;
std::cout << "line2 in poly3: " << bg::within(line1, poly2) << std::endl;
// boxes to insert into rtree
box poly_box1 = bg::return_envelope<box>( poly1 );
rtree.insert(std::make_pair(poly_box1, 0));
box poly_box2 = bg::return_envelope<box>( poly2 );
rtree.insert(std::make_pair(poly_box2, 2));
// box around the line
box line_box1 = bg::return_envelope<box>( line1 );
std::cout << "poly_box1: " << bg::wkt( poly_box1 ) << std::endl; // returns 0
std::cout << "poly_box2: " << bg::wkt( poly_box2 ) << std::endl; // returns 1
std::cout << "line_box1: " << bg::wkt( line_box1 ) << std::endl;
rtree.query(bgi::within( line_box1 ), std::back_inserter( result_s ));
std::cout << "line_box1 within rtree - size: " << result_s.size() << std::endl;
// result_s is empty (size == 0)
}
1 ответ
Когда вы вызываете бесплатную функцию within(geom1,geom2)
возвращает TRUE, если geom1
это внутри geom2
, Но когда вы читаете ссылку на использование within
как предикат
Создайте предикат, определяющий взаимосвязь Value и Geometry. Значение будет возвращено запросом, если bg:: inside (Indexable, Geometry) вернет true.
так что вы пытаетесь проверить, indexable
это внутри geometry
и результат ложный [indexable является прямоугольным, геометрия является линейным]. Вы должны использовать contains
предикат вместо within
используя rtree. contains
Предикат эквивалентен bg::within(Geometry, Indexable)
тогда ваш код работает как положено.