boost::geometry multi_polygon union_ 多多边形求并集

1,多边形概念(Polygon Concept)

2,一个接一个求并,{p0, p1, p2, p3} => p0+p1=p01, p01+p2=p012,p012+p3=p0123。

代码实现

namespace bg = boost::geometry;
using point_d = bg::model::d2::point_xy<double>;
using polygon_d = bg::model::polygon<point_d>;   //顺时针,闭合
using multi_polygon_d = bg::model::multi_polygon<polygon_d>;
multi_polygon_d polys; //需要求并的多多边形
multi_polygon_d outs; //求并后的输出
multi_polygon_d tmp;
for (const auto& poly : polys) {
    boost::geometry::union_(outs, poly, tmp);
    outs.swap(tmp);
    tmp.clear();
}

3,中间结果输出可能无效,比如p01无效,做为下一次求并的输入就是无效的。

通过调用is_valid (with failure value) - 1.84.0 (boost.org)

 无效的原因是可能有尖刺(failure_spikes = 12)或者自相交(failure_self_intersections = 21)。

4,correct - 1.84.0 (boost.org) 可以修复尖刺(failure_spikes = 12)

https://github.com/kleunen/boost_geometry_correct

 可以修复部分自相交(failure_self_intersections = 21)。但一直求并下去,有可能仍然存在无效的中间结果多边形,无法修复,导致合并的结果不正确。

5,用整数表示多边形坐标求并。

using point_i = bg::model::d2::point_xy<long>;
using ring_d = bg::model::ring<point_d>;
using ring_i = bg::model::ring<point_i>;
using polygon_i = bg::model::polygon<point_i>;
using multi_polygon_i = bg::model::multi_polygon<polygon_i>;
constexpr static double transform = 100.0;
void polyd2i(const polygon_d& poly, polygon_i& polyi) {
	for (const auto& p : poly.outer()) {
		polyi.outer().emplace_back(point_i(static_cast<long>(p.x() * transform), static_cast<long>(p.y() * transform)));
	}
	for (const auto& in : poly.inners()) {
		ring_i ini;
		for (const auto& p : in) {
			ini.emplace_back(point_i(static_cast<long>(p.x() * transform), static_cast<long>(p.y() * transform)));
		}
		polyi.inners().emplace_back(ini);
	}
	if (!bg::is_valid(polyi)) {
		bg::correct(polyi);
	}
}

void polyi2d(const polygon_i& polyi, polygon_d& poly) {
	for (const auto& p : polyi.outer()) {
		poly.outer().emplace_back(point_d(static_cast<double>(p.x()) / transform, static_cast<double>(p.y()) / transform));
	}
	for (const auto& in : polyi.inners()) {
		ring_d ini;
		for (const auto& p : in) {
			ini.emplace_back(point_d(static_cast<double>(p.x()) / transform, static_cast<double>(p.y()) / transform));
		}
		poly.inners().emplace_back(ini);
	}
	if (!bg::is_valid(poly)) {
		bg::correct(poly);
	}	
}
multi_polygon_i tmpi;
multi_polygon_i outsi;
for (const auto& polyd : polys) {
    polygon_i polyi;
    polyd2i(polyd, polyi);
    bg::union_(outsi, polyi, tmpi);
	outsi.swap(tmpi);
	bg::clear(tmpi);
}
outs.clear();
for (const auto& polyi : outsi) {
    polygon_d polyd;
    polyi2d(polyi, polyd);
    outs.emplace_back(polyd);
}

6,浮点数表示多边形坐标可能不准确,在对多边形进行布尔运算或者其他各种算法时,其实都用整数表示多边形坐标会比较好。

7,c++ - What is the fastest way to create the union of many boost::polygons? - Stack Overflow

 其中提到的属性合并Boost Polygon Library: Property Merge

 没有研究清楚,写了一点demo无法编译,希望有大佬赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值