如何设置Boost RTree坐标系

问题描述 投票:0回答:1

在这个例子中,我编写了一种允许 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(
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost r-tree
1个回答
0
投票

看起来 100% 像是您忘记包含一些标头。

该消息没有说明“您没有指定坐标系”(您指定了,它在您的点类型中)。它说“尚未找到该组合的专业化(对于该算法/策略/特征等...)”。

代码取证

但是,您没有显示包含内容,所以我们无法判断。另外,您 do 显示的代码引用了许多与 Boost Geometry 无关的专有类型(

point_size()
line_segment()
point()[]
似乎都与 Boost Geometry 无关)。

甚至

.x()
.y()
与您定义的点类型相矛盾。
point<>
没有这些成员。不过,
boost::geometry::model::d2::point_xy<>
确实如此。

所以,我能做的最好的事情就是编写大量(!!!)代码来让你的代码编译:

住在Coliru

#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。我想象你会这样编写代码:

住在Coliru

#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))

总结

很可能,您只需添加可以从我的示例中交叉引用的包含内容之一。

© www.soinside.com 2019 - 2024. All rights reserved.