使用R中的leaflet库绘制跨越国际日期变更线的路线。

3
我希望使用R语言的leaflet库绘制从滑铁卢到台湾的路线图。路线的坐标是使用geosphere的gcIntermediate函数获得的。然而,由于路线涉及跨越国际日期变更线,因此路线在地图边缘处被切断,并在顶部以直线连接。

我得到的图表: 错误的地图

enter image description here

我想要的图表: 理想地图

enter image description here

有可能可以使用Google地图解决这个问题,但是否有方法使用leaflet解决呢?我应该如何修改下面的代码以获得理想的路线?谢谢!
library(dplyr)
library(leaflet)
library(geosphere)

# Source
latWaterloo <- 43.46687 
lngWaterloo <- -80.52464

# Destination
latTaiwan <- 23.5983
lngTaiwan <- 120.8354


m <- leaflet() %>% addTiles()
m <- addCircleMarkers(m, lng=c(lngWaterloo, lngTaiwan) , lat=c(latWaterloo, latTaiwan), popup=c("Waterloo","Taiwan"), radius=5, opacity=0.5)
geo_lines <- gcIntermediate(c(lngWaterloo, latWaterloo), c(lngTaiwan, latTaiwan), n=100, addStartEnd=T, sp=T, breakAtDateLine=F)
m <- addPolylines(m, data=geo_lines, color="blue")
m

m <- leaflet() %>% addTiles()
m

你能生成包含路线坐标的输出吗? - LocoGris
我猜你想找到最短的路径?如果正确的路线(或多或少)经过白令海峡,那么你的“理想地图”是错误的:可能更美观,但不是最短的。最正确的方式可能是没有直线的“错误地图”。 - user10307643
谢谢!我对获取最短路径不是很感兴趣。我更关心的是展示两个位置之间连续连接的圆形路线。 - Daxaniie
3个回答

4

正如Jean-Claude在评论中所说,你手绘的路径比gcIntermediate给出的路径要长。为了得到正确的路径,只需使用breakAtDateLine=TRUE调用gcIntermediate

geo_lines <- gcIntermediate(c(lngWaterloo, latWaterloo), c(lngTaiwan, latTaiwan), n=100, addStartEnd=TRUE, sp=TRUE, breakAtDateLine=TRUE)
m <- addPolylines(m, data=geo_lines, color="blue")
m

这产生了:

screenshot

我不知道是否有一种方法可以告诉 leaflet 在越过日期线时复制路径的部分,使其直接到达绘图边缘。


2

关键在于将gcIntermediate返回的负经度加上360度。这样可以产生如下连续的图形。

enter image description here

代码:

library(dplyr)
library(leaflet)
library(geosphere)

# Source
latWaterloo <- 43.46687 
lngWaterloo <- -80.52464

# Destination
latTaiwan <- 23.5983
lngTaiwan <- 120.8354


m <- leaflet() %>% addTiles()
geo_lines <- gcIntermediate(c(lngWaterloo, latWaterloo), c(lngTaiwan, latTaiwan), n=100, addStartEnd=T, sp=F, breakAtDateLine=F)
geo_lines <- data.frame(geo_lines)

# Add 360 degrees to lngWaterloo and all the negative longitudes returned by gcIntermediate
lngWaterloo <- lngWaterloo + 360
lonn <- vector(length=nrow(geo_lines))
for (j in 1:nrow(geo_lines)) {
  if (geo_lines[j,]$lon < 0) {
    lonn[j] <- geo_lines[j,]$lon + 360
  } else {
    lonn[j] <- geo_lines[j,]$lon
  }
}

m <- addCircleMarkers(m, lng=c(lngWaterloo, lngTaiwan) , lat=c(latWaterloo, latTaiwan), popup=c("Waterloo","Taiwan"), radius=2, opacity=0.5)
m <- addPolylines(m, lng=lonn, lat=geo_lines$lat, color="blue", weight=2)
m

可能有简化代码的方法,但我不太确定如何实现。


0
一个更简单的方法是使用函数st_wrap_dateline()来处理sf对象,如下所示:
st_wrap_dateline(myLine, options = "WRAPDATELINE=YES", quiet = TRUE)

如果您正在使用sp对象,只需使用以下代码进行转换:

st_as_sf(myLine)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接