我的最终目标是使用gdistance::shortestPath()
来计算从岛屿一侧的一点到同一岛屿另一侧的一点的最短路径距离,同时不经过陆地(即通过海洋),同时考虑洋流速度和流向。
上面的一个中间步骤是生成一个过渡层,然后传递给shortestPath()
,我很难理解如何将多个栅格传递给gdistance::transition()
。
我有以下光栅图层:
- 海流速度
- 海流方位
- 一幅有岛屿的海洋Map
举个小例子:
library(dplyr)
library(sf)
library(terra)
library(gdistance)
library(raster)
# Ocean current speed raster
ocean_spd <- terra::rast(nrow = 100,
ncol = 100,
xmin = 0,
xmax = 1,
ymin = 0,
ymax = 1,
crs = NA)
# set all ocean values to 0.5 (m/s)
ocean_spd <- terra::setValues(ocean_spd, 0.5)
# Ocean current bearing raster
# set all current bearing to 90 (left to right)
ocean_dir <- terra::setValues(ocean_spd, 90)
# Create island raster
# island corners
poly_df <- data.frame(x = c(0.5, 0.5, 0.8, 0.8),
y = c(0.5,0.8, 0.8, 0.5))
# island as a polygon
poly_sf <- poly_df %>%
sf::st_as_sf(coords = c("x","y")) %>%
summarise(geometry = sf::st_combine(geometry)) %>%
sf::st_cast("POLYGON") %>%
sf::st_make_valid()
# convert polygon to raster
island_mask <- terra::rasterize(poly_sf, ocean_spd)
plot(island_mask)
# island cells = 999 and ocean cell = 1
island_mask[island_mask == 1] <- 999
island_mask[is.nan(island_mask)] <- 1
# remove island from current and bearing rasters
ocean_spd[island_mask == 999] <- NA
ocean_dir[island_mask == 999] <- NA
# convert rast objects to raster - needed by transition()
island_mask <- raster(island_mask)
ocean_spd <- raster(ocean_spd)
ocean_dir <- raster(ocean_dir)
# have a look at the layers
plot(island_mask)
text(island_mask, digits=1)
plot(ocean_spd)
text(ocean_spd, digits=1)
plot(ocean_dir)
text(ocean_dir, digits=1)
计算过渡层-这是我卡住的地方,我不清楚我如何整合岛屿光栅,海洋速度光栅和洋流轴承光栅来获得过渡对象。
trans_obj <- transition(island_mask, transitionFunction = ?, 16, symm = FALSE)
从这里开始,我将使用过渡对象(trans_obj
)计算岛屿边缘(例如港口)上两点之间的最短路径-通过海洋
pt_dist <- gdistance::shortestPath(trans_obj,
poly_df[1,],
poly_df[2,],
output = "SpatialLines")
# get the distance
sf::st_as_sf(pt_dist) %>%
sf::st_length()
我的问题:
如何将岛屿栅格、海洋速度栅格和洋流方位栅格传递给transition()
以生成过渡对象?或者在传递给transition()
之前,是否需要执行其他中间步骤来合并这三个栅格?
任何建议都将不胜感激。
1条答案
按热度按时间9nvpjoqh1#
一种方法是
geoCorrect
以上示例:
map
ping命令(带有{purrr}),但如果您不想保持较低的软件包数量,可以使用.apply
变体或其他方法来实现 *设置一些全局变量(仅用于演示)
创建岛屿掩码(问题中的代码)
创建“栅格”列表并开始填充:
根据当前方向创建具有水平和垂直速度分量的栅格:
创建经度和纬度位置的栅格(值从西向东和从北向南递增)。我们需要这些栅格将位置偏移与速度分量进一步相乘:
在位置处创建具有速度的光栅(这些是转换矩阵的基础):
使用岛遮罩遮罩所有栅格:
创建转换矩阵。转换是不对称的(取决于相对于速度分量的运动方向),因此
symm = FALSE
。添加一个轻微的偏移量(.001),以避免在90°、180°等Angular 处x或y速度分量的零矩阵(* 注:当使用参数x
调用transitionFunction
时,x[1]
是“from”单元格的值,x[2]
是“to”单元格的值。)*geoCorrect
过渡层(因为对角相邻单元比正交单元更远离):根据经度和纬度分量计算电导率代理(待最大化):
创建辅助函数以将过渡矩阵的值完全移动为正值(某些几何距离条件不允许负值):
移位转移矩阵,返回列表中最短路径和代价距离:
输出
在将代码 Package 到函数
get_shortest_path
中之后:...并计算方位角30、60... 360°的最短路径和成本距离: