Cesium教程 (3) 矢量切片mvt-imagery-provider加载
目录
0. 矢量切片
1. 开源项目
2. 环境
3. 代码
4. TODO
0. 矢量切片
WMTS:加载最快,图片格式,样式固定;
WMS:加载数量大则慢,但可以点击查询等;
WFS:编辑矢量属性信息,很少用;
矢量切片:XYZ、TMS的服务方式,想要经常更新样式,且快速渲染,那么矢量切片最合适。其速度在WMTS和WMS之间。标准主要为mvt-pbf。
矢量切片:mapbox提出的,mapbox-gl、maplibre-gl、openlayers、leaflet都支持,这几个属mapbox功能性能最好。但是mapbox的开源协议从2之后不友好,即使其2.9之后有球的形状,但是对于三维的功能不如cesium更强大,但是cesium不支持mvt的矢量切片,支持小数据量的geojson,超过5000 entities的geojson cesium会崩溃。如果想让cesium能实现类似矢量切片的渲染,只能通过仿照imageryProvider。mapbox有这样的能力,直接通过其加载,再渲染给cesium。
1. 开源项目
网上搜索的cesium矢量切片:cesium加载mvt格式的矢量切片、cesium加载arcgis server的矢量切片,前者是开源的,后者需要商用,既然有商用的没太大必要,直接用其API即可。所以,我们主要用开源的mvt。
https://github.com/landtechnologies/Mapbox-vector-tiles-basic-js-renderer 基础核心,cesium能实现mvt矢量切片渲染的底层关键,很多项目都是通过调用它来进一步实现的。
https://github.com/hongfaqiu/MVTImageryProvider 推荐!本文所使用的库,依赖的maobox-gl版本样式较老为0.43.0,但是支持到mapbox-gl 1.x版本,不过对于basic样式足够了,应该满足需求。当然这个也是参考了https://github.com/kikitte/MVTImageryProvider实现的。
https://github.com/reearth/cesium-mvt-imagery-provider 当然也可以用这个!
https://github.com/davenquinn/cesium-vector-provider
2. 环境
cesium 1.103及其以下版本
mvt-imagery-provider (其主要通过这个库 mvt-basic-render 来渲染,这里支持ES6,如果想直接用Mapbox-vector-tiles-basic-js-renderer的mapbox-gl.js 推荐在html script引入,因为其是commonJS)
vue3
采用vue-cli,那么webpack打包必不可少,vue.config.js配置vue3配置cesium参考vue3 cesium安装配置教程(共5种方式-推荐第3-4种)_LEILEI18A的博客-CSDN博客
3. 代码
// 主要采用ES6格式的 TS的 mvt-imagery-provider
<template>
<div id="container">
<div id="CesiumContainer"></div>
</div>
</template>
<script>
import {reactive, ref, onMounted} from "vue";
import * as Cesium from "cesium";
import "cesium/Source/Widgets/widgets.css";
// import MVTImageryProvider from "../utils/util.js";
import MVTImageryProvider from "mvt-imagery-provider";
export default {
name: "Data02",
components: {
},
setup(){
var legend = reactive({});
const firstCesium = ()=>{
//测试本地geoserver 或者 postgis产生的mvt矢量切片
const geoserverStyle = {
version: 8,
sources: {
maplibre: {
type: "vector",
// 'scheme': 'tms',
tiles: ['https://demotiles.maplibre.org/tiles/{z}/{x}/{y}.pbf'],
maxzoom: 6,
minzoom: 0,
},
},
// glyphs: "https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf",
layers: [
// {
// id: "00",
// 'source': 'maplibre',
// 'source-layer': 'countries',
// type: "fill",
// paint: {
// "fill-color": "#fdaf6b",
// },
// }
{
"id": "countries-fill",
"type": "fill",
"paint": {
"fill-outline-color": "#000000",
"fill-antialias": true,
"fill-color": [
"match",
[
"get",
"ADM0_A3"
],
[
"ARM",
"ATG",
"AUS",
"BTN",
"CAN",
"COG",
"CZE",
"GHA",
"GIN",
"HTI",
"ISL",
"JOR",
"KHM",
"KOR",
"LVA",
"MLT",
"MNE",
"MOZ",
"PER",
"SAH",
"SGP",
"SLV",
"SOM",
"TJK",
"TUV",
"UKR",
"WSM"
],
"#D6C7FF",
[
"AZE",
"BGD",
"CHL",
"CMR",
"CSI",
"DEU",
"DJI",
"GUY",
"HUN",
"IOA",
"JAM",
"LBN",
"LBY",
"LSO",
"MDG",
"MKD",
"MNG",
"MRT",
"NIU",
"NZL",
"PCN",
"PYF",
"SAU",
"SHN",
"STP",
"TTO",
"UGA",
"UZB",
"ZMB"
],
"#EBCA8A",
[
"AGO",
"ASM",
"ATF",
"BDI",
"BFA",
"BGR",
"BLZ",
"BRA",
"CHN",
"CRI",
"ESP",
"HKG",
"HRV",
"IDN",
"IRN",
"ISR",
"KNA",
"LBR",
"LCA",
"MAC",
"MUS",
"NOR",
"PLW",
"POL",
"PRI",
"SDN",
"TUN",
"UMI",
"USA",
"USG",
"VIR",
"VUT"
],
"#C1E599",
[
"ARE",
"ARG",
"BHS",
"CIV",
"CLP",
"DMA",
"ETH",
"GAB",
"GRD",
"HMD",
"IND",
"IOT",
"IRL",
"IRQ",
"ITA",
"KOS",
"LUX",
"MEX",
"NAM",
"NER",
"PHL",
"PRT",
"RUS",
"SEN",
"SUR",
"TZA",
"VAT"
],
"#E7E58F",
[
"AUT",
"BEL",
"BHR",
"BMU",
"BRB",
"CYN",
"DZA",
"EST",
"FLK",
"GMB",
"GUM",
"HND",
"JEY",
"KGZ",
"LIE",
"MAF",
"MDA",
"NGA",
"NRU",
"SLB",
"SOL",
"SRB",
"SWZ",
"THA",
"TUR",
"VEN",
"VGB"
],
"#98DDA1",
[
"AIA",
"BIH",
"BLM",
"BRN",
"CAF",
"CHE",
"COM",
"CPV",
"CUB",
"ECU",
"ESB",
"FSM",
"GAZ",
"GBR",
"GEO",
"KEN",
"LTU",
"MAR",
"MCO",
"MDV",
"NFK",
"NPL",
"PNG",
"PRY",
"QAT",
"SLE",
"SPM",
"SYC",
"TCA",
"TKM",
"TLS",
"VNM",
"WEB",
"WSB",
"YEM",
"ZWE"
],
"#83D5F4",
[
"ABW",
"ALB",
"AND",
"ATC",
"BOL",
"COD",
"CUW",
"CYM",
"CYP",
"EGY",
"FJI",
"GGY",
"IMN",
"KAB",
"KAZ",
"KWT",
"LAO",
"MLI",
"MNP",
"MSR",
"MYS",
"NIC",
"NLD",
"PAK",
"PAN",
"PRK",
"ROU",
"SGS",
"SVN",
"SWE",
"TGO",
"TWN",
"VCT",
"ZAF"
],
"#B1BBF9",
[
"ATA",
"GRL"
],
"#FFFFFF",
"#EAB38F"
]
},
"filter": [
"all"
],
"layout": {
"visibility": "visible"
},
"source": "maplibre",
"maxzoom": 24,
"source-layer": "countries"
},
]
};
const provider = new MVTImageryProvider({
style: 'https://demotiles.maplibre.org/style.json',
// style: geoserverStyle,
});
let viewer = new Cesium.Viewer("CesiumContainer", {
// infoBox: false,
// imageryProvider: new Cesium.TileCoordinatesImageryProvider(),
imageryProvider: provider,
});
// viewer.imageryLayers.addImageryProvider(new Cesium.TileCoordinatesImageryProvider())
// 去掉logo
viewer.cesiumWidget.creditContainer.style.display = "none";
// 去掉背景图层
// viewer.imageryLayers.removeAll();
// 鼠标右键 倾斜操作
viewer.scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.RIGHT_DRAG
];
// 鼠标滑轮 放缩操作
viewer.scene.screenSpaceCameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
// Cesium.CameraEventType.PINCH
];
// 鼠标左键 3D下聚焦局部时给人感觉是平移-本质是地球旋转(范围小-旋转类似平移)
viewer.scene.screenSpaceCameraController.rotateEventTypes = [
Cesium.CameraEventType.LEFT_DRAG
];
};
onMounted(() => {
firstCesium()
});
return {
legend,
}
}
}
</script>
<style lang="scss" scoped>
#container {
position: relative;
height: 100%;
}
#CesiumContainer {
height: 100%;
width: 100%;
}
#legend {
position: absolute;
bottom: 100px;
right: 20px;
}
</style>
采用https://demotiles.maplibre.org/style.json加载的,但是不直观
采用自定义json style,即:代码中的geoserverStyle,对于mapbox style基本样式、以及匹配规则可百度即可:对于样式要求mapbox-gl>0.43的,就实现不了了。
4. TODO
[1] 探索cesium-mvt-imagery-provider这个项目,更新的时间也挺新的,类似本文的推荐探索过程。
[2] 直接探索Mapbox-vector-tiles-basic-js-renderer,虽然其采用的mapbox版本比较老,但是对于日常需求满足。参考多个mvt-imagery-provider项目,引入Mapbox-vector-tiles-basic-js-renderer中dist的mapbox-gl.js(commonJS引入),按照cesium1.105最新版本改写相关代码,渲染通过前面的mapbox-gl.js实现。主要是根据cesium ImageryProvider的readyPromise 采用哪个函数代替,其已弃用。
[3] 对于小数据量用geojson,对于影像采用静态WMTS代理,对于大矢量数据,推荐采用postgis动态实现mvt切片(成熟技术),然后前端cesium+mvt-provider实现矢量的渲染点击查看。对于空间分析暂时通过sql 分页 geojson实现高亮等!
[4] 如果确定肯定不涉及三维的大数据(倾斜、点云、三维矢量等),那么直接采用mapbox-gl,虽然其有开源协议限制,但是自定义样式即可!其也有球的形状了,另外可通过第三方库实现3dtiles三维的加载。