1. 为什么选择CesiumGeoJSON绘制行政区划第一次接触地理可视化时我尝试过Leaflet、Mapbox等多个地图库但最终被Cesium的三维能力征服。特别是在展示行政区划这类需要立体感的场景时Cesium能带来完全不同的视觉体验。比如去年做某省经济数据可视化项目用传统二维地图展示各市GDP时领导反馈缺乏空间层次感改用Cesium三维渲染后通过地形高度突出经济差异效果立刻提升三个档次。GeoJSON作为轻量级地理数据格式简直是行政区划可视化的绝配。它的三大优势特别实用数据结构清晰用{type:FeatureCollection}包裹所有要素每个要素包含几何图形和属性兼容性强几乎所有GIS工具都支持导出GeoJSONWeb友好纯文本格式可直接被JavaScript解析// 典型GeoJSON结构示例 { type: FeatureCollection, features: [{ type: Feature, properties: {name: 北京市}, geometry: { type: Polygon, coordinates: [[[116.2,39.9],[116.3,39.8],...]] } }] }2. 快速获取精准的GeoJSON数据新手最容易卡壳的环节往往是数据获取。早期我为了找一个市的边界数据翻遍各种政府网站最后发现阿里云的DataV.GeoAtlas工具才是真香访问DataV地理小工具在区域选择器中勾选需要的省/市/县点击下载GeoJSON按钮实测下载的浙江省数据坐标精度达到小数点后6位完全满足业务需求。如果需要对数据进行裁剪推荐使用QGIS导入原始GeoJSON使用矢量→地理处理工具→裁剪导出为新的GeoJSON文件注意国内地图需使用GCJ-02或BD-09坐标系WGS84坐标会存在偏移。若发现位置偏差可用coordtransform库进行转换3. 完整代码实现省市高亮效果下面这段Vue组件代码是我在多个项目中验证过的稳定方案。核心逻辑是通过PolygonGeometry实现挖洞效果——只保留目标区域其他区域用半透明蒙版覆盖。template div classcesium-container refcesiumContainer/div /template script import Cesium from cesium import zhejiangGeoJSON from ./geojson/zhejiang.json export default { mounted() { this.initViewer() this.highlightProvince(zhejiangGeoJSON) }, methods: { initViewer() { // 初始化三维场景 this.viewer new Cesium.Viewer(this.$refs.cesiumContainer, { animation: false, baseLayerPicker: false, imageryProvider: new Cesium.UrlTemplateImageryProvider({ url: http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}, }) }) // 优化视觉样式 this.viewer.scene.globe.enableLighting true this.viewer.scene.skyBox.show false this.viewer.scene.backgroundColor Cesium.Color.BLACK }, highlightProvince(geoJSON) { // 提取边界坐标 const coordinates geoJSON.features[0].geometry.coordinates[0] const degreesArray coordinates.flat() // 创建带孔洞的多边形洞就是目标省份 const polygon new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArray([70,10, 140,10, 140,60, 70,60]), // 中国大致范围 [new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(degreesArray))] ) }) // 添加到场景 this.viewer.scene.primitives.add( new Cesium.Primitive({ geometryInstances: [new Cesium.GeometryInstance({ geometry: polygon, attributes: { color: Cesium.Color.BLUE.withAlpha(0.3) } })], appearance: new Cesium.PerInstanceColorAppearance() }) ) // 自动飞行到目标区域 this.viewer.camera.flyTo({ destination: Cesium.Rectangle.fromDegrees( 118, 27.5, // 西南角 122, 30.5 // 东北角 ) }) } } } /script style .cesium-container { width: 100%; height: 100vh; } /style4. 性能优化与常见问题排查在加载复杂行政区划时比如深圳的街道数据可能会遇到性能瓶颈。通过这三个技巧可以显著提升体验数据简化使用mapshaper工具简化多边形mapshaper input.json -simplify 10% -o output.json分级加载根据缩放级别加载不同精度数据viewer.scene.camera.changed.addEventListener(() { const zoom viewer.camera.positionCartographic.height if(zoom 100000) { loadLowResGeoJSON() } else { loadHighResGeoJSON() } })WebWorker解析将GeoJSON解析放到后台线程遇到显示异常时可以按这个流程排查检查控制台是否有Cesium警告确认GeoJSON坐标顺序是[[经度,纬度],...]尝试用Cesium.GeoJsonDataSource.load基础方法测试数据有效性检查Cesium版本是否过旧推荐1.905. 高级应用交互与样式定制让行政区划活起来的关键在于交互设计。这个示例实现鼠标悬浮高亮效果// 在highlightProvince方法中添加 const dataSource await Cesium.GeoJsonDataSource.load(./geojson/zhejiang.json) const entity dataSource.entities.values[0] // 原始样式 entity.polygon.material Cesium.Color.BLUE.withAlpha(0.5) entity.polygon.outline true entity.polygon.outlineColor Cesium.Color.WHITE // 悬浮事件 entity.polygon.outlineWidth 1 handler.setInputAction((movement) { const picked viewer.scene.pick(movement.endPosition) if(picked picked.id entity) { entity.polygon.outlineWidth 5 // 加粗边框 } else { entity.polygon.outlineWidth 1 } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)更专业的样式方案是使用CZML这个基于时间轴的描述语言可以定义复杂样式{ id: zhejiang, polygon: { positions: {cartographicDegrees: [120,30, 121,30,...]}, material: { solidColor: { color: {rgba: [0,0,255,128]}, time: 2020-01-01/2023-01-01 } } } }记得在项目初期就考虑移动端适配问题。Cesium的触摸事件需要特殊处理viewer.screenSpaceEventHandler.setInputAction( (touch) {...}, Cesium.ScreenSpaceEventType.TOUCH_END )