1. 为什么你的Entity总是“飘”着或“陷”下去?
如果你刚开始用Cesium做三维可视化,很可能遇到过这样的尴尬:你精心放置的图标、绘制的道路或者标注的区域,在地球上要么像气球一样飘在半空,要么直接“沉”到地下看不见了。这感觉就像在沙盘上放模型,结果模型要么悬空,要么被沙子埋了,完全达不到“贴合”地形的效果。
我刚开始做智慧城市项目时就踩过这个坑。当时要在地图上标注一批山区里的基站位置,结果代码一跑,所有图标都整齐地飘在同一个高度,跟下面的山脉起伏完全对不上,看起来非常假。后来才知道,在Cesium的世界里,地形是有起伏的,而我们创建的Entity(实体,比如点、线、面、模型这些可视对象)默认是放在一个绝对高度上的。如果你不告诉Cesium“请把这个东西贴在地面上”,它就会傻乎乎地把它放在你指定的那个固定高度,不管下面是高山还是深谷。
这个“告诉”的过程,就是贴地。它的核心目标,是让Entity的视觉位置能动态地匹配其正下方地形表面的真实高度,从而实现“稳稳站在地面上”的效果。无论是模拟一条蜿蜒的盘山公路,还是在地形复杂的区域规划一块用地,贴地都是让你的三维场景看起来真实、专业的基础。
实现贴地主要靠两个“开关”:heightReference 和 clampToGround。听起来有点技术?别怕,我们可以把它想象成给实体选择“站立模式”。heightReference 像是给点状、图标状的实体(如 billboard、label、model)选择是“绝对海拔模式”还是“贴地模式”。而 clampToGround 则是专门给线(polyline)和面(polygon、rectangle 等)准备的“强力胶”,能直接把整个几何形状“粘”在地形上。
接下来,我们就从最基础的原理开始,一步步拆解这两个关键参数,并看看如何把它们用在各种实体上。我会用大量我实际项目中用过的代码示例,带你避开我当年踩过的那些坑。
2. 核心原理:heightReference 与 clampToGround 深度剖析
要玩转贴地,你得先理解Cesium是怎么管理高度的。在三维地球中,一个位置由经度、纬度和高度决定。高度有两种参照系:一种是相对于椭球体表面(比如WGS84参考椭球),另一种是相对于地形表面。贴地,本质上就是把实体的高度参照系,从“固定值”切换到“跟随地形表面”。
2.1 heightReference:点状实体的“高度指南针”
heightReference 是 Entity 中许多图形对象(如 point、billboard、label、model)的一个属性。它决定了这个图形的高度值是基于什么来计算的。它有几个枚举值:
- Cesium.HeightReference.NONE:这是默认值。实体的高度就是你设置的
position里的那个Z值(高度值),它相对于椭球体表面。当地形有起伏时,实体就会保持这个绝对高度,从而出现“飘”或“陷”的现象。 - Cesium.HeightReference.CLAMP_TO_GROUND:贴地模式。这是实现贴地最常用的设置。它会忽略你设置的Z值(通常设为0),强制让实体“坐”在它所在经纬度对应的地形表面上。无论地形怎么起伏,它都紧贴地面。
- Cesium.HeightReference.RELATIVE_TO_GROUND:相对地面模式。这个模式很有趣,它允许你设置一个相对于地形表面的偏移量。比如,你设置高度为10米,实体就会出现在地形表面之上10米的位置。这非常适合做路灯、悬浮的指示牌等需要离地一定距离的物体。
这里有个非常重要的细节:要让 CLAMP_TO_GROUND 生效,必须开启地形深度测试。这行代码我建议你在初始化Viewer后就立刻加上:
viewer.scene.globe.depthTestAgainstTerrain = true;
如果不开启,即使设置了贴地,实体也可能被地形错误地遮挡。我把它理解为“告诉渲染引擎,请精确计算地形和实体谁在前谁在后”。
2.2 clampToGround:线和面的“地形吸附器”
对于 Polyline(线)和 Polygon、Rectangle、Ellipse 等面状实体,它们没有 heightReference 属性。要让它们贴地,你需要使用 clampToGround 属性。当 clampToGround 设置为 true 时,Cesium会计算这条线或这个面的每一个顶点所对应的地形高度,然后用这些动态的高度值来绘制图形,从而实现整个形状完美贴合起伏的地形。
这里有一个性能上的小秘密:clampToGround 的计算比简单的 heightReference 要复杂,因为它需要采样整条线或整个面上的多个点。当地形复杂或图形范围很大时,可能会对性能有些许影响。不过对于现代浏览器和大多数应用场景来说,这点开销完全值得,因为它带来的视觉效果提升是巨大的。
2.3 原理小结与选择策略
简单总结一下:
- 对付点、图标、文字、模型:用
heightReference。想贴地就设成CLAMP_TO_GROUND,想离地漂浮就设成RELATIVE_TO_GROUND并给个高度值。 - 对付线和面:用
clampToGround: true。
那么,Polygon 用 classificationType: Cesium.ClassificationType.TERRAIN


8132

被折叠的 条评论
为什么被折叠?



