使用 R / sf 从渔网/网格(线)创建多边形

Create Polygons from Fishnet / Grid (Lines) with R / sf

我有一个线数据框,每条线都有一个 x/y 开始和结束坐标。这些行描述了一个网格/鱼网,您可以在下面的最小示例中看到。遗憾的是,网格并不是完全均匀的,而且时不时会有一点偏移。

library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
library(purrr)
library(ggplot2)

df <- data.frame(
  x_start = c(2:9,rep(1,8)),
  x_end = c(2:9,rep(10,8)),
  y_start = c(rep(1,8),2:9),
  y_end = c(rep(10,8),2:9)
)

head(df)
#>   x_start x_end y_start y_end
#> 1       2     2       1    10
#> 2       3     3       1    10
#> 3       4     4       1    10
#> 4       5     5       1    10
#> 5       6     6       1    10
#> 6       7     7       1    10


lines_sf <- pmap(df,function(x_start,x_end,y_start,y_end){
  st_linestring(
    matrix(
      c(
        x_start,
        y_start,
        x_end,
        y_end),
      ncol = 2,byrow = TRUE)
  )
}) %>%
  st_as_sfc()

lines_sf
#> Geometry set for 16 features 
#> geometry type:  LINESTRING
#> dimension:      XY
#> bbox:           xmin: 1 ymin: 1 xmax: 10 ymax: 10
#> CRS:            NA
#> First 5 geometries:
#> LINESTRING (2 1, 2 10)
#> LINESTRING (3 1, 3 10)
#> LINESTRING (4 1, 4 10)
#> LINESTRING (5 1, 5 10)
#> LINESTRING (6 1, 6 10)

plot(lines_sf)

我想根据这些线创建多边形,其中(最小单位的)每个正方形都是一个单独的多边形(无重叠)。我在下面用手动构建的示例对此进行了说明:

polygons <- data.frame(x1 = rep(2:8,8),y1 = sort(rep(2:8,8)))

polygons$x2 <- polygons$x1+1
polygons$x3 <- polygons$x2
polygons$x4 <- polygons$x1
polygons$y2 <- polygons$y1
polygons$y3 <- polygons$y1+1
polygons$y4 <- polygons$y3


polygons_sf <- pmap(polygons,function(x1,x2,x3,x4,y1,y2,y3,y4){
  st_polygon(
    list(st_linestring(
      matrix(
        c(x1,y1,x2,y2,x3,y3,x4,y4,x1,y1),
        ncol = 2,byrow = TRUE)
    ))
  )
}) %>%
  st_as_sfc() %>%
  st_sf()


polygons_sf$nrow <- 1:nrow(polygons_sf)


ggplot() + geom_sf(data = polygons_sf, aes(fill = factor(nrow))) + 
  geom_sf(data = lines_sf, colour = "red",lty = 2) +
  theme(legend.position = "none")

reprex package (v0.3.0)

于 2020-03-09 创建

ESRI工具"Feature to Polygon"允许这种操作,如下图所示:

试试这个,想法是创建一个适合您的示例的实际网格(多边形),按行和列标记单元格并过滤第一行和最后一行和列:

#Size, if not square you could create sizex and sizey
size=length(unique(df$x_start))

#Grid to pols
grid=st_make_grid(lines_sf, n=c(size,size)) #Final number of cells

#Add a df
grid.df=st_sf(ind=1:length(grid), grid)

#Label rows and cols
grid.df$row=cut(grid.df$ind,size, labels=FALSE)
grid.df$col=rep(1:size,size)

#Filter our first and last col and row
polys <- grid.df[!grid.df$row %in% c(1,size) & !grid.df$col %in% c(1,size),]
plot(st_geometry(polys), col="red", add=TRUE)

一位同事让我知道 st_polygonize(),这很有效!

polygons_sf <- st_sf(st_cast(st_polygonize(st_union(lines_sf))))

polygons_sf$nrow <- rnorm(nrow(polygons_sf))

plot(polygons_sf)

reprex package (v0.3.0)

于 2020 年 3 月 10 日创建