前言
最近在研究Cesium,首先就需要有个可以加载的三维模型。发现香港提供了可下载的三维实景模型,故下载后加载到Cesium中。现将这个过程分享一下,最后有几个疑问也想请看到的友友解答一下。
一、获取模型
下载链接是:Planning Department Hong Kong 3D Photo-realistic Model 規劃署 香港三維實景模型 规划署 香港三维实景模型 (pland.gov.hk)
如图所示:
因为要加载到Cesium中,选择了3D Tiles,在左侧点击想要的窗格,最多可以选择六个,然后点击download,后发现报错,错误原因见下图,该ppgis的域名失效了。
后来找到一个可以正确下载的链接,具体见文档:
以
https://pdmap.pland.gov.hk/PLANDWEB/public/3d_photo_realistic_models/cesium/tile_20_27_CESIUM.zip
为例,只要对照上面下载链接中窗口的序号,将上面的20、27替换成想要序号的就可以下载了。这里可以借用下面简单的脚本简化下载过程,在开发者工具中运行即可
function downloadFile (url, fileName) {
const link = document.createElement('a')
link.href = url
link.download = fileName
link.target = "_blank" // 可选,如果希望在新窗口中下载文件,请取消注释此行
link.click()
}
async function fn () {
let arri = [21,22,23], arrj = [24,25,26,27]
for (let i = 0; i < arri.length; i++) {
for (let j = 0; j < arrj.length; j++) {
let url = `https://pdmap.pland.gov.hk/PLANDWEB/public/3d_photo_realistic_models/cesium/tile_${arri[i]}_${arrj[j]}_CESIUM.zip`
await downloadFile(url, `tile_${arri[i]}_${arrj[j]}_CESIUM.zip`)
}
}
}
fn();
二、加载模型
我是在Vue中使用Cesium,将解压后的3DTiles文件放入public中
通过以下代码加载模型
// 初始化Cesium
this.initMap();
// 加载3dTiles
let arri = [21, 22, 23, 24, 25, 26, 27, 28], arrj = [24, 25, 26, 27]
for (let i = 0; i < arri.length; i++) {
for (let j = 0; j < arrj.length; j++) {
let url = `/nine/tile_${arri[i]}_${arrj[j]}_CESIUM/tileset.json` // 这个就是public中的模型地址
this.add3DTiles(url);
}
}
initMap () {
this.viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false,
animation: false, //左下角的动画仪表盘。这个仪表盘实在太大,并不怎么好看。
baseLayerPicker: false, //右上角的图层选择按钮
geocoder: false, //搜索框
homeButton: false, //home按钮
sceneModePicker: false, //模式切换按钮
timeline: false, //底部的时间轴
navigationHelpButton: false, //右上角的帮助按钮,
fullscreenButton: false //右下角的全屏按钮。我们可以自己实现全屏按钮
})
// 初始化场景位置
this.viewer.scene.camera.setView({
// 初始化相机经纬度
destination: new Cesium.Cartesian3.fromDegrees(119.2, 34.6, 500),
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-90),
roll: Cesium.Math.toRadians(0)
}
});
// 清除原有的建筑模型
this.viewer.imageryLayers.removeAll()
// 去掉cesium的logo
this.viewer._cesiumWidget._creditContainer.style.display = "none";
// 显示帧率
this.viewer.scene.debugShowFramesPerSecond = true;
// 加载高德地图
var layer = new Cesium.UrlTemplateImageryProvider({
url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
minimumLevel: 4,
maximumLevel: 18
})
this.viewer.imageryLayers.addImageryProvider(layer);
}
async add3DTiles (url) {
const tileset = await Cesium.Cesium3DTileset.fromUrl(url)
this.viewer.scene.primitives.add(tileset); // 将倾斜摄影实体加载到地图上
this.viewer.zoomTo(tileset)
}
注意:我看好多博客写加载3DTiles用的方法是:new Cesium.Cesium3DTileset({url:""}),但是我用了这个方法会报错,可能是版本的问题,查阅文档改用了现在的方法。
三、加载效果
四、疑问
上面就是我这段时间看了好多博客得来的成果,希望能对大家有所帮助。但是我有几个疑问,希望能得到解答。
- 该模型放大后发现细节很模糊,不知道是我加载的问题,还是提供的模型就很模糊
- 我把下载的模型都引入到public中,发现文件数量很多且很大。实际开发项目中,是如何处理3Dtiles文件的,总不能就是放到public中和项目一起打包吧?是用服务器发布服务吗?
- 如果是用服务器发布服务的形式,前端通过url调用,那么这么多文件也要调用这么多次吗?我也想过使用cesiumLab的合并模型功能,但是它恰恰不支持本模型,遂作罢。
望解答。