繁体   English   中英

R cran sf 从两个缝合的 shapefile 创建一个多边形

[英]R cran sf create a polygon from two sewed shapefiles

我的最终目标是创建一张 Vermeille Coast 的地图,以便在两个采样点之间的路径不穿过陆地的情况下计算两个采样点之间的距离。

为此:

1/我拿了两个shapefile(你可以在这里下载它们: https ://www.dropbox.com/sh/hzsdklnmvjg4hsz/AAATHLV0pkJXDvSqyRIBlVl_a?dl=0)

2/我根据以下方法缝制它们: R cran:sf Sew two MULTILINESTRING/LINESTRING

3/尝试根据该创建关联的多边形: Sf package: Close a polygon fom complex shape

脚本如下:

frenchCoast_CoteBanyuls <- st_read("coasts_subnational/coasts_subnational.shp")
spainCoast_CoteBanyuls <- st_read("coasts_subnational SPAIN/coasts_subnational.shp")

combined_coast <- rbind(spainCoast_CoteBanyuls, frenchCoast_CoteBanyuls) 
plot(combined_coast$geometry)

我得到以下情节:

在此处输入图像描述

到目前为止这是正确的。 我现在只需要创建关联的多边形:

bbox_combined_coast <- st_bbox(combined_coast) %>% 
  st_as_sfc()

polygon_combined_coast <- bbox_combined_coast %>% 
  lwgeom::st_split(combined_coast) %>% 
  st_collection_extract("POLYGON")

par(mfrow = c(2,4), mar = c(0,0,0,0))
for(i in 1:8){
  plot(polygon_combined_coast[i], col = 'steelblue')
}

这给了:

在此处输入图像描述

这些多边形都不代表上述组合地图的形状。

然而,当我从每个 shapefile 绘制多边形时:

par(mfrow = c(1,2), mar = c(0,0,0,0))

bbox_frenchCoast_CoteBanyuls <- st_bbox(frenchCoast_CoteBanyuls) %>% 
  st_as_sfc()

polygon_frenchCoast_CoteBanyuls <- bbox_frenchCoast_CoteBanyuls %>% 
  lwgeom::st_split(frenchCoast_CoteBanyuls) %>% 
  st_collection_extract("POLYGON")

plot(polygon_frenchCoast_CoteBanyuls[1], col = 'steelblue')

bbox_spainCoast_CoteBanyuls <- st_bbox(spainCoast_CoteBanyuls) %>% 
  st_as_sfc()

polygon_spainCoast_CoteBanyuls <- bbox_spainCoast_CoteBanyuls %>% 
  lwgeom::st_split(spainCoast_CoteBanyuls) %>% 
  st_collection_extract("POLYGON")

plot(polygon_spainCoast_CoteBanyuls[3], col = 'steelblue')

它给出了:

在此处输入图像描述

这两个多边形正确地塑造了与每个 shapefile 关联的多边形。

似乎 rbinding 两个 shapefile 会产生一些意想不到的结果。 你知道错误吗?

提前致谢,

夏洛特

将两条海岸线汇总,没有分组变量combined_coast <- rbind(spainCoast_CoteBanyuls, frenchCoast_CoteBanyuls) %>% summarise()请注意,它始终是 MULTILINESTRING,因为离海岸有几个小岛,所以不能是单个 LINESTRING

可以用combined_coast_poly<- combined_coast %>% st_cast("POLYGON")把它变成多边形

问题是两条海岸线都没有接触,这就是多边形方法不起作用的原因。

请参阅此处的解决方案,我将两条主要海岸线合并,添加西班牙的小岛并尝试您提供的方法:


# Download files
spainurl <- "https://geo.vliz.be/geoserver/wfs?request=getfeature&service=wfs&version=1.0.0&typename=MarineRegions:coasts_subnational&outputformat=SHAPE-ZIP&filter=%3CPropertyIsEqualTo%3E%3CPropertyName%3Emrgid_1%3C%2FPropertyName%3E%3CLiteral%3E3417%3C%2FLiteral%3E%3C%2FPropertyIsEqualTo%3E"
download.file(spainurl, "spain.zip", mode = "wb")
unzip("spain.zip", exdir = "spain", junkpaths = TRUE)

franceurl <- "https://geo.vliz.be/geoserver/wfs?request=getfeature&service=wfs&version=1.0.0&typename=MarineRegions:coasts_subnational&outputformat=SHAPE-ZIP&filter=%3CPropertyIsEqualTo%3E%3CPropertyName%3Emrgid_1%3C%2FPropertyName%3E%3CLiteral%3E19888%3C%2FLiteral%3E%3C%2FPropertyIsEqualTo%3E"
download.file(franceurl, "france.zip", mode = "wb")
unzip("france.zip", exdir = "france", junkpaths = TRUE)

library(sf)
library(tidyverse)
spainCoast_CoteBanyuls <- list.files("spain",
                                     pattern = "shp$",
                                     full.names = TRUE) %>% st_read()
frenchCoast_CoteBanyuls <- list.files("france",
                                      pattern = "shp$",
                                      full.names = TRUE) %>% st_read()
ggplot(spainCoast_CoteBanyuls) +
  geom_sf() +
  geom_sf(data = frenchCoast_CoteBanyuls)

好的,现在提取对象的每一个LINESTRING 法国只有1个。

# A. Decompose in linestrings

lines_spain <- st_geometry(spainCoast_CoteBanyuls) %>% st_cast("LINESTRING")
spainCoast_l <- st_sf(n = as.character(seq_len(length(lines_spain))), lines_spain)

ggplot(spainCoast_l) +
  geom_sf(aes(color = n), size = 3)

lines_france <- st_geometry(frenchCoast_CoteBanyuls) %>% st_cast("LINESTRING")
franceCoast_l <- st_sf(n = as.character(seq_len(length(lines_france))), lines_france)

ggplot(franceCoast_l) +
  geom_sf(aes(color = n), size = 3)

看看法国和西班牙是否接触(剧透:否)

st_touches(lines_france, lines_spain, sparse = FALSE)
#>       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
#> [1,] FALSE FALSE FALSE FALSE FALSE FALSE

# Lines doesn't touch. Merge both main coastlines
spainmax <- spainCoast_l[which.max(st_length(spainCoast_l)), ]
spainrest <- spainCoast_l[-which.max(st_length(spainCoast_l)), ]

ggplot(spainmax) +
  geom_sf() +
  geom_sf(data = franceCoast_l)

ggplot(spainrest) +
  geom_sf()

在这里,我将两个 LINESTRING 与st_union()合并:


# Merge

joined <- c(st_geometry(spainmax), st_geometry(franceCoast_l)) %>%
  st_union()


ggplot(joined) +
  geom_sf()

现在的任务是重新组合西班牙的小部分地区并应用lwgeom::st_split()方法。


# Ok, we are ready
# Get the rest of pieces of Spain

join_end <- st_union(joined, st_geometry(spainrest))

ggplot(join_end) +
  geom_sf()

bbox_all <- st_bbox(joined) %>%
  st_as_sfc()

polygon_joined <- bbox_all %>%
  lwgeom::st_split(join_end) %>%
  st_collection_extract("POLYGON")

#Polygons on position 2 and 3 need to be removed (visual inspection)
polygon_end <- polygon_joined[-c(2:3)]

ggplot(polygon_end) +
  geom_sf()

reprex 包于 2022-06-15 创建 (v2.0.1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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