|
Geometry : |
Subject: [geometry] rtree nearest query with custom geometries
From: Andrea Beconcini (andrea.beconcini_at_[hidden])
Date: 2019-04-16 10:05:42
Hi everybody,
I am trying to use an rtree as an index to a set of triangles to perform
some spatial queries.
The rtree stores std::pair<box, triangles> where box is the boost geometry
box.
The problem occurs with the nearest query and, in particular, when two or
more elements have equivalent boxes,
and I look for just one element, the result may be wrong.
Look at the code below; the problem is that the two triangles have
equivalent bounding boxes, and since
the query returns just one element, the result is the one I inserted first.
Even though the bounding boxes
are the same, the two elements are not, I'd like the query to returns t2
instead.
I think I need to provide an IndexableGetter to my rtree, but according to
https://www.boost.org/doc/libs/1_70_0/libs/geometry/doc/html/geometry/spatial_indexes/creation_and_modification.html
the returned value has to be one of the Indexable concepts (Point, Box, or
Segment) and none of them seems to satisfy
my requirements.
Do I need to make my triangle Indexable? I could not find any reference on
how to do that and what methods are required
for a type to be indexable; can anyone provide any resources that may be
useful?
Thanks, Andrea.
#include <boost/geometry.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point.hpp>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
using point = typename bg::model::point<double, 2, bg::cs::cartesian>;
using box = typename bg::model::box<point>;
bool operator==(point const &a, point const &b)
{
using bg::get;
return get<0>(a) == get<0>(b) && get<1>(a) == get<1>(b);
}
struct triangle
{
point a;
point b;
point c;
bool operator==(triangle const &other) const
{
return a == other.a && b == other.b && c == other.c;
}
};
int main()
{
using indexed_t = typename std::pair<box, triangle>;
using RTree = boost::geometry::index::rtree<indexed_t,
boost::geometry::index::rstar<8>>;
triangle t1{point{0, 0}, point{1, 0}, point{1, 1}};
box b1{point{0, 0}, point{1, 1}};
triangle t2{point{0, 0}, point{1, 1}, point{0, 1}};
box b2{point{0, 0}, point{1, 1}};
RTree rtree;
rtree.insert({b1, t1});
rtree.insert({b2, t2});
auto it = rtree.qbegin(bgi::nearest(point(-1, 0.5), 1));
assert(it->second == t2); // this fails
return 0;
}
Geometry list run by mateusz at loskot.net