1. 为什么你的Cesium标签总像“牛皮癣”?从原生Label到自定义美化的蜕变
刚接触Cesium做三维可视化那会儿,我总觉得地图上那些标签(Label)差点意思。默认的白色文字,配上一条细细的引线,密密麻麻挤在一起,别说美观了,连看清楚都费劲,活像贴在精美地图上的“牛皮癣小广告”。尤其是当我们需要展示设备状态、传感器读数等复杂信息时,原生Label那点可怜的样式定制能力,根本不够用。
后来项目逼得紧,甲方爸爸指着屏幕说:“这个标签,我要它像手机APP里的信息卡片一样好看,能变色、能带背景图、还能分组展示不同字段。” 得,原生Label肯定是没戏了。于是,我走上了Cesium Label自定义美化的“不归路”。这条路我踩过不少坑,比如用Entity的label属性折腾半天,发现字体阴影和边框效果极其有限;也试过用Billboard贴图片当背景,但文字排版和动态更新又成了新问题。
最终,我发现了一条更灵活、更强大的路径:完全跳出Cesium的Label API,用HTML + CSS来“画”出我们想要的任何标签样式。这听起来有点“离经叛道”,但实测下来,效果和可控性简直是一个天上一个地下。你可以做出圆角渐变背景、嵌入图标、实现动态数据刷新,甚至做出带动画效果的悬浮卡片。今天,我就把我从基础实现到高级优化的实战经验,掰开揉碎了分享给你,保证你跟着做,就能让地图上的标签从此告别简陋,颜值飙升。
2. 基础入门:手把手创建一个会“跟地图走”的HTML标签
别被“自定义”吓到,其实核心原理非常简单。Cesium提供了一个关键函数:Cesium.SceneTransforms.wgs84ToWindowCoordinates。这个函数能干一件神奇的事:把地球上的一个经纬度坐标(WGS84),实时转换成你电脑屏幕上的像素坐标(x, y)。
这就为我们打开了新世界的大门。我们不再需要去修改Cesium内部那些难以驾驭的标签对象,而是可以:
- 创建一个普通的HTML
div元素。 - 用CSS把这个
div打扮成任何你想要的样子(信息卡片、警示牌、状态图标等等)。 - 在Cesium的每一帧渲染循环里,调用上述函数,计算出我们关心的那个地理坐标对应的屏幕位置。
- 把这个位置(
left,top)设置给我们的HTMLdiv。
这样,这个HTML标签就会牢牢地“粘”在那个地理位置上,随着你拖动、缩放地图而同步移动。下面,我们抛开任何框架,用最纯粹的代码来实现它。
2.1 核心代码拆解:一个可复用的美化助手
我习惯把核心逻辑封装成一个叫labelBeautifulHelper的函数,这样在任何项目里都能即插即用。我们来逐段分析:
// labelBeautifulHelper.js
function labelBeautifulHelper(info) {
// 1. 获取关键参数
let viewer = info.viewer; // Cesium的viewer实例
let geometry = info.position; // 标签要跟随的地理位置(Cartesian3类型)
let contentID = "contentBeautiful" + info.properties.id; // 给标签一个唯一ID,方便控制
// 2. 创建并插入HTML容器
let ctn = $(`<div class='LabelPlotBeautiful-container' id='${contentID}'>`);
$(viewer.container).append(ctn); // 将容器挂载到Cesium的DOM容器内
ctn.append(_createHtml(info.properties)); // 往容器里添加具体的标签内容
// 3. 核心:在每一帧渲染时更新标签位置
try {
_render(geometry); // 初始渲染一次
viewer.clock.onTick.addEventListener(function(clock) {
_render(geometry); // 每帧都调用,保证位置实时更新
});
} catch (e) {
console.error("位置渲染错误:", e);
}
// 4. 位置渲染函数
function _render(geometry) {
let position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, geometry);
if (position) {


564

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



