如何在R中实现2D与3D组合地图的渲染绘制
R复刻《图形语法》悬浮3D曲面+平面等高线填色图方案
你推测的rgl::persp3d()实现路径是完全可行的,两个核心疑问的解决方式如下:
共形映射实现
共形映射的核心是保证平面地理要素和3D曲面的坐标严格对齐、无角度变形,不需要手写复杂转换函数,按以下步骤操作即可:
- 所有空间数据(州界多边形、用于生成曲面的栅格/插值数据)提前用
sf::st_transform()统一转换为美国本土专用的Albers等积圆锥投影(EPSG:5070),该投影对美国大陆区域满足共形(保角)要求,不会出现形状拉伸变形。 - 提取投影后数据的x、y坐标极值,作为
persp3d()的xlim、ylim参数输入,保证3D坐标轴范围和平面地理数据范围完全重合。 - 调用rgl场景初始化后执行
aspect3d("iso"),强制三个坐标轴使用统一比例尺,避免渲染时自动拉伸破坏坐标对应关系。
3D场景中绘制2D填色地图与等高线
rgl没有专门的“2D图层”接口,本质上只要把所有平面要素的z坐标固定在同一个低于曲面的基准高度,就能实现平面贴在XY轴位置的效果:
- 先计算3D曲面的z值最小值,将基准平面的z值设为比最小值低5%~10%的位置,避免后续绘制的平面要素和曲面穿模。
- 填色多边形绘制:遍历投影后的州界多边形,提取每个多边形的x、y坐标,用
rgl::polygon3d()绘制,所有点的z参数统一传入之前设定的基准z值,填充色、边框色按需求设置即可。 - 等高线绘制:提前用
grDevices::contourLines()基于曲面矩阵生成对应层级的等高线坐标,同样把所有等高线点的z值设为基准平面高度,用rgl::lines3d()逐段绘制即可。 - 最后调用
persp3d()绘制3D曲面,设置add = TRUE把曲面叠加到已有场景中,给曲面加alpha = 0.6~0.8的半透明材质,既能看到曲面起伏,也不会完全遮挡下方平面的内容。
核心参考代码
library(rgl) library(sf) library(terra) # ---------------------- # 数据准备(替换为你自己的数据集即可) # ---------------------- # 读入州界数据,统一转共形投影 us_states <- st_read(system.file("shape/nc.shp", package="sf"), quiet = T) |> st_transform(5070) # 示例用高程数据生成曲面矩阵,实际使用替换为你的指标数据 dem <- terra::rast(system.file("ex/elev.tif", package="terra")) |> terra::project(st_crs(us_states)$wkt) dem_mat <- terra::as.matrix(dem, wide = T) x_seq <- seq(terra::ext(dem)[1], terra::ext(dem)[2], length.out = ncol(dem_mat)) y_seq <- seq(terra::ext(dem)[3], terra::ext(dem)[4], length.out = nrow(dem_mat)) # ---------------------- # 3D场景绘制 # ---------------------- # 初始化场景,等比例坐标轴 open3d(verbose = F) aspect3d("iso") # 设置基准平面z值,比曲面最低点低200单位避免穿模 base_z <- min(dem_mat, na.rm = T) - 200 # 1. 绘制平面填色地图 for (i in seq_len(nrow(us_states))) { poly_xy <- st_coordinates(us_states[i,])[, 1:2] polygon3d( x = poly_xy[,1], y = poly_xy[,2], z = base_z, col = "#f0f0f0", border = "white" ) } # 2. 绘制平面等高线 contour_segs <- contourLines(x = x_seq, y = y_seq, z = dem_mat, nlevels = 8) for (seg in contour_segs) { lines3d( x = seg$x, y = seg$y, z = base_z, col = "#636363", lwd = 1 ) } # 3. 绘制上方悬浮3D曲面 persp3d( x = x_seq, y = y_seq, z = dem_mat, add = T, alpha = 0.7, col = terrain.colors(8) )
小提示:如果需要强化等高线和曲面的对应关系,可以从等高线的关键节点向上绘制垂直连线,连接到曲面对应z值的位置,视觉引导效果会更好。
内容的提问来源于stack exchange,提问作者ctesta01
相关产品推荐
相关产品推荐

