使用gIntersection循环多边形裁剪

时间:2014-12-05 13:14:10

标签: r loops gis polygon clip

问题

我试图在循环中使用带有R的gIntersection函数执行多个多边形剪辑。我可以手动获取正确的剪辑并重新输入数据(因此我可以将生成的SpatialPolygons对象转换回SpatialPolygonsDataFrame对象)。我无法做到的是使用for()apply()使其正常工作。

目前这不是一个问题。我有9个英语区域(伦敦),因此手动设置每个剪辑并不是一个巨大的挑战。但是,我想最终在LAD中剪辑LSOA,这实质上意味着设置> 400个剪辑。

所以,我的问题是,如何将手动剪辑转换为工作循环?

最小可重复示例

为了简单起见,让我们使用英语区域(n = 9)。对于9个地区中的每个地区,我都要剪掉这些县。以下代码加载适当的shapefile并将它们重新投影为British National Grid:

require(rgdal)
require(rgeos)
# English counties shapefile (~ 10MB zipped)
download.file(
  "https://dl.dropboxusercontent.com/s/6o0mi28pjo1kh9k/england-counties.zip",
  "ec", method = "wget")
unzip("ec")
ec <- readOGR("england-counties", "england_ct_2011")
proj4string(ec) <- CRS("+init=epsg:27700")

# English regions (~6MB zipped)
download.file(
  "https://dl.dropboxusercontent.com/s/p69m0vk2fh4xe3o/england-regions-2011.zip",
  "er", method = "wget")
unzip("er")
er <- readOGR("england-regions-2011", "England_gor_2011")
proj4string(er) <- CRS("+init=epsg:27700")

您应该留下两个对象er(英语区域)和ec(英语县)。两者都是SpatialPolygonsDataFrame对象。

选择第一个地区 - 英格兰东部E12000006 - 让我们剪切县并将结果重新转换为SpatialPolygonsDataFrame对象:

ee <- gIntersection(ec, er[er$CODE == "E12000006", ],
                    byid = T, drop_not_poly = T)
row.names(ee) <- as.character(gsub(" 0", "", row.names(ee)))
# gIntersection adds ' 0' to each row.name?
ee <- SpatialPolygonsDataFrame(ee, ec@data[row.names(ee), ])

ee的情节证实了这一点:

Plot of East of England region with counties

正如您所看到的,这对于几个形状来说是一个很好的工作流程,但我真的想要遍历所有区域,最终还有更多的多边形。

我尝试过什么

我对apply()循环不是很好,所以我到目前为止尝试的是一个for()循环(我知道它比较慢,但仍然比键入更快一切都出来了!):

regions <- as.character(er$CODE)  # length = 9 as expected
for(i in 1:length(regions)){
  as.name(paste0(regions[i], "c")) <- 
    gIntersection(ec, er[er$CODE == regions[1], ], byid = T, drop_not_poly = T)
}

而不是预期的行为,我得到以下错误:

Error in as.name(paste0(regions[1], "c")) <- gIntersection(ec, er[er$CODE ==  : 
could not find function "as.name<-"

我还尝试将对象名称包装在eval()中,但出现以下错误:

Error in eval(as.name(paste0(regions[1], "c"))) <- gIntersection(ec, er[er$CODE ==  :
could not find function "eval<-"

我错过了什么?

除了gIntersection之外,我想尽可能重新创建一个SpatialPolygonsDataFrame对象。我已经尝试了以下代码,手动完成了一个gIntersection,但它再次没有工作:

for(i in 1:length(regions)){
   row.names(as.name(paste0(regions[i], "c"))) <- as.character(gsub(" 0", "",
     row.names(as.name(paste0(regions[i], "c")))))
}

我收到以下错误:

Error in `rownames<-`(x, value) : 
  attempt to set 'rownames' on an object with no dimensions

我也不确定如何增加" 0",因为每个新区域(" 1"" 2"等都会增加一个。)

同样,手动设置第一个示例我也无法执行最终的SpatialPolygonsDataFrame步骤:

for(i in 1:length(regions)){    
    as.name(regions[i]) <- SpatialPolygonsDataFrame(regions[i],
      ec@data[row.names(regions[i], )])
}

为此,我收到以下错误:

Error in stopifnot(length(Sr@polygons) == nrow(data)) :
trying to get slot "polygons" from an object of a basic class ("character") with no
slots

我在哪看

以下相关的SO示例似乎没有帮助,或者至少我无法看到如何将它们应用于此示例:

感谢您花时间阅读本文。

1 个答案:

答案 0 :(得分:1)

这有帮助吗?

ee <- lapply(regions, function(x)  
  gIntersection(ec, er[er$CODE == x, ], byid = TRUE, drop_not_poly = TRUE))

这将为您提供SpatialPolygonsDataFrame的列表,每个区域对应一个。您可以通过常规方式访问,例如

ee[[1]]
plot(ee[[1]])  # to plot the first region with counties

修改

你的orignial代码应该使用sligh修改(见打击)。

res <- list()
for (i in 1:length(regions)) {
  ee <- gIntersection(ec, er[er$CODE == regions[i], ],
                      byid = TRUE, drop_not_poly = TRUE)
  row.names(ee) <- as.character(gsub(paste0(" ", i-1), "", row.names(ee)))
  ee <- SpatialPolygonsDataFrame(ee, ec@data[row.names(ee), ])
  res[[i]] <- ee
}

如果这样可以解决问题,那么问题是,ee的行名称总是加1而你没有考虑到这一点。

相关问题