[英]How to crop a polygon from an underlying grid with the R sf package?
我想知道它是否比下面的带有rstats sf的示例更简单,以计算基础网格中多边形shapefile的(分数)面覆盖率。 到目前为止,我还没有找到可以为我完成这项工作的功能。 这是我的示例:
library(sf)
## create a multipolygon
p1 <- rbind(c(7, 48), c(8, 52), c(11, 49), c(9, 48), c(7, 48))
p2 <- rbind(c(8, 50), c(8, 51), c(9, 50), c(8, 50))
mpol <- st_sfc(st_multipolygon(list(list(p1, p2))), crs=st_crs(4326))
## create a half degree grid covering the multipolygon
grid <- st_make_grid(mpol, cellsize=0.5)
## Create a sf object with the required attributes
## package 'lwgeom' reqiured
area <- st_area(grid)
grid <- st_as_sf(data.frame(ID=c(1:length(area)), area=area, geometry=grid))
## check 'map' elements
plot(grid['area'])
plot(mpol, col="#FF0000AA", add=TRUE)
现在是计算,在这里我首先通过从边界框(bpol)中减去mpol来反转多边形(ipol),然后计算新的覆盖面积。
## create a rectangular bounding box around the polygon
bbox <- st_bbox(mpol)
bpol <- st_sfc(st_polygon(list(rbind(c(bbox['xmin'], bbox['ymin']),
c(bbox['xmax'], bbox['ymin']),
c(bbox['xmax'], bbox['ymax']),
c(bbox['xmin'], bbox['ymax']),
c(bbox['xmin'], bbox['ymin'])))), crs=st_crs(4326))
## invert the multipolygon, by substracting it from the bounding box
ipol <- st_difference(bpol, mpol)
## substract the inverted polygon from the grid
gridinpoly <- st_difference(grid, ipol)
## calculate new 'cropped' area
gridinpoly$croppedArea = st_area(gridinpoly)
plot(gridinpoly['area'])
plot(gridinpoly['croppedArea'])
## Finally the fractional coverage is calculated:
gridinpoly$frac = gridinpoly$croppedArea / gridinpoly$area
plot(gridinpoly['frac'])
如果将网格单元覆盖两次,然后从网格中断处裁剪倒置的多边形,可能会变得更加复杂。
p3 <- rbind(c(9.75, 50.5), c(10, 51), c(10.5, 50), c(9.75, 50.5))
mpol <- st_sfc(st_multipolygon(list(list(p1, p2, p3))), crs=st_crs(4326))
ipol <- st_difference(bpol, mpol)
gridinpoly <- st_difference(grid, ipol)
错误消息:“ CPL_geos_op2(op,st_geometry(x),st_geometry(y))中的错误:评估错误:TopologyException:输入几何1无效:在9.75 50.5点处或附近的嵌套壳在9.75 50.5处。”
现在我的问题是,是否已经有一个功能,该功能可以完成? 我错过了文档中的某些内容吗? 以及如何多次裁剪网格单元时如何解决该错误?
谢谢,谢谢。
对我来说,使用st_intersection
似乎更自然/容易。
复制并举例几乎与您相同。 唯一的区别是未指定crs。 它应与任何crs一起使用,但不适用于经度纬度(请参见下文)
library(sf)
## create a multipolygon
p1 <- rbind(c(7, 48), c(8, 52), c(11, 49), c(9, 48), c(7, 48))
p2 <- rbind(c(8, 50), c(8, 51), c(9, 50), c(8, 50))
mpol <- st_sfc(st_multipolygon(list(list(p1, p2))))
## create a half unit grid covering the multipolygon
grid <- st_make_grid(mpol, cellsize=0.5)
area <- st_area(grid)
grid <- st_as_sf(data.frame(ID=c(1:length(area)), area=area, geometry=grid))
计算多边形内部的网格表面的分数:
tmp <- st_intersection(grid, mpol)
tmp$area <- st_area(tmp)
tmp$frac <- tmp$area/unique(area)
plot(tmp['frac'])
# If needed, you can remove the non polygons :
tmp[tmp$area > 0,]
结合以下两个原因,这不适用于经度纬度:
st_area
上经纬度使用sf
调用另一个包geosphere
上工作sp
的对象。 然后,您的sf
对象会立即转换为sp
对象。 sf
对象到sp
的转换不起作用 但是,如果您只需要%的面积,则可能不建议也不需要测量经度/纬度区域。
至于您的p3错误消息,我不确定您要模拟什么。 如果您想要一个由p1和p3组成且在p1中带有孔(p2)的mpol
,则创建mpol
的语法必须稍有不同(并且面积计算可以正常进行):
p3 <- rbind(c(9.75, 50.5), c(10, 51), c(10.5, 50), c(9.75, 50.5))
mpol <- st_sfc(st_multipolygon(list(list(p1, p2), list(p3))))
plot(mpol)
tmp <- st_intersection(grid, mpol)
tmp$area <- st_area(tmp)
tmp$frac <- tmp$area/unique(area)
plot(tmp['frac'])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.