如何在Boost geometry中使用多个linestrings创建box
Boost.Geometry 多连通LineString构建Box实现方案
你需要的功能可以通过 Boost.Geometry 库的现有接口组合实现,没有直接一步完成的单函数,但调用现有接口可以快速满足需求,具体方案如下:
- 首先确认输入合法性,如果你已经确定所有LineString刚好贴合矩形四条边、没有冗余或缺口,可以直接调用
boost::geometry::envelope接口,直接计算所有输入LineString的外包矩形,输出结果就是你需要的boost::geometry::model::box对象。 - 如果输入的LineString合法性不确定,需要先做校验再生成Box,可以按以下步骤处理:
- 调用
boost::geometry::union_接口将所有连通的LineString合并为单个闭合Ring - 调用
boost::geometry::is_valid校验Ring无自交、无缺口,再调用boost::geometry::num_interior_rings确认没有内部空洞 - 校验通过后调用
boost::geometry::envelope传入合并后的Ring,输出标准Box对象
- 调用
以下是可直接运行的参考代码:
#include <boost/geometry.hpp> #include <boost/geometry/geometries/linestring.hpp> #include <boost/geometry/geometries/point_xy.hpp> #include <boost/geometry/geometries/box.hpp> #include <vector> namespace bg = boost::geometry; using Point = bg::model::d2::point_xy<double>; using LineString = bg::model::linestring<Point>; using Box = bg::model::box<Point>; int main() { // 输入示例:4条构成矩形边界的连通LineString std::vector<LineString> input_lines = { {{0,0}, {10,0}}, {{10,0}, {10,10}}, {{10,10}, {0,10}}, {{0,10}, {0,0}} }; Box target_box; // 快速方案:确认输入符合要求时直接调用 bg::envelope(input_lines, target_box); // 严格校验方案:输入不确定时使用 bg::model::ring<Point> merged_boundary; bg::union_(input_lines, merged_boundary); if (bg::is_valid(merged_boundary) && bg::num_interior_rings(merged_boundary) == 0) { bg::envelope(merged_boundary, target_box); // 额外校验:确认合并的轮廓和生成的Box完全重合 Box temp_box; bg::envelope(merged_boundary, temp_box); std::vector<Point> box_corners = {temp_box.min_corner(), Point(temp_box.max_corner().x(), temp_box.min_corner().y()), temp_box.max_corner(), Point(temp_box.min_corner().x(), temp_box.max_corner().y())}; bool is_exact_rect = true; for (auto& p : box_corners) { if (!bg::within(p, merged_boundary)) { is_exact_rect = false; break; } } } return 0; }
- 额外处理提示:如果输入的LineString存在冗余点或者超出边界的部分,可以先调用
boost::geometry::simplify做简化,或者调用boost::geometry::intersection裁剪掉多余部分后再做后续处理。
内容的提问来源于stack exchange,提问作者Xiaoyu
相关产品推荐
相关产品推荐

