【发布时间】:2016-05-25 07:59:03
【问题描述】:
我正在尝试使用 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 缩放级别的增加,开始看起来不错的东西会逐渐变形。我怀疑就翻转和旋转而言我有问题,但这是迄今为止我实现的最接近的组合。我知道一个特定的问题,但代码可能对其他人有用,所以我在这里发布。提前致谢。
【问题讨论】:
-
嘿,别再篡改我的标题了
-
不错的代码!您是否尝试过仅绘制地图图像的缩放光栅图像,以查看它们在“叠加”到 3D 景观之前的样子? (我训练有素的眼球怀疑像素行可能会被重新映射,例如将 100x100 数组写入 105xN 数组时会发生这种情况)
-
您可能是对的,尽管我已经检查了尺寸是否匹配。我添加了参数
plot_rasters,所以这可以选择自动发生。尝试使用plot_3d_tile(.. plot_rasters=T)我还添加了一行以将函数的主要元素输出到名为“结果”的列表中,以使事情变得更容易。