大家好,我是日拱一卒的
攻城师不浪
,致力于前沿科技探索,摸索小而美工作室,这是2025年输出的第57/100篇原创文章。
效果预览
群里经常会有小伙伴抱怨道:我们领导又提了个奇葩的需求,他不想看到整个地球的地形影像,因为其他地区的跟业务无关,没有必要展示。他只想看到只展示某个指定的区域的地形影像
,这样会更清晰简洁明了。
其实这个功能就需要对地球进行区域裁剪,那么,今天我们就来一起实现下,其实还蛮简单的。


源码放在了文章末尾,需要的自行领取!
区域地形裁剪的优势
个人认为此功能具备以下几个优势吧:
-
聚焦分析特定区域,排除无关区域干扰
-
有利于创建地形剖面,能够更清晰的展示地下结构或地质构造

- 形成特殊的视觉效果,提升展示的专业性和美观性
应用场景
该功能可以利用在很多场景,例如
-
地质分析与勘探;
-
灾害模拟分析:如洪水、滑坡,聚焦于受影响区域,可更精准的分析辅助决策;
-
矿山工程施工可视化等等
开发原理
首先我们先捋一下,做该功能的原理是啥。
-
首先,你得先加载地形吧。
-
其次,你得知道你要裁剪的区域吧,你得去下载
区域坐标json
吧,去哪下呢?这个我们之前已经提过跟多次啦!datav.aliyun.com/portal/scho... -
然后你得知道用Cesium的哪个API去裁吧,
ClippingPolygon
,是它,就是它。
上手撸
关闭不必要的元素影响
javascript
// 添加地形
const addCesiumTerrain = async () => {
// 加载默认地形
const terrain = await Cesium.CesiumTerrainProvider.fromIonAssetId(1);
__viewer.terrainProvider = terrain;
__viewer.scene.globe.depthTestAgainstTerrain = true;
// 关闭一些不必要的视觉效果,优化性能
__viewer.scene.sun.show = false; // 太阳
__viewer.scene.moon.show = false; // 月亮
__viewer.scene.skyBox.show = false; // 天空盒
__viewer.scene.fog.enabled = false; // 雾
__viewer.scene.skyAtmosphere.show = false; // 大气
};
裁剪
javascript
const start = () => {
// 加载青岛区域的GeoJSON数据
axios.get('/json/qingdao.json').then(res => {
const coors = res.data.features[0].geometry.coordinates[0].flat().flat()
console.log(coors)
const areas = new Cesium.ClippingPolygon({
positions: Cesium.Cartesian3.fromDegreesArray(coors),
})
__viewer.scene.globe.clippingPolygons = new Cesium.ClippingPolygonCollection({
polygons: [areas],
inverse: true
})
// 飞行到青岛区域
__viewer.camera.flyTo({
destination: new Cesium.Cartesian3.fromDegrees(120.656037, 36.322163, 30000),
})
})
}
拿到区域json数据然后将经纬度多维数组拍平 !将所有的ClippingPolygon都放入到截面集合ClippingPolygonCollection
中,决定地形裁剪的范围;
这里注意inverse
参数,它负责判断裁剪区域外还是内,当为true,则是裁剪掉区域以外的内容。
性能优化
不过,如果区域点位过多,裁剪完之后运行起来会感觉异常的卡顿,帧率甚至连10都不到,所以需要做性能优化。
这里我采用的方案是多边形简化,缩减区域点位数量 ,利用turf
插件库。
js
// 性能优化,简化点位
const coors = res.data.features[0].geometry.coordinates[0]
const geojson = turf.polygon(coors)
const simplified = turf.simplify(geojson, {
tolerance: 0.01,
highQuality: false, // 是否花费更多时间使用其他算法创建更高质量的简化
})
const areas =
new Cesium.ClippingPolygon({
positions: Cesium.Cartesian3.fromDegreesArray(simplified.geometry.coordinates[0].flat())
})
__viewer.scene.globe.clippingPolygons = new Cesium.ClippingPolygonCollection({
polygons: [areas],
inverse: true
})
简化后的性能就要好很多了,不过裁剪边界就显得没有那么精细了,所以这个简化参数视情况而定。
五、最后
完整源码放在了不浪的开源项目里,觉得有帮助的朋友可以帮忙点一个star
,鼓励不浪开源更多案例。
【开源地址】:github.com/tingyuxuan2...
想系统学习Cesium的小伙伴儿,可以了解下不浪的教程
《Cesium从入门到实战》
,将Cesium的知识点进行串联,让不了解Cesium的小伙伴拥有一个完整的学习路线,并最终完成一个智慧城市
的完整项目,关注公众号:攻城师不浪,即可获取教程介绍,也可+作者:brown_7778(备注来意)。
有需要进可视化&Webgis交流群
可以加我:brown_7778(备注来意)。