麻辣GIS微信平台

更多 GIS 干货

微信关注不错过

介绍下GIS中的凸包和凹包

最近有小伙伴在群里问:手里有一堆 POI 点,想自动生成一块“贴合实际范围”的边界多边形,凸包包出来面积太大、形状太圆,有没有更贴边的办法?小编就尝试介绍下凹包和凸包的定义、算法以及常用工具。

凹包和凸包

凸包可以理解为用一根橡皮筋套住所有点,松手后橡皮筋绷出的多边形,它是包含这些点的最小凸集。GIS 里一般用来算建筑轮廓、点集外包盒,凸包的算法计算速度快、结果稳定,但形状往往偏“鼓”,凹进去的细节会被抹平。

凹包则反过来:同样要包住所有点,但允许边界出现凹陷,面积通常更小、周长更长,更接近人眼认定的“合理范围”。比如根据城市 POI 推断建成区边界、激光雷达点云地块范围等,凹包往往比凸包更顺眼。

如下图,蓝线是凸包,红线是凹包。

不过需要注意的是,凹包并没有一个像凸包那样“唯一最优”的严格定义。不同算法、不同参数会得到不同结果。

主流算法

社区里讨论最多的,是把凹包看作 Alpha Shape 的特例。Alpha Shape 由 Edelsbrunner 等人在 1983 年提出,Alpha 值很大时接近凸包,Alpha 值变小时边界逐渐向内收缩、出现凹陷。

另一条经典路线是 Duckham 等人 2008 年发表在 Pattern Recognition 上的算法,思路是从点集高效生成简单多边形,用来刻画平面点集形状,有 Java 开源实现,效果如下。

近几年 JTS 几何库也加入了凹包实现,基于输入点的 Delaunay 三角网做“侵蚀”:从外围三角形逐步去掉过长的边,保留贴合点云的外轮廓。该算法已移植到 GEOS,并在 PostGIS 3.3 及以后版本中通过 ST_ConcaveHull 暴露出来,支持绝对长度和相对比例两种参数,还能控制是否保留孔洞。

此外还有面向海量激光雷达点云的 lasboundary算法,属于 LAStools 工具链,能从 LAS、LAZ、SHP 等格式直接输出凹包边界,特点是支持大数据量。另外,R 语言生态里的 alphahull、spatialEco 包也可以实现。

QGIS处理方法

QGIS 处理工具箱里自带 Concave hull 工具,如下图:

主要有三个参数

  • Threshold:0 到 1,默认 0.3。数值越小边界越贴点,越大越接近凸包,1 时等价于凸包。
  • Allow holes:是否允许结果带孔洞,默认开启。
  • Split multipart geometry:是否把多部件拆成单部件。

PostGIS计算凹包

PostGIS 3.3 起提供 ST_ConcaveHull,底层走 JTS 凹包算法。基本用法:

SELECT ST_ConcaveHull(ST_Collect(geom), 0.3) AS hull
FROM your_point_table;

第二个参数是 target_percent,含义与 QGIS 的 Threshold 类似,0 最贴边,1 为凸包。还可指定是否允许孔洞。

点云与其他工具

激光雷达场景推荐 lasboundary,命令行示例:

lasboundary -i SerpentMound.las -o SerpentMound_boundary.shp

工具会先算凸包,再按 concavity 参数向内收缩成凹包,输出 Shapefile 或 KML。

Python 纯代码实现

桌面和数据库之外,走 Python 脚本最省事的方式是直接用 Shapely 2.0+ 自带的 concave_hull,底层同样走 GEOS,参数口径和 PostGIS 接近:

from shapely import MultiPoint, concave_hull

pts = MultiPoint([
    (0, 0), (0, 2), (1, 1.5), (2, 2), (2, 0),
    (1, 0.2), (1.5, 1), (0.5, 1),
])

# ratio: 0 最贴边,1 接近凸包,和 QGIS Threshold / PostGIS target_percent 同一套直觉
hull = concave_hull(pts, ratio=0.3, allow_holes=False)
print(hull.wkt)

需要 Shapely 2.0+ 且底层 GEOS ≥ 3.11,如果点来自 GeoPandas,也可以写成 gdf.unary_union.concave_hull(ratio=0.3)

另外,Alpha Shape 路线可以用 alphashape 库:alphashape.alphashape(coords, alpha)

总结

你在项目有没有用到凹包和凸包?用了什么方法?如果你有更顺手的凹包工具或踩坑经验,欢迎留言补充。

参考:https://gis.stackexchange.com/questions/1200/what-are-definition-algorithms-and-practical-solutions-for-concave-hull

相关阅读

麻辣GIS-Sailor

作者:

GIS爱好者,学GIS,更爱玩GIS。

声明

1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。

2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。

手机阅读
公众号关注
知识星球
手机阅读
麻辣GIS微信公众号关注
最新GIS干货
关注麻辣GIS知识星球
私享圈子
没有下文

留言板(小编看到第一时间回复)