我需要在世界地图中表示陆地和海洋的空间多边形,然后将它们转换为数据框

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

我需要一张 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)

r maps distance r-sf r-raster
1个回答
0
投票

您已经很接近了,但是您需要考虑一件事。由于

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)

result

如果您仍想创建

transition()
对象:

library(rnaturalearth)
library(sf)
library(terra)
library(raster)
library(gdistance)

# Create world sf
world <- ne_countries(scale = "medium")

# Create base SpatRaster (low-res for this example, increase at 1:2 ratio for actual data)
r <- rast(nrow = 180, ncol = 360)

# Convert world sf to SpatRaster
r <- rasterize(world, r)

# Assign values to sea and land
r <- ifel(is.na(r), 1, 999)

# Convert to RasterLayer for transition()
r1 <- raster(r)

# Create a transition() object from the raster
tr <- transition(r1, function(x) 1/mean(x), 16)
tr <- geoCorrection(tr, scl = FALSE)
© www.soinside.com 2019 - 2024. All rights reserved.