固定R中的孤立孔


18

在合并两个相邻的shapefile之后,我试图在一个公共字段上执行并集。shapefile最终在它们之间至少留有一小段空间。尝试并集时,出现以下孤立孔错误:

createPolygonsComment(p)中的错误:rgeos_PolyCreateComment:孤立的孔,在索引17处找不到包含孔的多边形

我在此链接上将可复制的示例上传到Dropbox 。

这是重新创建问题的代码:

#loading required packages
require(sp)    
require(rgdal)
require(maptools)
require(rgeos)

#load example data, set "dsn=" to your working directory or specify the path
example <- readOGR(dsn=".",layer="ReproducibleExample")

#Attempting a UnionSpatialPolygons based on the COUNTY field
example.df <- as(example, "data.frame")
countycol <- example.df$COUNTY
example.diss <- unionSpatialPolygons(example, countycol)

返回值:

createPolygonsComment(p)中的错误:rgeos_PolyCreateComment:孤立的孔,在索引17处找不到包含孔的多边形

尝试在此处此处提出的修复程序:

slot(example, "polygons") <- lapply(slot(example, "polygons"), checkPolygonsHoles)

这将返回来自联合尝试的相同错误,但索引号不同:

rgeos_PolyCreateComment:孤立的孔,在索引30处找不到包含孔的多边形

尝试在Roger Bivand的有用教程中提出的修复程序

fix <- slot(example, "polygons")
fixa <- lapply(fix, checkPolygonsHoles)

返回与上面的索引30相同的错误。

其他人在这里这里都提出了这个问题,尽管上面提出的解决方案在某些情况下似乎可行,但其他情况却无法解决。一位用户使用QGIS解决了该问题,另一位用户修复了3项中的2项,但没有解决最后一项的解决方案。

尽管该代码不时起作用,但人们似乎仍然遇到问题。有人在R中找到解决方案吗?

我已经在ArcGIS中执行了“修复几何体”工具,它纠正了该问题,但是似乎应该在R中进行修复。


没有您的数据,很难说出问题出在哪里。

@Pascal,我刚刚上传了一个dropbox链接,其压缩文件的形状文件缩小了10mb,未压缩的16mb可以重现该问题。我不确定如何提供数据,因为原始数据为1.5 gb,但是设法使用ArcGIS将问题缩小到一个较小的文件。是否有用于创建和共享可管理大小的可复制示例的良好协议?
路加·麦考利

用R尝试不同的方法无效。检查几何时,Qgis冻结了。

Answers:


25

我分析了附加数据的几何问题,而且现在看来,这不仅有orphaned holesgeometry validity issues。的确orphaned hole是几何几何有效性问题,但是rgeos不能以相同的方式处理它,对于孤立的孔,会引发错误,而不是简单的警告。正如您所指出的那样,它们是检查多边形孔的提示,但为修复孤立孔而应用时并非总是成功。

那么让我们:

  1. 清理您的数据(如果您希望像联合一样进行地理处理,这是必需的)

  2. 在合并过程中使用清理的数据

