凹形船体的定义,算法和实用解决方案是什么?[关闭]


116

凸包

形状的凸包定义为:

在数学中,实向量空间V中的一组点X的凸包或凸包络是包含X的最小凸集(Wikipedia

Wikipedia使用橡皮筋类比很好地形象化了它,并且有一些很好的算法可以对其进行计算

凹面船体

下图中的红线显示了凹壳(蓝线显示了凸壳)。直观地讲,它是一个包含所有点的多边形,但是与凸包相比,其面积较小(最小?)。结果,多边形的边界长度更长。

凹面船体可能是解决某些实际问题(例如,找到城市的合理边界)的解决方案。

在此处输入图片说明

我没有为凹面船体的概念找到合适的定义,算法和实用解决方案。该草Wiki有一些说明和图片,并且在商业解决方案concavehull.com

有什么想法,算法和链接吗?


您想在什么情况下生成凹壳/ alpha形状?在PostGIS,ArcMap,网络地图中,您自己的软件是?
fmark 2010年

PostGIS和我自己的Python脚本。
亚当·马坦

凹壳算法的实现是否具有与C ++ Linux兼容的版本?
Sylv255 '18

如果您有新问题,请单击“ 提问”按钮提问。如果它有助于提供上下文,请包括指向该问题的链接。- 评分
邪恶天才

计算几何算法库(CGAL)是具有Alpha形状的C ++库。它具有Linux下载,并已许可> = 4.0版本的GPL / LGPL。
klewis

Answers:


57

正如scw所指出的,您想要实现α形状

可以将Alpha形状视为凸包的概括。在1981年首次对它们进行了描述:

Edelsbrunner,H .;柯克帕特里克(D. 塞德尔河。,“论平面中一组点的形状”,信息论,IEEE Transactions,第29卷,第4期,第551-559页,1983年7月

存在您感兴趣的环境的开源实现:

邮政地理信息系统

如果您使用的是PostGIS堆栈,则pgRouting的可选Driving Distance扩展会公开一个alpha形状的实现。但是,我不确定是否可以更改alpha参数。

用法如下:

SELECT the_geom AS alpha_shape 
FROM 
  points_as_polygon(
    'SELECT id, ST_X(your_geom) AS x, ST_Y(your_geom) AS y FROM your_table');

蟒蛇

您可能会使用许多python模块。我听说过有关CGAL的好消息,CGAL是C ++计算几何库。 对于CGAL的某些部分,存在Python包装器,包括将CGAL的alpha形状实现公开给Python

请注意,CGAL的某些部分已获得QPL的许可,这意味着,如果您分发与CGAL链接的程序,则可能需要根据QPL发行它。如果不重新分发程序代码或二进制文件,则可以保留代码专有性。


我无法编译CGAL的python包装器-似乎已经有一段时间没有支持它们了,并且不再与最新版本的CGAL一起使用。
conradlee

2
@fmark:您发布的第二个链接似乎已死。
radek 2011年

1
@fmark PostGIS链接似乎已死..
radek 2015年


29

这似乎是alpha形状的特定应用,据我阅读,此形状是此问题的更一般形式。R具有alphahull模块,该模块具有有关计算alpha形状的出色文档。还要检查有关alpha形状的详细背景。如果只想计算凸/凹外壳,请检查lastboundslasboundary,它可以很好地缩放并可以处理数百万个输入点。

最终,Flickr对该alpha形状进行了有趣的应用前一阵子,展示了它们用于汇总用户生成的点内容的实用程序:

来自flickr的德克萨斯州alpha船体


1
OMG的源代码是用FORTRAN编写的:-)
Adam Matan 2010年

如果更适合您,则有一个用C ++编写的clustr软件包。但要小心在CGAL牌:github.com/straup/Clustr
SCW

2
真实的例子。
DavidF


19

我创建了一个称为[lasboundary] [1,2]的高效工具,它以LAS / LAZ / SHP / ASCII格式为LIDAR计算凹面船体,并将结果存储为ESRI Shapefile格式或geo的矢量边界多边形引用的KML文件。

这是一个示例运行:

C:\lastools\bin>lasboundary -i SerpentMound.las -o SerpentMound_boundary.shp
reading 3265110 points and computing convex hull for 3265110 points
growing inward towards concave hull (with concavity = 50)
outputting the concave hull
concave hull has 1639 points

一些结果图片在这里



10

这是一个实现Alpha Hull模型的R函数。输出是一个sp多边形对象。请参见标题中的示例。它需要sp,alphahull和maptools软件包。

**更新(2018年1月15日)对alphahull软件包产生的结果对象进行了许多更改。因此,我需要重写该函数。我在spatialEco包中添加了凸凸函数。但是,由于alphahull软件包中的许可限制,此功能仅在GitHub的开发版本中可用。可以使用以下方式安装开发版本:

library(devtools)
install_github("jeffreyevans/spatialEco")

这是函数用法的一个例子

library(sp)
library(spatialEco)
data(meuse)
 coordinates(meuse) = ~x+y
a <- convexHull(meuse, alpha=100000)
  plot(a)
    points(meuse, pch=19)

将生成的SpatialLinesDataFrame转换为SpatialPolygonsDataFrame

library(sf)
a <- sf::st_as_sf(a) 
a <- sf::st_polygonize(a)
class( a <- as(a, "Spatial") )
  plot(a)

测试多个Alpha值

par(mfcol=c(2,2))
   for (a in c(500, 1500, 5000, 100000)) {
   ch <- convexHull(meuse, alpha = a)
     plot(ch)
      points(meuse, pch=19)
        title( paste0("alpha=", a))      
   }

各种ahull alpha参数


+1您能否解释一下这与alpha形状包有何不同?
ub

3
alphahull对象的输出存储为矩阵,并且必须强制为可用的sp对象。我认为这是创建多边形的“帮助器”功能,该多边形可以导出为GIS格式。此函数使用alphahull包创建外壳矩阵对象,创建sp对象,然后爆炸多边形槽,使其成为单部分多边形数据框对象。软件包帮助中什么都没有显示,但是可能对我不知道的sp类对象有新实现的本机强制。如果是这种情况,请告诉我,以便我可以停用此功能。
杰弗里·埃文斯

什么是编程语言?
亚当·马坦

感谢@JeffreyEvans我已经设法解决了这个问题。您能否解释这些参数?我已经看过链接的jstatsoft文件,但是它非常难以理解。
geotheory,2013年

9

JTS(http://tsusiatsoftware.net/jts/main.html)提供了Convex Hull实现。马丁·戴维斯(Martin Davies)还提到了正在使用的Alpha Shape算法,因此您可能需要检查SVN存储库以查看它是否在里面。


据我所知,截至2012年6月,仍然没有凹壳/ alpha形状的实现。
blah238


JTS还活着吗?最新版本是2006
jts /

尝试答案中的链接
伊恩·特顿

JTS现在位于Github上,版本为1.15:github.com/locationtech/jts尽管据我所知,似乎仍然没有Alpha Shapes实现。
科林·伍德伯里


7

这是一个用C编写的程序,用于计算凸包,alpha形状,Delauney三角剖分和Voronoi体积:

  • 船体 -肯·克拉克森(2002)

另一个带有CJava实现的凸包算法在这里:


7

为了补充本帖的先前答案,至少从QGIS 2.6开始,它具有凹壳算法

参数
输入点层[vector:point]
在此处输入参数说明

阈值(0-1,其中1与凸包相等)[数字]
在此处放置参数说明
默认值:0.3

允许孔[布尔值]
在此处放置参数说明
默认值:True

将多部分几何体拆分为单部分几何体[boolean]
默认值:False

输出凹面船体[矢量]
将输出描述放在此处

控制台使用
处理.runalg('qgis:concavehull',输入,alpha,孔,no_multigeometry,输出)

此外,Esri还有一个工具“ 最小边界几何”(数据管理)

允许您选择几何类型,其中包括凸包

在此处输入图片说明



3

帮助您解决问题的“正确定义”部分;您可能已经看过 https://en.wikipedia.org/wiki/Convex_hull并获得了可以被认为是“适当”定义的内容,但发现它缺乏,因此也许更“有用”的定义是:

对于凸包内的每个点,到不在该包内的任何点的直线只会与该包相交一次。

这很有用,因为给定一个点,您可以通过它构造一条线并测试与船体的线段相交的那条构造的线。

  • 没有相交点不在船体中。
  • 一个交叉点位于船体上。
  • 两个相交点在外壳内
  • 直线与凸包的相交不能超过两次

2
操作人员询问的是凹壳,而不是凸壳
Winwaed 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.