我需要一张 R 中的世界地图,它可以转换为陆地多边形,以便能够计算从一个点到另一个点通过海洋并绕过陆地/多边形的距离。这些多边形需要采用数据帧格式才能栅格化世界地图。从这个光栅文件中,我需要一个过渡对象。
我已经尝试过 ggplot2 包中的 map_data("world") ,但是当我尝试使用 df_to_SpatialPolygons() 函数将此数据框转换为空间多边形并绘制它时,世界地图上出现了一些奇怪的水平线(plot(wrld_simpl) )。我需要一张世界地图,可以将陆地转为 999,将海洋转为 1。只是陆地和水之间的区别。正如您在下面的代码中看到的。但是当我绘制“tr”或“worldras”时,您可以清楚地看到线条对陆地和海洋的区分有很大影响,并且世界地图变得几乎无法识别。无法识别的世界地图
wrld_simpl <- map_data("world") # comes from ggplot2
wrld_simpl <- df_to_SpatialPolygons(df = wrld_simpl,
keys = "region",
coords = c("long", "lat"),
proj = CRS("+proj=longlat +ellps=sphere"))
plot(wrld_simpl)
# Generate a scaffold for the raster file
world_crs <- crs(land_polygons)
worldshp <- spTransform(land_polygons, world_crs)
ras <- raster(nrow=1200, ncol=1200)
# Generate a raster file
worldmask <- rasterize(worldshp, ras)
worldras <- is.na(worldmask) # inverse water and land, so ocean becomes 1 and land 0
worldras[worldras==0] <- 999 # set land to 999
# Create a Transition object from the raster
tr <- transition(worldras, function(x) 1/mean(x), 16)
tr = geoCorrection(tr, scl=FALSE)
我还尝试在下面的代码中使用 rnaturalearth 包,但这也不起作用。 world_df 中没有任何数据。
library(rnaturalearth)
# Step 2: Download High-Quality World Map Data
world <- ne_countries(scale = "medium", returnclass = "sf")
# Plot the high-quality world map
plot(world)
# Dissolve polygons into a single polygon representing the entire world
world_union <- st_union(world)
world_df <- st_sf(geometry = world_union)
最后我尝试了下面的代码块。在绘制 land_df 和 sea_df 时,我得到的图形是迄今为止我拥有的最好的世界地图。但是,如果我尝试将 land_polygons 变量放入第一个代码块中,它仍然不起作用并给出此错误:
世界shp<- spTransform(land_polygons, world_crs) Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘spTransform’ for signature ‘"sf", "character"’
library(rnaturalearth)
library(sf)
# Step 1: Download World Map Data
world <- ne_countries(scale = "medium", returnclass = "sf")
# Create a rectangle covering the entire world
world_bbox <- st_bbox(world)
world_rectangle <- st_as_sfc(world_bbox)
# Remove land area from the rectangle to obtain sea/ocean areas
sea_mask <- st_difference(world_rectangle, world)
# Plot the map with land in black and sea in white
plot(st_geometry(sea_mask), col = "white", border = NA)
plot(world, col = "black", border = NA, add = TRUE)
# Convert land and sea masks to dataframes
land_df <- as.data.frame(world)
sea_df <- as.data.frame(st_sf(geometry = sea_mask))
# Convert the dataframe land_df to a spatial polygon object
land_polygons <- st_as_sf(land_df)
# Display information about the resulting spatial polygon object
print(land_polygons)
您已经很接近了,但是您需要考虑一件事。由于
ne_countries()
是一个具有完整全局范围的 S2 对象,您必须将其 st_transform()
转换为平面坐标,或者关闭 sf_as_s2()
以返回您的期望的结果。此外,map_data("world")
针对 geom_poly()
进行了优化,因此需要一些额外的步骤才能将其转换为 sf 对象。如果您想知道如何操作,请在下面评论,否则让我们保持简单并坚持ne_countries()
。
尚不清楚您将对结果应用什么分析,因此我尽可能保留了您的原始工作流程。这样您应该能够轻松修改代码以输出 sf 或 df 对象。我还将输出保留为多边形几何形状。如果您想要单独的多边形,请在下面发表评论,我将更新答案。
library(rnaturalearth)
library(sf)
library(dplyr)
library(ggplot2)
# Turn off S2
sf_use_s2(FALSE)
# Create world
world <- ne_countries(scale = "medium")
# Create a rectangle covering the entire world
world_bbox <- st_bbox(world)
world_rectangle <- st_as_sfc(world_bbox)
# Remove land area from the rectangle to obtain sea/ocean areas, convert to df
sea_mask <- st_difference(world_rectangle, st_union(world)) %>%
st_as_sf() %>%
mutate(id = 1) %>%
data.frame()
# Create df of world sf object
world_df <- world %>%
st_union() %>%
st_as_sf() %>%
mutate(id = 999) %>%
data.frame()
# Join world_df and sea_mask and convert to sf
result <- rbind(sea_mask, world_df) %>%
st_as_sf()
ggplot() +
geom_sf(data = result, aes(fill = factor(id))) +
scale_fill_manual(values = c("#b6dbff", "#F0E442"),
name = "Type",
labels = c("Sea", "Land")) +
coord_sf(expand = FALSE)