我正在尝试创建一个包含多边形的地图,这些多边形代表从每个国家的海岸线到海洋的 25 公里缓冲区,以便我可以计算每个国家的缓冲区内的面积。我在使用上传的海岸线文件和自然地球数据执行此操作时遇到困难。这是我迄今为止尝试过的:
library(rgdal)
library(sf)
library(rnaturalearthdata)
library(rnaturalearth)
library(rgeos)
library(maps)
library(countrycode)
# World polygons from the maps package
world_shp <- sf::st_as_sf(maps::map("world", plot = T, fill = TRUE))
world_shp_df <- world_shp %>%
mutate(Alpha.3.code = countrycode(ID, "country.name", "iso3c", warn = FALSE))
# Get coastlines using rnaturalearth
coastline <- ne_coastline(scale = "medium", returnclass = "sf")
# Buffer the coastlines by 25 km
buffer_distance <- 25000 # 25 km in meters
coastline_buffers <- st_buffer(coastline, dist = buffer_distance) %>%
st_make_valid()
ggplot() +
geom_sf(data = coastline_buffers , fill = "lightblue")
这会导致地图上有水平线穿过,请参见图像:
我尝试过使用不同的 crs 来简化几何形状,但我似乎无法弄清楚。任何帮助将非常感激!
st_buffer
在纬度两端 (+/- 180°) 进行计算时存在困难,会产生水平条纹。
分析具有此类条纹的多边形表明它们都有位于
xmin = -180
的点。
这些条纹可以通过它们的边界框进行排序:
stripes <- sapply(coastline_buffers$geometry,\(x) {bbox <- st_bbox(x); unname(bbox$xmin==-180)})
which(stripes)
#[1] 1 61 138 297 298 299 811 1352 1353 1387 1388 1404
ggplot() +
geom_sf(data = coastline_buffers[stripes,] , fill = "lightblue")
一个快速的解决方法是从多边形中删除这些错误点:
# Create a band from latitudes -175° to 180°
cleanup <- data.frame(lon=c(-175,-175,180,180,-175),lat=c(90,-90,-90,90,90)) %>%
st_as_sf(coords = c("lon", "lat"),
crs = st_crs(p[1,])) %>%
st_bbox() %>%
st_as_sfc()
# Remove points in this band
coastline_buffers_cleaned <- st_difference(coastline_buffers,cleanup)
ggplot() +
geom_sf(data = coastline_buffers_cleaned , fill = "lightblue")
此清理并非 100% 准确,因为地图两端的一些沿海区域消失了,但条纹已消失,并且与总缓冲区相比,删除的区域可以忽略不计。