cesium 实现地图上添加标签
今天,我们来一起看一下如何在 cesium 增加标签,下面我在地图上增加北京的字样,并且能够快速定位北京的地点,先看下效果。
搭建 cesium 的项目,大家可以看之前的使用 vite 搭建项目的文章,这里就不过多叙述了。
https://mp.weixin.qq.com/s/2odNqZZdKYJViAC-f4Vzdg?token=1735587643&lang=zh_CN (opens in a new tab)
实现步骤
- 确定目标坐标
- 通过
Cartesian3.fromDegrees(116.3912757, 39.906217, 0)
将北京的经纬度转换为 Cesium 中使用的三维笛卡尔坐标。该位置将用于后续实体的锚点(即图标和标签所处的位置)。
- 通过
- 创建实体并设置图标(Billboard)
- 调用
viewer.entities.add(...)
创建一个新的Entity
对象,并指定以下属性:position
: 实体的位置,使用上一步获取的坐标。billboard
: 通过image
(图标路径)、verticalOrigin
(垂直对齐)、scale
(图标大小)、color
(整体颜色)等来定义图标的外观和摆放方式。
- 调用
- 添加文字标签(Label)
- 在同一个实体中设置
label
属性,用于在图标旁边显示文字说明:text
指定标签文字内容(如“北京”)。font
、style
、outlineWidth
等属性则设定文字的字体、样式和描边。verticalOrigin
与pixelOffset
则决定标签与图标之间的对齐和相对偏移,让文字显示在合适的位置。
- 在同一个实体中设置
- 飞行定位到指定位置
- 使用
viewer.camera.flyTo(...)
将摄像机视角平滑移动至刚才标注的位置上空,并通过第三个参数设置高度(这里约 50,000 米)。这样用户即可在进入场景后迅速聚焦到标注点上,形成直观的三维地球定位效果。
- 使用
确定目标坐标
// 添加一个图标点(以北京为例)
const position = Cartesian3.fromDegrees(116.3912757, 39.906217, 0);
通过该行代码,我们就取得了一个可以用于定位(position)的三维坐标。
- Cesium 中的世界坐标并非直接使用经纬度,而是使用笛卡尔坐标 (Cartesian)。
fromDegrees(lng, lat, height)
方法可以将我们熟悉的地理坐标(经纬度 + 高度)转化为 Cesium 可识别的世界坐标系(WGS84)。- 这里示例使用了北京的经纬度:经度 116.3912757,纬度 39.906217。第三个参数
0
表示高度(海拔),即贴近地面。
添加实体(Entity)并设置图标
const icon = viewer.entities.add({
position: position,
billboard: {
image: "/pin.png", // 图标图片路径
verticalOrigin: 0, // 垂直对齐方式
scale: 0.5, // 图标大小
color: Color.RED, // 图标颜色
},
label: {
text: "北京", // 图标标签文字
font: "14pt monospace",
style: 0,
outlineWidth: 2,
verticalOrigin: 1,
pixelOffset: new Cartesian2(0, -9),
},
});
1. viewer.entities.add
和 Entity
- 在 CesiumJS 中,
Entity
是对三维场景中可视化对象的抽象,几乎所有在地图上呈现的对象都可以通过Entity
来实现。 - 使用
viewer.entities.add(...)
可以轻松地将一个实体对象加入到当前 Cesium 场景。
2. position
position
属性指定了实体在三维空间中的位置,这里直接引用了前面创建的position
变量(北京坐标)。
3. billboard
(广告牌/图标)
image
:- 指定图标的资源路径或 URL,这里引用本地
/pin.png
文件。 - 可以使用相对路径(如
./pin.png
)或绝对路径(如https://yourdomain.com/pin.png
),需要根据项目资源存放位置进行调整。
- 指定图标的资源路径或 URL,这里引用本地
verticalOrigin
:- 控制图标在垂直方向上的对齐方式。
0
通常表示 底部对齐(Cesium.VerticalOrigin.BOTTOM
),也就是图标底边与定位点重合。
scale
:- 表示图标缩放比例,
0.5
意味着显示的图标大小是原图的 50%。 - 如果想让图标更大或更小,可以修改这个数值。
- 表示图标缩放比例,
color
:- 使用
Color.RED
将图标整体调成红色。 - Cesium 中的
Color
可以灵活设置透明度、渐变等。如果只想改变透明度,可使用Color.RED.withAlpha(0.5)
等。
- 使用
4. label
(标签)
text
:- 这里设置了
"北京"
,用以标注图标所代表的城市名称。
- 这里设置了
font
:- 字体样式,如
"14pt monospace"
,可以根据需求更改为"16px sans-serif"
等浏览器支持的字体格式。
- 字体样式,如
style
:- 文字样式的枚举值,
0
对应 Cesium 中的LabelStyle.FILL
,表示纯色填充。 - 若想显示描边文字,可使用
Cesium.LabelStyle.OUTLINE
或结合 outlineWidth 使用。
- 文字样式的枚举值,
outlineWidth
:- 文字描边的宽度,设置为 2 可以让文字边缘更清晰。
verticalOrigin
:- 和
billboard
类似,控制文字的垂直对齐方式。 1
通常表示 基线对齐(Cesium.VerticalOrigin.BASELINE
)。
- 和
pixelOffset
:- 以像素为单位设置文字相对实体位置的偏移量。
- 这里设置为
new Cartesian2(0, -9)
,表示在 y 轴上向上移动 9 像素,让文字位于图标上方或附近。
通过这部分配置,我们可以同时展示图标(Billboard)与文字标签(Label),在三维地图上形成对地点的直观标注。
## 摄像机视角定位
viewer.camera.flyTo({
destination: Cartesian3.fromDegrees(116.3912757, 39.906217, 50000),
});
camera
属性viewer.camera
是 Cesium 中对摄像机(视角)的全局管理对象,我们可以通过它来控制视角的位置、角度及运动方式。
flyTo
方法flyTo
会使摄像机平滑地移动到指定的位置,带有动画效果,让用户在浏览器中感受到“飞”向目标地的过程。
destination
- 与
position
类似,这里依然使用Cartesian3.fromDegrees
获取目标笛卡尔坐标。 - 不同之处是第三个参数给出了一个较大的数值
50000
(单位为米),代表我们想要在北京上空约 50 公里处查看场景。 - 值越大,代表视野越远,能看到的范围也会越广。
- 与
当这行代码执行时,场景会把用户的视角逐步移动到北京这个坐标点上方 50 公里的位置,同时保留一定倾斜度,让地图看起来更有空间感。
代码
import { Ion, Viewer, Cartesian3, Color, Cartesian2 } from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
// Your access token can be found at: https://ion.cesium.com/tokens.
// Replace `your_access_token` with your Cesium ion access token.
Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6Ixxx";
// Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
const viewer = new Viewer("cesiumContainer");
// 添加一个图标点(以北京为例)
const position = Cartesian3.fromDegrees(116.3912757, 39.906217, 0);
// 添加一个实体(Entity)作为图标
const icon = viewer.entities.add({
position: position,
billboard: {
image: "/pin.png", // 图标图片路径
verticalOrigin: 0, // 垂直对齐方式
scale: 0.5, // 图标大小
color: Color.RED, // 图标颜色
},
label: {
text: "北京", // 图标标签文字
font: "14pt monospace",
style: 0,
outlineWidth: 2,
verticalOrigin: 1,
pixelOffset: new Cartesian2(0, -9),
},
});
// 将视角定位到图标位置
viewer.camera.flyTo({
destination: Cartesian3.fromDegrees(116.3912757, 39.906217, 50000),
});