1.清洁几何 体在R 修复几何体有时可能会很困难,因此我试图构建一个实验性R包(请参阅https://github.com/eblondel/cleangeo),旨在促进sp物体的清洁(目前仅限于多边形)。您可以通过以下方式安装软件包:

require(devtools)
install_github("eblondel/cleangeo")
require(cleangeo)

首先,最好查看源数据中存在哪些几何问题。为此,您可以运行以下命令(您的数据很大,因此可能需要一些时间):

#get a report of geometry validity & issues for a sp spatial object
report <- clgeo_CollectionReport(sp)
summary <- clgeo_SummaryReport(report)
issues <- report[report$valid == FALSE,]

这样,您将看到数据有两种问题:orphaned holesgeometry validity issues。这两个(不仅是孤立的孔)都可能使union过程失败,因此应该在可能的情况下以自动方式清除数据。为了快速重现,下面的第一个示例代码仅采用标记为可疑的功能子集(最新的功能除外,在原始数据中索引为9002-请参阅下面的我的注释)

#get suspicious features (indexes)
nv <- clgeo_SuspiciousFeatures(report)
mysp <- sp[nv[-14],]

#try to clean data
mysp.clean <- clgeo_Clean(mysp, print.log = TRUE)

#check if they are still errors
report.clean <- clgeo_CollectionReport(mysp.clean)
summary.clean <- clgeo_SummaryReport(report.clean)

如果clgeo_Clean做得好,您现在应该使所有几何有效。您可以将其应用于完整的数据集(特征索引= 9002除外)

#try to clean data
mysp <- sp[-9002,]
mysp.clean <- clgeo_Clean(mysp, print.log = TRUE)

#check if they are still errors
report.clean <- clgeo_CollectionReport(mysp.clean)
summary.clean <- clgeo_SummaryReport(report.clean)

2.联合过程 现在,让我们看看union该数据集是否适用:

#Attempting a UnionSpatialPolygons based on the COUNTY field
mysp.df <- as(mysp, "data.frame")
countycol <- mysp.df$COUNTY
mysp.diss <- unionSpatialPolygons(mysp.clean, countycol)

注意:如前所述,我已经删除了一个功能(索引= 9002)。通过绘制它:plot(sp[9002,]),您将看到此功能非常非常复杂。我之所以从样本中排除它,只是因为检查孔花了太多时间。现在让我们看看使用readShapePoly(from maptools)读取数据是否发生相同的问题...

3.切换到readShapePoly和readOGR来读取数据(更新)

readOGR不是唯一可读取shapefile的函数。您还可以使用readShapePolyfrom maptools软件包,通常比第一个软件包具有更高的性能:

require(maptools)
mysp <- readShapePoly("ReproducibleExample.shp")

除了运行速度更快:

  • 如果您使用基于的上述代码clgeo_CollectionReport,则不会出现孤立孔的问题,但是仍然存在几何问题。

  • 清洗几何体clgeo_Clean也运行良好,现在它不会卡在特征索引9002上

  • 而且...联合程序有效。

参见下面的绘图结果:

#plot the result
plot(mysp, border= "lightgray")
plot(mysp.diss, border="red", add = TRUE)

联合结果

结论:首选使用maptools读取shapefile数据,并考虑在任何地理处理之前使用cleangeo清洁数据。


谢谢eblondel!我会尝试的。感谢软件包开发!
路加·麦考利

eblondel,您好,但我想让您知道,在校正几何图形时,通常在处理复杂而复杂的特征时会创建一个很大的多边形。例如,将道路网络校正为一个大的多边形,这基本上就是该网络的范围。我不确定要纠正的难易程度,但想通知您。
路加·麦考利

哇。非常令人印象深刻的包装。那一定是很多工作。
nograpes

3
感谢@nograpes的反馈。发布此问题时,我是从头开始构建此程序包的,这也是因为清洁几何形状并不总是一件容易的事。如果您在Github上,我将欢迎您的“星级” :-),我希望将来进一步改进该程序包,并可能在CRAN上发布它。
eblondel

7
为了让您知道cleangeo已在CRAN中发布(cran.r-project.org/package=cleangeo),所有使用它的人都可以随时报告功能增强请求或Github中的错误。
eblondel

1

在R中对我有用的一个方便的解决方案是应用零宽度缓冲区

#loading required packages
require(sp)    
require(rgdal)
require(maptools)
require(rgeos)

#load example data, set "dsn=" to your working directory or specify the path
example <- readOGR(dsn=".",layer="ReproducibleExample")

#project your data (I'm using California Albers here) and apply a zero-width buffer
example <- spTransform(example, CRS("+init=epsg:3310"))
example <- gBuffer(example, byid = T, width = 0)

#Attempting a UnionSpatialPolygons based on the COUNTY field
example.df <- as(example, "data.frame")
countycol <- example.df$COUNTY
example.diss <- unionSpatialPolygons(example, countycol)

unionSpatialPolygons需要一些时间来处理此数据集,但似乎工作得很好。

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.