this example, I wrote one method for allowing rtree.query to work: i want to get intersects with two segments
using Point2d =
boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian>;
using Segment2d = boost::geometry::model::segment<Point2d>;
using SegmentRtree =
boost::geometry::index::rtree<Segment2d, boost::geometry::index::rstar<16>>;
for (int point_index = 0;
point_index + 1 < segment.line_segment().point_size();
point_index++) {
const Segment2d segment_in_range = {
{segment.line_segment().point()[point_index].x(),
segment.line_segment().point()[point_index].y()},
{segment.line_segment().point()[point_index + 1].x(),
segment.line_segment().point()[point_index + 1].y()}};
uncrossable_segments_in_range.insert(segment_in_range);
Some of the errors I am getting:
/home/xx/xx/xx/xx/xx/xx/xx/xx.cc:220:66: required from here
/home/xx/xx/xx/build_x86/_deps/boost-src/include/boost/geometry/strategies/index/services.hpp:31:5: error: static assertion failed: Not implemented for this coordinate system.
31 | BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It looks 100% like you've forgotten to include some header.
The message doesn't state "you don't specify a coordinate system" (you do, it's in your point type). It says "the specialization (for this algorithm/strategy/trait etc...) for this combination has not been found".
However, you don't show the includes, so we can't tell. Also, the code you do show refers to a lot of proprietary types not related to Boost Geometry (point_size()
, line_segment()
, point()[]
all seem unrelated to Boost Geometry).
Even the .x()
and .y()
contradict the point type you defined. point<>
does not have these members. boost::geometry::model::d2::point_xy<>
does, though.
So, the best I can do is make up a lot (!!!) of code to make your code compile:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/segment.hpp>
namespace bg = boost::geometry;
namespace bgm = bg::model;
namespace bgi = bg::index;
// using Point2d = bgm::point<double, 2, bg::cs::cartesian>;
using Point2d = bgm::d2::point_xy<double, bg::cs::cartesian>;
using Segment2d = bgm::segment<Point2d>;
using SegmentRtree = bgi::rtree<Segment2d, bgi::rstar<16>>;
/////// stubs to make the code look like the question code...
struct {
auto const& line_segment() { return ls_; }
private:
struct {
Segment2d data_;
size_t point_size() const { return 2; }
struct proxy {
Segment2d const& ref_;
auto operator[](unsigned i) const {
switch (i) {
case 0: return ref_.first;
case 1: return ref_.second;
}
throw std::range_error("i");
}
};
proxy point() const { return {data_}; }
} ls_;
} segment;
struct Comparer {
using Point = Point2d;
using Base = std::pair<Point2d, Point2d>;
bool operator()(Point const& a, Point const& b) const {
return std::tie(a.x(), a.y()) < std::tie(b.x(), b.y());
}
bool operator()(Base const& a, Base const& b) const {
return operator()(a.first, b.first) ||
(bg::equals(a.first, b.first) && operator()(a.second, b.second));
}
};
std::set<Segment2d, Comparer> uncrossable_segments_in_range;
/////// end stubs
int main() {
for (unsigned point_index = 0; point_index + 1 < segment.line_segment().point_size(); point_index++) {
Segment2d segment_in_range{{segment.line_segment().point()[point_index].x(),
segment.line_segment().point()[point_index].y()},
{segment.line_segment().point()[point_index + 1].x(),
segment.line_segment().point()[point_index + 1].y()}};
uncrossable_segments_in_range.insert(segment_in_range);
}
}
It would help a little to make your loop more readable:
auto& ls = segment.line_segment();
for (unsigned i = 0; i + 1 < ls.point_size(); i++) {
auto&& p = ls.point();
uncrossable_segments_in_range.emplace(Point2d{p[i].x(), p[i].y()},
Point2d{p[i + 1].x(), p[i + 1].y()});
}
Now, this looks like improbable amounts of (poor) code to have to imagine. Also, it does nothing with rtree
, which is supposedly your question?
I just had a brainwave. Probably uncrossable_segments_in_range
was supposed to be your rtree
? And the whole loop was building the rtree from [some unrelated data structure]. Here's how I imagine you'd write that code:
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/segment.hpp>
namespace bg = boost::geometry;
namespace bgm = bg::model;
namespace bgi = bg::index;
using Point2d = bgm::point<double, 2, bg::cs::cartesian>;
using Segment2d = bgm::segment<Point2d>;
using LineString = bgm::linestring<Point2d>;
using SegmentRtree = bgi::rtree<Segment2d, bgi::rstar<16>>;
int main() {
SegmentRtree segments;
LineString input;
bg::read_wkt("LINESTRING(2 0, 5 3, 8 0, 4 -4, 11 -4, 11 5, 14 5)", input);
for (auto it = bg::segments_begin(input); it != bg::segments_end(input); ++it)
segments.insert({*it->first, *it->second});
for (auto& el : segments)
std::cout << "in tree: " << bg::dsv(el) << std::endl;
}
Which prints
in tree: ((2, 0), (5, 3))
in tree: ((5, 3), (8, 0))
in tree: ((8, 0), (4, -4))
in tree: ((4, -4), (11, -4))
in tree: ((11, -4), (11, 5))
in tree: ((11, 5), (14, 5))
In all likelihood, you just had to add one of the includes you can cross-reference from my examples.