WEB端显示三维地形模型
注:正常在WEB上显示三维地形首选Cesium,本文内容仅作为研究,展示文章用DEM制作通用三维地形模型中制作的局部三维地形模型
Cesium是可以很容易的实现在WEB端三维地形的,下面的图是分别是使用基于Cesium的Mars3D和超图的iClient3D出来的效果。不过Cesium终究是基于地球的,比较适合大块区域的展示。和文章用DEM制作通用三维地形模型里做的模型效果来比,还是差点意思,资源占用也很高。加上因为三维模型都是笛卡尔坐标系,我们在制作模型的时候也使用了高斯克吕格投影坐标系,直接整个模型加到球形的Cesium里再缩放到一个县的范围那么大,必然是不能处处对应准的,所以那篇文章的成果就不太适合用Cesium展示了。
理论上只要支持gltf的webgl库比如three.js等都是可以展示我再上篇文章中生成的地形模型的,我使用的babylon.js,我在之前文章蓝牙Beacon室内定位全栈里有用过,功能比较强大,可以说是一个WebGL的三维引擎也不为过。
babylon.js的使用比较方便,引入babylon.js和加载gltf的babylonjs.loaders.js,使用canvas进行渲染。
|
首先初始化引擎和场景
let _canvas,_engine,_scene,_camera; |
在创建引擎和场景的时候,为了方便调试,可以在场景中把坐标轴展示出来,很可惜babylon.js不原生支持坐标轴展示,需要手动画上去。
//创建坐标轴 |
加载DEM glb文件
//加载DEM |
毕竟这是一个地理数据,难免需要加一些其他地理数据,因此需要实现坐标转换。这里需要再次说明,之前所有的数据制作流程都是使用的高斯克吕格投影投影,为什么要是用高斯克吕格投影请看我的文章三维GIS建模不要用墨卡托投影,高斯克吕格投影投影和经纬度之间的坐标转换请看我的文章蓝牙Beacon室内定位全栈的移动端展示模型
部分。单就我这个DEMO来说,还有一点点不同,我使用的坐标系是CGCS2000_3_Degree_GK_Zone_37而不是CGCS2000_3_Degree_GK_CM_111E(两者有啥区别以及为什么会有两种以后有机会再说),加上我们建模的时候不是直接按图像的尺寸来的,有一个缩放,因此在经纬度转成高斯克吕格投影坐标系之后,还需要做一个转换到当前的三维空间坐标,代码如下:
//经纬度转场景坐标 |
其中_center
和_cellSize
从DEM影像数据的属性信息来。
然后我们就可以按位置加入一些模型了,比如
//加载模型 |
还可以在上面加Geojson数据,但是我没找到怎么让线贴着地形走的方式。
const request = new XMLHttpRequest(); |
我想,既然画上去的线没法贴地,那我可不可以给模型贴材质贴图呢。于是,我把要在上面展示的数据转换坐标系到CGCS2000_3_Degree_GK_Zone_37,通过GeoServer发布成WMS服务,将通过WMS请求回来的图片当做材质贴图贴在模型上。代码如下:
const url = `${_geoserverUrl}/map/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=true&STYLES&LAYERS=map:xzq&SRS=EPSG:4525&WIDTH=${_imgSize[0]}&HEIGHT=${_imgSize[1]}&BBOX=${xmin},${ymin},${xmax},${ymax}` |
这里需要注意,请求里的WIDTH和HEIGHT要和建模时使用的图片成比例,我是直接使用的原尺寸。请求里面的BBOX的最大值最小值一定要是用DEM影像属性里的范围,不能错。SRS要是用对应的高斯克吕格坐标系,也不能错。
最终效果就如图了。