在这个例子中,我编写了一种允许 rtree.query 工作的方法: 我想与两个线段相交
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);
我遇到的一些错误:
/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(
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
看起来 100% 像是您忘记包含一些标头。
该消息没有说明“您没有指定坐标系”(您指定了,它在您的点类型中)。它说“尚未找到该组合的专业化(对于该算法/策略/特征等...)”。
但是,您没有显示包含内容,所以我们无法判断。另外,您 do 显示的代码引用了许多与 Boost Geometry 无关的专有类型(
point_size()
、line_segment()
、point()[]
似乎都与 Boost Geometry 无关)。
甚至
.x()
和.y()
与您定义的点类型相矛盾。 point<>
没有有这些成员。不过,boost::geometry::model::d2::point_xy<>
确实如此。
所以,我能做的最好的事情就是编写大量(!!!)代码来让你的代码编译:
#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);
}
}
这会让你的循环更具可读性:
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()});
}
现在,这看起来像是难以想象的(糟糕的)代码量。另外,它对 rtree
什么都没有,这应该是你的问题?
我灵机一动。也许
uncrossable_segments_in_range
应该是你的 rtree
?整个循环是从[一些不相关的数据结构]构建rtree。我想象你会这样编写代码:
#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;
}
哪个打印
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))
很可能,您只需添加可以从我的示例中交叉引用的包含内容之一。