繁体   English   中英

如何使用R sf包从基础网格中裁剪多边形?

[英]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,]

结合以下两个原因,这不适用于经度纬度:

  1. st_area上经纬度使用sf调用另一个包geosphere上工作sp的对象。 然后,您的sf对象会立即转换为sp对象。
  2. 在您的情况下,网格和多边形相交的结果不是多多边形,而是由点,线和多边形(类型=几何)组成的复杂对象。 从这种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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM