使用 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 日创建
我有一个线数据框,每条线都有一个 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 日创建