Cesium地图二次封装与实战应用(附完整源码)
本文将带你如何用 JavaScript 对 Cesium 地图进行二次封装,并在 Vue(包含vue2、vue3) 项目中实现丰富的地图交互功能。文末附完整源码,适合前端地图开发者参考和实践。
一、为什么要封装 Cesium 地图?
Cesium 是业界领先的 WebGL 三维地球引擎,功能强大但 API 较为底层。实际项目中,我们常常需要:
- 统一管理地图实例
- 简化点、线、面、围栏、3D Tiles 等常用操作
- 支持自定义交互、测量、标注、弹窗等业务需求
因此,进行一层面向业务的封装,可以极大提升开发效率和代码可维护性。
二、CesiumMap.js 封装核心代码
我们将 Cesium 的常用操作封装成一个类,支持点、线、面、圆、围栏、3D Tiles、热力图、测量、截图等功能。
文件结构:
src/
utils/
CesiumMap.js // Cesium地图封装
components/
CesiumMapDemo.vue // Vue组件实战
1. CesiumMap.js 封装类(核心片段)
// src/utils/CesiumMap.js
import * as Cesium from 'cesium';
Cesium.Ion.defaultAccessToken = '你的CesiumToken';
export default class CesiumMap {
constructor(containerId, options = {}) {
this.viewer = new Cesium.Viewer(containerId, {
animation: false,
timeline: false,
baseLayerPicker: false,
// ... 其他参数
...options
});
}
// 添加点
addEntity(entityOptions) {
return this.viewer.entities.add(entityOptions);
}
// 移除实体
removeEntity(entity) {
this.viewer.entities.remove(entity);
}
// 相机飞行
flyTo(target, options = {}) {
// 支持实体、坐标、数组等多种形式
// ... 见完整代码
}
// 添加marker
addMarker({ lon, lat, image, width = 32, heightPx = 32, name = '', description = '' }) {
return this.viewer.entities.add({
name,
position: Cesium.Cartesian3.fromDegrees(lon, lat),
billboard: { image, width, height: heightPx },
description,
});
}
// 添加折线
addPolyline({ positions, color = Cesium.Color.BLUE, width = 3, name = '', description = '' }) {
return this.viewer.entities.add({
name,
polyline: {
positions: positions.map(p => Cesium.Cartesian3.fromDegrees(...p)),
width,
material: color,
},
description,
});
}
// 添加圆
addCircle({ lon, lat, radius, color = Cesium.Color.GREEN.withAlpha(0.5), outlineColor = Cesium.Color.GREEN, outlineWidth = 2, name = '', description = '' }) {
return this.viewer.entities.add({
name,
position: Cesium.Cartesian3.fromDegrees(lon, lat),
ellipse: {
semiMajorAxis: radius,
semiMinorAxis: radius,
material: color,
outline: true,
outlineColor,
outlineWidth,
},
description,
});
}
// ... 还有多边形、围栏、3D Tiles、热力图、测量等方法
// 见文末完整代码
}
完整 CesiumMap.js 源码见项目仓库或文末下载方式。
三、Vue3 组件实战:CesiumMapDemo.vue
我们将 CesiumMap 封装类应用到 Vue3 组件中,实现丰富的地图交互。
1. 组件结构
<template>
<div class="cesium-map-demo">
<div ref="mapContainer" class="map-container"></div>
<div class="toolbar">
<button @click="addPoint">添加点</button>
<button @click="addPolyline">画线</button>
<button @click="addCircle">画圆</button>
<button @click="addPolygon">画多边形</button>
<!-- ... 其他按钮 ... -->
</div>
<div v-if="measureResult" class="measure-result">{{ measureResult }}</div>
<!-- 属性弹窗 -->
<div v-if="popupVisible" class="popup" :style="{ left: popupScreen.x + 'px', top: popupScreen.y + 'px' }" v-html="popupContent"></div>
</div>
</template>
2. 组件核心逻辑
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import CesiumMap from '../utils/CesiumMap';
const mapContainer = ref(null);
let cesiumMap = null;
let pointEntity = null;
let polylineEntity = null;
let circleEntity = null;
let polygonEntity = null;
onMounted(() => {
cesiumMap = new CesiumMap(mapContainer.value);
// 注册实体点击事件,显示弹窗
cesiumMap.onEntityClick(({ entity, screenPosition }) => {
// ... 弹窗逻辑
});
});
onBeforeUnmount(() => {
cesiumMap && cesiumMap.destroy();
});
// 添加点
function addPoint() {
if (pointEntity) return;
pointEntity = cesiumMap.addEntity({
position: CesiumMap.Cartesian3.fromDegrees(116.3913, 39.9075, 100),
point: { pixelSize: 10, color: CesiumMap.Color.RED },
description: '北京',
});
}
// 添加折线
function addPolyline() {
if (polylineEntity) return;
polylineEntity = cesiumMap.addPolyline({
positions: [
[116.3913, 39.9075],
[116.3974, 39.9087],
[116.4053, 39.9200],
],
color: CesiumMap.Color.BLUE,
width: 4,
name: '示例线',
description: '北京示例线',
});
}
// ... 还有画圆、画多边形、交互绘制、测量、围栏、弧形、标记点等丰富功能
</script>
完整 CesiumMapDemo.vue 源码见文末。
四、主要功能亮点与效果说明
- 支持点、线、面、圆、围栏、3D Tiles、热力图等一键添加
- 支持鼠标交互绘制线、面、圆、围栏、弧形
- 支持距离、面积测量
- 支持属性弹窗、标记点、围栏管理等
- 支持相机飞行、截图、事件注册等高级功能
- 兼容性检测,适配不同 Cesium 版本
效果演示:
- 具体效果可以到文本末进行下载查看
五、总结与参考
通过对 Cesium 地图的二次封装,我们可以极大提升三维地图开发效率,并实现高度可复用、可维护的业务组件。
本方案支持点、线、面、圆、围栏、3D Tiles、热力图、测量、截图、弹窗等常用功能,适合大部分前端三维可视化项目。
可以直接将CesiumMap.js
拿到你的项目中直接使用,最好使用和uncleTom一样的版本
uncleTom用的版本是 cesium: 1.130.1-splats.0
参考链接:
demo源码地址: uncleTom/Cesium-utils
如有任何问题,欢迎评论区留言交流!希望这篇文章对你能用帮助,如果喜欢给uncleTom点个关注哟,我以后也会多多分享更多前端内容