Cesium加载MVT矢量瓦片服务

Cesium加载MVT矢量瓦片服务

基于mapbox-vector-tiles-basic-js-renderer的方式,引入mvt-imagery-provider库加载MVT服务。

环境

基于vite创建项目

vite.config.js:

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import cesium from 'vite-plugin-cesium';
import path from 'path';

export default defineConfig({
  plugins: [vue(),cesium()],
  resolve: {
    alias: {
      cesium: path.resolve(__dirname, 'node_modules/cesium/Build/Cesium'),
    },
  },
  server: {
    port: 3000,
  },
});

依赖版本:

  "dependencies": {
    "@mapbox/vector-tile": "^2.0.3",
    "mapbox-gl": "^1.13.3",
    "mvt-imagery-provider": "^1.0.3",
    "protobufjs": "^7.4.0",
    "vue": "^3.4.21"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
    "cesium": "^1.127.0",
    "vite": "^5.4.14",
    "vite-plugin-cesium": "^1.2.23"
  }

代码

Template

mmmap用于mapboxgl地图展示,C用于Cesium地图展示

<template>
    <div id='mmmap'>
    </div>
    <div id="C">
    </div>
</template>

Script setup

引入所需的包
import { onMounted } from 'vue'
import mapboxgl from 'mapbox-gl'
import * as Cesium from 'cesium';
import MVTImageryProvider from 'mvt-imagery-provider';
onMounted:

基础配置

mapboxgl.accessToken ='your-mapboxgl-access-token';
Cesium.Ion.defaultAccessToken = "your-cesium-access-token";
const viewer = new Cesium.Viewer('C');
// 启用抗锯齿
viewer.scene.globe.enableAntialiasing = true;
//调整文本渲染质量
viewer.scene.textureAnisotropy = 16; 

根据mvt服务地址获取.json或.mvt文件,获取文件后提取出样式部分:

let response = await fetch('your-mvt-service-address');
let s = null;
if (response.ok) {
  s = await response.json();
}

注意这里的s用于后续构造ImageryProvider时作为style参数传入,s可以具有如下的基本格式:

{
  "bearing": 0,
  "center": [
    lat,
    lon
  ],
  "glyphs": "your-glyphs-service-address",
  "layers": [
    {
      "id": "id",
      "source": "your-style-source",
      "source-layer": "your-source-layer",
      "type": "symbol",
      "layout": {
        ......
      },
      "paint": {
        ...
      },
      "maxzoom": 1,
      "minzoom": 0,
    },
    ......
  ],
  "metadata": {},
  "name": "",
  "pitch": 0,
  "sources": {
    "your-style-source": {
      "rectangle": [
        lat1,
        lat2,
        lon1,
        lon2
      ],
      "tiles": [
        "your-tile-service-address"
      ],
      "type": "vector"
    }
  },
  "sprite": "your-sprite-service-address",
  "version": 8,
  "zoom": 1
}
部分数据处理:

由于mvt-imagery-provider包年久失修,部分内容与新版本框架有冲突,部分冲突如下:

精灵图服务地址:

//mvt-imagery-provider包会根据传入的style参数中的sprite属性构造精灵图服务地址,当前版本会在地址后自动添加@2x表示2级清晰度,所以需要修改精灵图服务地址为如下格式:
s.sprite = "http://your-sprite-service-address/sprite";
//如此修改后最终的请求URL即为http://your-sprite-service-address/sprite@2x

绘制属性冲突:

在图层的绘制属性(paint)中,fill-pattern属性和其他属性冲突导致type为fill的面类型数据不能正常加载,将该属性删除:

for (let lyr of s['layers']){
  let {layout, paint} = lyr;
  if (paint.hasOwnProperty('fill-pattern')){
      delete paint['fill-pattern'];
  }
}

布局属性冲突:

在图层的布局属性(layout)中,text-radial-offset径向偏移量属性Cesium无法识别,直接删除。同时text-justify属性可能被设置为auto,而Cesium对于该属性只接受center、left、right三个配置,改为居中即可。

for (let lyr of s['layers']){
  if (layout.hasOwnProperty('text-radial-offset')){
      delete layout['text-radial-offset'];
  }
  if (layout.hasOwnProperty('text-justify')){
      if (layout['text-justify'] === 'auto'){
          layout['text-justify'] = 'center';
      }
  }
}

图层顺序:

如果部分图层未能看到可能是因为加载顺序的原因,尝试将图层反转:

s.layers.reverse();

构造provider并添加入图层:

const mvtProvider = new MVTImageryProvider({
    style: s,
  });
viewer.imageryLayers.addImageryProvider(mvtProvider);

图标与文字:

MVT服务所需的文字是通过字形服务获取到的,即"glyphs": “your-glyphs-service-address”,该服务获取到的往往是.pbf文件,Cesium不一定能识别,可能会出现只展示图标而未能展示文字的情况。对此可以将文字部分单独加载,忽略layers中type为symbol的图层,即图标文字图层,将数据源通过Cesium创建独立实体加载:

如果数据源为.gdb文件可通过ArcGIS的要素转JSON工具将其转换为GeoJSON类型数据加载,注意坐标系应选择WGS_1984(WGS84)。

具体添加方法可以看这篇:Cesium加载GeoJson数据添加文字标签

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值