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

问题描述 投票:0回答:2

我有一条线的数据框,每条线都有一个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"允许这种操作,如下图所示:

enter image description here

r casting gis polygon sf
2个回答
0
投票

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

#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)

enter image description here


0
投票

[一位同事让我意识到了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-03-10创建

© www.soinside.com 2019 - 2024. All rights reserved.