我有一组分布随机的森林地块(SpatialPolygonDataFrame),即分散和聚集。对于每个多边形,我想判断它是否具有开放边缘。如果多边形具有开放边缘,则:
- 没有邻居
- 至少在一侧没有邻居;
- 有邻居,但是与邻居之间的树高度差大于5
我想知道如何将属性open_edge = TRUE / FALSE
添加到各个多边形中?在raster
包中,使用moving window
可以有希望的方法。然而,我的原始数据是要素类,不像工作示例中那样类似于栅格。
我考虑过(伪代码):
- 逐个子集化每个地块(在
for
循环中) - 创建周围缓冲区
- 子集化周围地块与地块的
buffer
重叠部分 - 如果有任何邻居->比较高度。 如果差异> 5,则
open_edge = TRUE
但是,这种方法没有考虑地块只有3个侧面邻居的情况,即车门邻域。 poly2nb
工具似乎很有前途,但如何向各自地块添加属性呢?
这是我的虚拟方法,但我想知道您是否有更高效的解决方案?
创建虚拟数据:
library(ggplot2) # for choropleth map plot
library(broom) # to convert spatial data to dataframe
library(mapproj)
library(spdep) # neighbours
library(rgdal)
library(rgeos)
library(sf)
library(raster)
library(dplyr)
library(spData)
library(sf)
r <- raster(nrow=6, ncol=6, crs = "+init=epsg:2957")
values(r) <- matrix(data = c(9, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA,
NA, NA, NA, 1, 1, 1,
NA, NA, NA, 1, 9, 1,
NA, NA, NA, 1, 1, 1),
nrow = 6,
ncol = 6,
byrow = TRUE)
# Convert raster to polygon
polys <- rasterToPolygons(r)
通过一个展架示例来识别其是否具有开放的边缘:
# Subset first row in SpatialPolygonDataFrame
i = 10
one = polys[i, ]
# Keep the remaining polygons
left = polys[-i,]
# Create buffer within distance
buff = buffer(one, width = 100)
# subset set of neighbours by spatial overlap
nbrs <- left[which(gContains(sp::geometry(buff),
sp::geometry(left), byid = T)),
# Compare if the values are different
height.one = rep(one$layer[1], nrow(nbrs))
height.nbrs = nbrs$layer
# Get the differences between the neighbouring stands
difference = height.one - height.nbrs
# If the difference in at least one stand is
# in more than 5, set open_edge = TRUE
# or if no neighbours find
one$open_edge <- any(difference > 5)