1. 数据获取与预处理
全球地形数据的获取是三维可视化的第一步。GEBCO(通用海底地形图)和ETOPO1作为两种常用的全球地形数据集,各有特点。GEBCO数据分辨率更高(2023版达到15弧秒),适合精细分析;ETOPO1虽然分辨率稍低(1弧分),但数据处理更简单。
下载GEBCO数据时,我习惯先在地图界面用Ctrl+鼠标拖拽选择研究区域。比如分析白令海区域时,我会将范围设为北纬50°-65°,西经160°-200°。下载的NetCDF格式文件包含经度、纬度和高程三个关键变量。这里有个细节要注意:GEBCO的高程数据中,正值表示陆地海拔,负值表示海深。为了突出海底地形,我通常会用ele(find(ele>0))=nan将陆地数据设为NaN。
ETOPO1数据的处理则更简单些。Matlab自带的etopo函数可以直接读取二进制格式的ETOPO1数据文件。不过要注意坐标系转换问题:ETOPO1使用-180°到180°的经度范围,而GEBCO使用0°到360°。我在处理白令海数据时就遇到过这个问题,东经180°附近的区域需要特别小心。
2. 基础二维可视化
在进入三维可视化前,我建议先用二维图形熟悉数据特征。Matlab的m_map工具箱特别适合绘制地理数据。以下是我常用的白令海二维可视化代码:
m_proj('mercator','lon',[160 200],'lat',[50 65]); m_coast('patch',[0.92 .92 .92],'edgecolor','none'); m_grid('linestyle','-','gridcolor','w'); hold on [x,y]=meshgrid(lon,lat); m_contourf(x,y,ele'); colormap(winter(128)); colorbar('southoutside','FontSize',12);这里有几个实用技巧:
m_coast函数绘制海岸线时,用浅灰色填充陆地([0.92 .92 .92])可以让海底地形更突出- 使用
winter色图能更好表现深度变化 - 将colorbar放在图外('southoutside')可以节省绘图空间
3. 三维地形建模
3.1 基础三维曲面绘制
Matlab的contour3函数是最简单的三维地形绘制方法:
figure('Position',[100 100 800 600]) contour3(x,y,ele',100,'fill','on'); view(-30,30) % 设置视角 xlabel('经度'); ylabel('纬度'); title('白令海三维地形','FontSize',14); light('Position',[-1 -1 0.5]) % 添加光源这个基础版本已经能展现海底地形特征,但还有优化空间:
- 通过
view函数调整视角,我通常用方位角-30°、仰角30° - 添加
light光源可以让地形阴影更明显 - 调整图形窗口大小([800 600])能获得更好的显示效果
3.2 高级曲面渲染
要获得更专业的效果,可以用surf函数配合光照设置:
figure('Position',[100 100 1000 750]) s = surf(x,y,ele',ele'); s.EdgeColor = 'none'; colormap(jet(256)) view(-40,40) light('Position',[-1 -1 0.5],'Style','infinite') material dull % 控制反射特性 camlight('headlight') % 添加相机光源这里的关键参数:
EdgeColor='none'去掉网格线使表面更平滑material控制材质反射特性,'dull'适合地形展示- 组合使用
light和camlight能产生更自然的光照效果
4. 可视化优化技巧
4.1 色图定制
默认色图可能不适合地形展示,我常用以下方法定制:
% 创建海底专用色图 cmap = [linspace(0,0.2,32)' linspace(0,0.5,32)' linspace(0.5,1,32)'; winter(224)]; colormap(cmap) caxis([-6000 0]) % 固定色标范围这个色图前32级是深蓝到浅蓝的渐变,后224级使用winter色图,特别适合表现深海地形。
4.2 地形夸张处理
海底地形起伏相对较小,可以适当夸张:
exaggeration = 5; % 夸张系数 ele_ex = ele * exaggeration;但要注意:
- 夸张系数不宜过大(建议2-5倍)
- 需要在colorbar中标明夸张比例
4.3 多视角展示
创建多视角组合图能更好展示三维特征:
figure('Position',[100 100 1200 900]) subplot(2,2,1) surf(x,y,ele'); view(0,90); title('俯视图') subplot(2,2,2) surf(x,y,ele'); view(-30,30); title('斜视图') subplot(2,2,3) surf(x,y,ele'); view(0,0); title('侧视图') subplot(2,2,4) surf(x,y,ele'); view(-60,60); title('透视图')5. 成果输出与分享
完成可视化后,高质量的输出很重要。我推荐使用矢量格式保存:
print('-dpdf','-r600','BeringSea_3D.pdf') % 矢量PDF print('-dpng','-r600','BeringSea_3D.png') % 高分辨率PNG对于需要演示的情况,可以创建旋转动画:
v = VideoWriter('terrain_rotation.mp4','MPEG-4'); open(v); for az = 0:5:360 view(az,30); frame = getframe(gcf); writeVideo(v,frame); end close(v);在实际项目中,我发现将GEBCO和ETOPO1数据结合使用效果最好:用GEBCO的高分辨率数据作为基础,ETOPO1作为补充。特别是在处理东经180°附近区域时,两种数据的坐标系差异需要特别注意。