利用CesiumLab地形pak文件发布Cesium地形服务

Cesiumlab提供了两种地形切片方式,一种是散列文件,一种是sqlite数据库形式。

散列文件数量往往巨大,拷贝和发布需要耗费较长的时间,因此选用sqlite形式,该方案需要自己写服务发布。本人试着用Node.js+Koa2写了一个地形发布服务。

根据帮助文件,sqlite数据库包括infos表和blocks表两种,infos表主要存储了layer.json文件,blocks表则存储了terrain文件。为了提高查询效率,blocks表根据层级划分为了不同的表。如果一个块的索引为x、y、z,如果  z < 10,那么表名是blocks,否则表名为“blocks_” + tostring(z) + “_” + tostring(x / 512) + “_” + tostring(y / 512) 。

服务发布方法如下:

const path = require('path');
const Koa = require('koa');
const app = new Koa();
const serve = require('koa-static');
const router = require('koa-router')();
const SqliteDB = require('./src/js/sqlite.js').SqliteDB;

// 静态文件
const home = serve(path.join(__dirname) + '/src/');
app.use(home);

// 引入sqlite数据库
var file = "./src/data/dem.pak";
var sqliteDB = new SqliteDB(file);

// 查询layer.json文件,由于查询需要时间,所以使用Promise形式,否则会加载失败
function layerQuery() {
    let querySql = 'select layerjson from infos where type = "terrain"';
    return new Promise((resolve, reject) => {
        sqliteDB.queryData(querySql, (obj) => {
            if (obj.length > 0) {
                let layerBuf = obj[0].layerjson;
                // 需要把Buffer转为字符串,否则无法读取
                resolve(layerBuf.toString('utf-8'));
            } else {
                reject('查询结果为空!');
            }
        })
    });
}

// 查询地形文件
function blockQuery(x, y, z) {
    let tableName = z < 10 ? 'blocks' : `blocks_${z.toString()}_${Math.floor(x/512).toString()}_${Math.floor(y/512).toString()}`;
    let querySql = `select tile from ${tableName} where x=${x} and y=${y} and z=${z}`;
    return new Promise((resolve, reject) => {
        sqliteDB.queryData(querySql, (obj) => {
            if (obj.length > 0) {
                let layerBuf = obj[0].tile;
                // 地形文件不需要转格式
                resolve(layerBuf);
            } else {
                reject('查询结果为空!');
            }
        })
    });
}

// 添加路由
router.get('/dem', '/dem/layer.json', async(ctx) => {
    await layerQuery().then(res =>
        ctx.body = res
    ).catch(rej =>
        ctx.body = rej
    );
});

router.get('/dem', '/dem/:z/:x/:y.terrain', async(ctx) => {
    await blockQuery(ctx.params.x, ctx.params.y, ctx.params.z).then(res => {
        ctx.body = res
    }).catch(rej =>
        ctx.body = rej
    );
});

// 加载路由中间件
app.use(router.routes());
app.listen(3000);

 效果如下图所示:

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C 加载pak文件是指在计算机中加载、读取和使用pak文件pak文件是一种资源文件格式常用于存储游戏或软件中的各种素材(如图片、音频、视频等)和配置文件。 加载pak文件首先需要通过程序代码找到pak文件的路径,并创建一个合适的数据结构来存储pak文件的内容。接着,需要使用相应的文件读取函数来读取pak文件,并将其内容解析存储到内存中。 一般情况下,pak文件内部会使用目录结构来组织其中的资源文件。所以,在加载pak文件时,还需要对其内部的目录结构进行解析,并根据需要进行索引和查找。这通常包括读取pak文件中的目录索引表或相应的配置文件。有了正确的索引,程序就能够快速地找到所需的资源文件并进行加载和使用。 加载pak文件主要有以下几个步骤: 1. 打开pak文件,可以使用文件读取函数将pak文件读入内存。 2. 解析pak文件的头部信息,获取pak文件的版本、文件数量等信息。 3. 解析目录索引表或配置文件,构建内存中的适当数据结构,如哈希表或树结构,用于快速查找和访问pak文件中的资源。 4. 根据需要,逐个读取和加载pak文件中的资源文件到内存中,并进行必要的处理,如解码、解压缩等。 5. 在程序需要使用pak文件中的资源时,根据已构建的数据结构进行快速的资源访问。 总之,加载pak文件是一项复杂的任务,需要在程序中实现相关的文件读取、解析和资源管理功能。通过正确加载和使用pak文件,程序可以高效地获取和利用其中的资源,提升用户体验和程序性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值