我有一个港口数据库,里面有近10k个港口名称及其对应的位置,我想找出港口之间的距离。
根据我的理解,使用谷歌距离矩阵API,我们只能找到一组特定出行方式的两点之间的距离,如自行车,驾驶,步行和内部交通。
但在我的例子中,我希望在船舶航行过程中找到两个港口之间的距离。如果有人做过类似的工作,请分享你的知识…
参考网站:[http://www.portworld.com/map]
谢谢!
发布于 2015-05-20 04:19:02
我也遇到了同样的问题,并找到了解决方案。
1)首先,你必须创建一个世界地图栅格,其中包含一艘船可以通过一个值的所有部分,以及它不能到达另一个值的所有地方。
为此,我从所有国家边界的形状文件开始,使用QGIS手动添加了苏伊士和巴拿马运河。然后我还在北冰洋添加了冰。剩下的工作我用R语言完成,使用了rgdal,raster和gdistance包。
install.packages("rgdal")
install.packages("raster")
install.packages("gdistance")
library(rgdal)
library(raster)
library(gdistance)我首先创建了一个空栅格:
new <- raster(ncol=360*5, nrow= 180*5)
projection(new) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"(通过更改列数,可以使栅格更加精确。当它很低时,贴图看起来就像是由点组成的,而当它非常大时,它看起来非常平滑。当你把分辨率调得太低时,你画的“渠道”也会消失。因为它们无法与周围环境区分开来。但是,当计算时间随着栅格分辨率的增加而急剧增加时!!)
#Import Shapefile
map <- readOGR(dsn = "location of shape file" , layer = "name shape file")
#Create map from shapefile and empty map
r <- rasterize(map, new)
#replace values to 1 and 99999
values(r)[is.na(values(r))] <- 1
values(r)[values(r)>1] <- 99999因此,你最终得到了一张地图,其中一艘船可以去的所有地方都等于1,而船不能去的所有地方都是99999。
2)将端口的坐标保存在名为" ports“的矩阵中。其中第一列是经度,第二列是纬度。
应用计算最短路径所需的过渡,并应用地理校正有关地理校正的更多信息,您可以找到here。
p <- transition(r, function(x){1/mean(x)}, 8)
p <- geoCorrection(p)3)运行循环,计算所有端口之间的最短路径。最短路径的长度存储在一个称为“结果”的三列矩阵中。整个循环是并行运行的,以加快速度。
install.packages("doParallel")
install.packages("foreach")
library(foreach)
library(doParallel)
# Create cluster with number of cores of the system.
cl <- makeCluster(detectCores())
registerDoParallel(cl)
i <- 1
nrow_data <- nrow(ports)
results <- foreach(i=icount(nrow_data), .combine='rbind', .packages="gdistance") %dopar% {
A <- cbind(ports[i,1],ports[i,2])
r <- matrix(NA, ncol=3,nrow=nrow_data)
r[,1] <- i
j <- i+1
while(j<=nrow_data){
r[j,2] <- j
B <- cbind(ports[j,1],ports[j,2])
tryCatch({
path <- shortestPath(p, A,B, output = "SpatialLines")
r[j,3] <- SpatialLinesLengths(path ,longlat=TRUE)
}, error=function(e){})
j <- j+1
}
r[1:nrow_data,]
}我添加了"tryCatch“,以消除当两个端口位于彼此非常近的位置时有时会收到的错误。由于光栅的分辨率较低,因此无法区分这两个端口。
这可能不是做任何事情的最好的方式,但它对我来说非常有效!
https://stackoverflow.com/questions/28575364
复制相似问题