Vue3+Cesium实战:5分钟搞定高德/百度/天地图多源地图切换(附完整代码)

张开发
2026/4/15 19:48:03 15 分钟阅读

分享文章

Vue3+Cesium实战:5分钟搞定高德/百度/天地图多源地图切换(附完整代码)
Vue3Cesium多源地图切换实战从配置优化到工程化实践最近在做一个智慧城市项目时遇到了一个典型需求需要在同一个三维场景中快速切换高德、百度和天地图三种地图源。刚开始觉得这应该很简单但实际开发中踩了不少坑——不同地图源的API差异、图层叠加顺序问题、跨域请求限制...经过几轮迭代终于总结出一套高效的解决方案。1. 环境搭建与基础配置在开始地图切换功能前我们需要确保开发环境正确配置。Vue3的组合式API与Cesium的强类型系统结合时有几个关键点需要注意# 创建Vue3项目如果尚未创建 npm init vuelatest cesium-map-demo # 安装Cesium核心库 npm install cesium cesium/engineCesium在Vue3中的初始化方式与传统HTML项目有所不同。这里推荐使用provide/inject实现单例Viewer管理// src/utils/cesiumInstance.js import { Viewer } from cesium; let viewerInstance null; export const initCesium (containerId) { if (!viewerInstance) { viewerInstance new Viewer(containerId, { terrain: Cesium.Terrain.fromWorldTerrain(), baseLayerPicker: false, // 禁用默认底图选择器 timeline: false, animation: false }); // 隐藏版权信息需遵守各地图API的授权要求 viewerInstance.cesiumWidget.creditContainer.style.display none; } return viewerInstance; };提示Cesium的CSS样式需要单独引入建议在main.js中添加import cesium/Build/Cesium/Widgets/widgets.css2. 多地图源接入方案对比国内主流地图服务在Cesium中的接入方式主要有三种实现模式地图服务接入方式关键参数是否需要密钥坐标系高德地图UrlTemplateImageryProviderstyle/z/x/y否Web墨卡托百度地图UrlTemplateImageryProviderx/y/zcustomquadtree否百度墨卡托天地图WebMapTileServiceImageryProviderLAYER/tileMatrixSet是CGCS2000高德地图接入示例const addAMapLayer (viewer, type vector) { const baseUrl type vector ? https://webst02.is.autonavi.com/appmaptile?style6x{x}y{y}z{z} : https://webst02.is.autonavi.com/appmaptile?style8x{x}y{y}z{z}; return viewer.imageryLayers.addImageryProvider( new Cesium.UrlTemplateImageryProvider({ url: baseUrl, minimumLevel: 3, maximumLevel: 18, credit: © 高德地图 }) ); };天地图特殊处理 由于天地图使用WMTS服务需要特别注意坐标转换问题const addTianDiMapLayer (viewer, tk) { const layerTypes { vec: vec_w, // 矢量底图 cva: cva_w, // 矢量注记 img: img_w, // 影像底图 cia: cia_w // 影像注记 }; return Object.entries(layerTypes).map(([key, path]) { return viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: http://t0.tianditu.gov.cn/${path}/wmts?tk${tk}, layer: key, style: default, tileMatrixSetID: w, format: tiles, tileMatrixLabels: [...Array(18).keys()].map(i i.toString()) }) ); }); };3. 动态切换的工程化实现单纯的图层叠加只是基础真正的难点在于实现流畅的切换体验和状态管理。我们采用Pinia来维护地图状态// stores/mapStore.js import { defineStore } from pinia; export const useMapStore defineStore(map, { state: () ({ currentMap: amap, mapOptions: [ { value: amap, label: 高德地图 }, { value: baidu, label: 百度地图 }, { value: tianditu, label: 天地图 } ] }), actions: { async switchMap(type) { // 先移除所有影像图层 const layers viewer.imageryLayers; while (layers.length 1) { layers.remove(layers.get(1)); } // 添加新图层 switch (type) { case amap: this.currentMap amap; await addAMapLayer(viewer); break; case baidu: this.currentMap baidu; await addBaiduMapLayer(viewer); break; case tianditu: this.currentMap tianditu; await addTianDiMapLayer(viewer, import.meta.env.VITE_TIANDI_KEY); break; } } } });对应的Vue组件实现template div classmap-container div idcesium-container/div div classmap-switcher button v-foroption in mapOptions :keyoption.value clickswitchMap(option.value) :class{ active: currentMap option.value } {{ option.label }} /button /div /div /template script setup import { onMounted } from vue; import { useMapStore } from /stores/mapStore; import { initCesium } from /utils/cesiumInstance; const mapStore useMapStore(); const { currentMap, mapOptions, switchMap } mapStore; onMounted(async () { const viewer initCesium(cesium-container); await switchMap(currentMap); }); /script4. 性能优化与常见问题排查在实际项目中我们遇到了几个典型性能问题图层闪烁问题原因新图层加载完成前短暂显示底层地图解决方案预加载所有地图源通过show属性控制显隐// 预加载所有地图 const preloadMaps async (viewer) { const amap addAMapLayer(viewer); amap.show false; const baidu addBaiduMapLayer(viewer); baidu.show false; const tianditu await addTianDiMapLayer(viewer, your_key); tianditu.forEach(layer layer.show false); return { amap, baidu, tianditu }; };内存泄漏检测 使用Cesium的MemoryUsage模块监控资源占用setInterval(() { console.log(Memory usage:, Cesium.MemoryUsage.getMemoryUsage().totalMemoryUsage); }, 5000);跨域问题解决方案开发环境配置vite代理// vite.config.js export default defineConfig({ server: { proxy: { /amap: { target: https://webst02.is.autonavi.com, changeOrigin: true, rewrite: path path.replace(/^\/amap/, ) } } } });生产环境推荐使用Nginx反向代理5. 进阶功能扩展基础切换功能实现后可以进一步优化用户体验图层混合模式// 实现50%透明度的地图叠加 viewer.imageryLayers.addImageryProvider( new Cesium.UrlTemplateImageryProvider({ url: https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}, alpha: 0.5 // 设置透明度 }) );自定义切换动画const switchWithAnimation async (type) { await viewer.scene.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(116.4, 39.9, 2000000), complete: () switchMap(type) }); };地形数据集成// 添加Cesium全球地形 viewer.terrainProvider Cesium.createWorldTerrain({ requestWaterMask: true, requestVertexNormals: true });

更多文章