3DTiles协议设计用于流式处理和渲染大量3D地理空间内容。本文主要研究如何下载Cesium官方提供的测试数据,以便更好的研究3dtiles格式。
总述
本文通过nodejs代码实现了从CesiumIcon下载测试3dtiles数据。下载的数据来源如下网址:
https://sandcastle.cesium.com/?src=3D%20Tiles%20Feature%20Picking.html
下载数据保存内容如下:
实现
涉及到的相关类库
名称 | 作用 |
reques | 用于http的请求 |
zlib | 对压缩数据的解压 |
fs | 写文件 |
path | 获取文件的路径 |
调用流程:
首先获取tileset.json文件,然后解析所有children对象,获取所有content的uri。即下面红色的地址,保存到一个队列。tileset的格式可以参考官方文档:https://github.com/CesiumGS/3d-tiles/tree/master/specification#tileset-json
大概格式如下图所示:
然后再通过http请求把所有url的数据请求下来并保存成文件。如果遇到url的格式是json,那么重新进入开头的流程。
主要实现
1、获取tileset的所有content的uri
这里采用的一个递归函数来实现。首先遍历当前children的所有对象,如果是content就把url保存起来,如果又是一个children那么就递归调用,最后将所有的uri保存到一个数组里面。伪代码如下:
function getChildrenUrl(children: any) {
for (let i = 0; i < length; i++) {
const _child = children[i]
if (_child.hasOwnProperty('content')) {
stack.push(_child.content.uri)
}
if (_child.hasOwnProperty('children')) {
stack = stack.concat(getChildrenUrl(_child.children))
}
}
return stack
}
2、同时发起N个http的请求下载tile
正常的逻辑遍历uri的队列,一个下载完之后再去下载接下来的一个数据。伪代码如下:
while (totalUrl.length > 0) {
let tileUrl: string = totalUrl.pop()
await downloadTile(tileUrl)
}
但是由于我们数据量比较大,一个一个下载太耗费时间,所以我们需要设计成可以支持同时指定路数的并发下载。再看下面的代码
while (totalUrl.length > 0) {
let tileUrl: string = totalUrl.pop()
downloadTile(tileUrl)
}
这段代码和开始代码最大的区别就是去掉了await。这样带来的后果就是会把http请求一次性全部发送数据。不过这肯定无法接受,因为无论是网络带宽还是后台服务都扛不住。不过我们可以改造一下这段代码,增加一个标志位,比如如果当前的http并发请求超过5路,我们就让while循环睡眠50毫秒,接下来再检查当前的并发路数,如果小于5路了,就可以再次发起请求了。伪代码如下:其中maxDownload为全局参数,用来设置http的并发路数。
while (totalUrl.length > 0) {
if (taskNumber.currentTask > maxDownload) {
await sleep(50)
continue
}
let tileUrl: string = totalUrl.pop()
downloadTile(tileUrl, taskNumber)
}
这里说一下sleep函数,这个函数在nodejs中并不存在,不过我们可以通过
setTimeout来进行模拟,伪代码如下:
//模拟线程的休眠
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(() => resolve(0), ms))
}
3、cesiumIcon下载数据
我们代码编写好之后,还需要知道去哪里下载数据。这里讲述了如何通过浏览器网络调试获取cesiumIcon的3dtiles的url地址以及如何通过权限校验。看下图:
url的地址如下:
https://assets.cesium.com/75343/tileset.json?v=1
鉴权如下
Authorization:
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjM2E5NjM1ZS03MzMxLTRlNTQtYTk0Yi01NDU0MjkyMzE5NGUiLCJpZCI6MjU5LCJhc3NldHMiOnsiNzUzNDMiOnsidHlwZSI6IjNEVElMRVMifX0sInNyYyI6ImRlZmE0YTY1LTQ0MTUtNDEzZi1hMTBhLWU5MWVjM2Y4MDJjNiIsImlhdCI6MTYxNzU0MDEyNiwiZXhwIjoxNjE3NTQzNzI2fQ.SaNdWVx_-zBuKzSXBPJ-iPut48W3Iwlz2eTegbQf450
有了上述两个数据,我们就可以通过本工具去下载3dtiles数据了。
写在最后:
可以关注本人公众号:
迷途小书童爱读书
或者扫描如下二维码:
回复3dtiles下载
即可获得已经下载好的一份官方3dtiles测试数据以及nodejs的代码。