如何修复以太平洋为中心(0°-360°经度)显示的地图库数据?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我正在使用R maps包在世界地图上绘制一些点,如下所示:

绘制底图的命令是:

map("world", fill=TRUE, col="white", bg="gray", ylim=c(-60, 90), mar=c(0,0,0,0))

但我需要展示以太平洋为中心的地图。我使用map("world2",etc来使用地图包中的太平洋中心底图,并将dataframe(df)中数据点的坐标转换为:

df$longitude[df$longitude < 0] = df$longitude[df$longitude < 0] + 360

如果我不使用该fill选项,但fill这种方法适用于跨越0°的多边形导致问题。

我想我需要将maps库中的多边形数据以某种方式转换出来,但我不知道如何解决这个问题。

我的理想解决方案是绘制一个左边界在-20°和右边界在-30°(即330°)的地图。下面的地图将获得正确的点和海岸线,但零交叉问题是相同的

df$longitude[df$longitude < -20] = df$longitude[d$longitude < -20] + 360
map("world", fill=TRUE, col="white", bg="gray", mar=c(0,0,0,0),
  ylim=c(-60, 90), xlim=c(-20, 330))
map("world2", add=TRUE, col="white", bg="gray", fill=TRUE, xlim=c(180, 330))
提问于
用户回答回答于

可以使用这样一个事实,即在内部,map函数返回的对象map()可以重新计算并在map()函数中再次使用。我会创建一个包含单个多边形的列表,检查哪些列表具有非常不同的经度值,并重新排列这些列表。我在下面的函数*中给出了这个方法的一个例子,它允许像下面这样的东西:

plot.map("world", center=180, col="white",bg="gray",
   fill=TRUE,ylim=c(-60,90),mar=c(0,0,0,0))

要得到

如果我是你,我会把所有东西都转移一点,比如:

plot.map("world", center=200, col="white",bg="gray",
   fill=TRUE,ylim=c(-60,90),mar=c(0,0,0,0))

功能 :

plot.map<- function(database,center,...){
    Obj <- map(database,...,plot=F)
    coord <- cbind(Obj[[1]],Obj[[2]])

    # split up the coordinates
    id <- rle(!is.na(coord[,1]))
    id <- matrix(c(1,cumsum(id$lengths)),ncol=2,byrow=T)
    polygons <- apply(id,1,function(i){coord[i[1]:i[2],]})

    # split up polygons that differ too much
    polygons <- lapply(polygons,function(x){
        x[,1] <- x[,1] + center
        x[,1] <- ifelse(x[,1]>180,x[,1]-360,x[,1])
        if(sum(diff(x[,1])>300,na.rm=T) >0){
          id <- x[,1] < 0
          x <- rbind(x[id,],c(NA,NA),x[!id,])
       }
       x
    })
    # reconstruct the object
    polygons <- do.call(rbind,polygons)
    Obj[[1]] <- polygons[,1]
    Obj[[2]] <- polygons[,2]

    map(Obj,...)
}

*请注意,此功能只取正中心值。

用户回答回答于

你也可以使用投影(需要mapproj包)来创建一个移动的地图:

  map("world", projection="rectangular", parameter=0, 
      orientation=c(90,0,180), wrap=TRUE, fill=T, resolution=0,col=0)

这将会改变180度。但与'world2'的区别在于经度坐标将会不同([-pi,pi])。这个包的所有预测都将0放在中心位置。在这种情况下,'wrap'选项会正确检测跳转。

'分辨率= 0'有助于获得更清晰的边框。

扫码关注云+社区