簡體   English   中英

操作地圖圖塊數據以與R中的柵格數據對齊

[英]Manipulating map tile data to align with raster data in R

我正在嘗試使用rgl在3D表面上繪制地圖圖塊,但無法弄清楚如何正確對齊數據。 這可能與R在矩陣和柵格之間進行轉換時添加90度旋轉的行為有關,但我也發現需要在代碼中添加翻轉以獲得正確的結果。 工作流程有點棘手,所以我把它變成了一個函數來顯示結果與輸入變量的關系。 展示:

require(raster)
require(akima)
require(OpenStreetMap)
require(rgl)

wgs84 = '+proj=longlat +datum=WGS84'

plot_3d_tile = function(z, xlims, ylims, zscale=1, zoom, crs, plot_rasters=F, ...){
  # specify raster's spatial info
  extent(z) = c(xlims, ylims); crs(z) = crs

  # extend range slightly to crop back to rect after reproj
  osm_x = extendrange(r=xlims); osm_y = extendrange(r=ylims)

  # get OSM map tile & reproject to wgs84
  m = raster(openproj(openmap(c(osm_y[2],osm_x[1]), c(osm_y[1],osm_x[2]), zoom=zoom)))
  m = crop(flip(m,'y'), extent(z))             # FLIPPED
  if(plot_rasters) plotRGB(m)

  # coerce to lists of points for akima::interp
  pts_m = rasterToPoints(m); pts_z = rasterToPoints(z)

  # resizes z to match tile
  intp = interp(x=pts_z[,1], y=pts_z[,2], z=pts_z[,3], 
                xo=unique(pts_m[,1]), yo=unique(pts_m[,2]))

  # get matrix of interpolated z values and convert back to spatial
  z2 = flip(raster(apply(intp$z, 1, rev)),'y') # FLIPPED AND ROTATED
  cat("dimensions match? ", dim(z2) == dim(raster(m)))    # check dimensions match up
  extent(z2) = extent(xlims, ylims); crs(z2) = crs  # spatialise
  if(plot_rasters) plot(z2, asp=T)
  pts_z2 = rasterToPoints(z2)

  # create hex colour vector from tile values
  col_data = getValues(m)
  cols = rgb(col_data[,1], col_data[,2], col_data[,3], maxColorValue = 255)

  # plot 3d extruded map tile
  rgl.open(); bg3d("white")
  rgl.surface(unique(pts_z2[,1]), unique(pts_z2[,2]), pts_z2[,3]*zscale, 
              color=cols, specular="black",  back="lines", asp=T, ...)
  results <<- list(z=z, z2=z2, m=m, intp=intp, pts_m=pts_m, pts_z=pts_z, pts_z2=pts_z2)
}

z1 = raster(volcano)
xlims = c(-0.24, -0.1)
ylims = c(51.4, 51.58)

現在測試一下:

plot_3d_tile(z1, xlims, ylims, zscale=1/3000, zoom=9, crs=wgs84)

在此輸入圖像描述

plot_3d_tile(z1, xlims, ylims, zscale=1/3000, zoom=10, crs=wgs84)

在此輸入圖像描述

plot_3d_tile(z1, xlims, ylims, zscale=1/3000, zoom=11, crs=wgs84)

在此輸入圖像描述

正如您所看到的,隨着OSM縮放級別的增加,開始看起來不錯的內容會逐漸變形。 我擔心就翻轉和旋轉而言,我遇到了一些問題,但這是迄今為止我所取得的最接近的組合。 我知道一個特定的問題,但代碼可能對其他人有用,所以我在這里發帖。 提前致謝。

我找到了一個解決方法。 不是將顏色信息提供給rgl.surface而是可以為其texture參數提供png。 這可能意味着我的代碼使表面光柵與瓷磚的尺寸相匹配有點多余,盡管如果表面分辨率低得多,它仍然可以使插值更平滑。 工作職能:

在此輸入圖像描述

plot_3d_tile = function(z, xlims, ylims, zscale=1, zoom, crs, plot_rasters=F, ...){
  # specify raster's spatial info
  extent(z) = c(xlims, ylims); crs(z) = crs
  if(plot_rasters) plot(z, asp=T, main='z')

  # extend range slightly to crop back to rect after reproj
  osm_x = extendrange(r=xlims); osm_y = extendrange(r=ylims)

  # get OSM map tile & reproject to wgs84
  m = raster(openproj(openmap(c(osm_y[2],osm_x[1]), c(osm_y[1],osm_x[2]), zoom=zoom)))
  m = crop(flip(m,'y'), extent(z))             # FLIPPED
  if(plot_rasters) plotRGB(m, asp=T, main='m')
  png('plot.png', width=ncol(m), height=nrow(m))
  plotRGB(m)
  dev.off()

  # coerce to lists of points for akima::interp
  pts_m = rasterToPoints(m); pts_z = rasterToPoints(z)

  # resizes z to match tile
  intp = interp(x=pts_z[,1], y=pts_z[,2], z=pts_z[,3], 
                xo=unique(pts_m[,1]), yo=unique(pts_m[,2]))

  # get matrix of interpolated z values and convert back to spatial
  z2 = raster(apply(intp$z, 1, rev)) # ROTATED
  cat("dimensions match? ", dim(z2) == dim(raster(m)))    # check dimensions match up
  extent(z2) = extent(xlims, ylims); crs(z2) = crs  # spatialise
  if(plot_rasters) plot(z2, asp=T, main='z2')
  pts_z2 = rasterToPoints(z2)

  # plot 3d extruded map tile
  bg3d("white")
  rgl.surface(unique(pts_z2[,1]), unique(pts_z2[,2]), pts_z2[,3]*zscale, 
              texture='plot.png', specular="black",  back="lines", asp=T, ...)
  results <<- list(z=z, z2=z2, m=m, intp=intp, pts_m=pts_m, pts_z=pts_z, pts_z2=pts_z2)
}

rgl.open()

plot_3d_tile(z1, xlims, ylims, zscale=1/3000, zoom=12, crs=wgs84, plot_rasters=T)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM