外观
3D · 实体与业务标记
3D 文档 · 声明式实体、批量标记与实体管理
三套 API 面向不同场景:少量独立对象使用 CesiumEntity,业务点位列表使用 CesiumDropMarker,大量动态对象的命令式增删改查使用 useEntityManager。
CesiumEntity:声明式点、线、面
先看清楚:点、线、面分别能传什么
推荐把一个实体的全部内容放进 config 对象。type 决定这是点、线还是面,TypeScript 会据此提示对应参数。
配置内容分为两类:
- 图形参数:
point、billboard、polyline、polygon,决定地图上画什么。 - 通用附加参数:
label、name、description、properties,用于补充文字或业务数据。
颜色可以直接填写常见的 CSS 格式,包括 #fff、#ffffff、rgb(255, 255, 255) 和 rgba(255, 255, 255, 0.8);已有 Cesium 项目也可以继续传 Color.RED、Color.WHITE 等原生对象。
常用配置优先使用组件库提供的直观格式:
| 业务含义 | 推荐写法 | 不再推荐的 Cesium 底层写法 |
|---|---|---|
| 始终可见 | alwaysVisible: true | disableDepthTestDistance: Number.POSITIVE_INFINITY |
| 屏幕偏移 | pixelOffset: [0, -28] | new Cartesian2(0, -28) |
| 贴地显示 | heightReference: "clamp-to-ground" | HeightReference.CLAMP_TO_GROUND |
| 水平居中 | horizontalOrigin: "center" | HorizontalOrigin.CENTER |
| 底部对齐 | verticalOrigin: "bottom" | VerticalOrigin.BOTTOM |
| 线坐标 | positions: [[经度, 纬度], ...] | Cartesian3.fromDegreesArray(...) |
| 面边界 | hierarchy: [[经度, 纬度], ...] | Cartesian3.fromDegreesArray(...) |
Cesium 原生对象仍然兼容,只有使用高级原生能力时才需要传入。
点标签使用点坐标,面标签默认放在地表中心。组件会根据面的三维边界计算中心并投影回地球表面,因此业务页面不需要再次计算位置。线本身可以直接渲染;只有在线上添加文字时,才需要通过 label.position 指定文字位置。
| 使用场景 | 必传参数 | 可以直接搭配 | 需要注意 |
|---|---|---|---|
| 点 | type: "point"、position、point | label、billboard | point、label 和 billboard 共用同一个 position |
| 图片标记 | type: "point"、position、billboard | label、point | 图片和文字都显示在 position 附近 |
| 线 | type: "polyline"、polyline | label、name、properties | 线直接渲染;添加标签时填写 label.position |
| 面 | type: "polygon"、polygon | label、name、properties | 标签默认固定在地块表面中心,无需另外计算坐标 |
点实体
点实体使用 position 确定位置,再通过 point、billboard 或 label 决定显示内容。三者可以单独使用,也可以组合使用。
vue
<CesiumEntity :config="pointConfig" />ts
import type { CesiumEntityConfig } from "scene-mapping-gis/3d";
const pointConfig: CesiumEntityConfig = {
type: "point",
name: "上海外滩",
position: [121.4737, 31.2304, 300],
point: {
pixelSize: 16,
color: "#ef4444",
outlineColor: "#fff",
outlineWidth: 3,
},
label: {
text: "上海 · 外滩",
fillColor: "#fff",
outlineColor: "rgba(0, 0, 0, 0.9)",
outlineWidth: 3,
style: "fill-and-outline",
pixelOffset: [0, -28],
alwaysVisible: true,
},
};label 使用与 point 相同的 position,pixelOffset 只负责让文字在屏幕上稍微偏离圆点,避免重叠。
线实体
线实体只需要 polyline,坐标全部写在 polyline.positions 中,不需要顶层 position。
vue
<CesiumEntity :config="polylineConfig" />ts
import type { CesiumEntityConfig } from "scene-mapping-gis/3d";
const polylineConfig: CesiumEntityConfig = {
type: "polyline",
name: "巡检路线",
polyline: {
positions: [
[121.45, 31.22],
[121.48, 31.24],
[121.50, 31.23],
],
width: 6,
material: "rgb(6, 182, 212)",
clampToGround: true,
},
};线可以直接按照 positions 渲染。如果需要在线上显示文字,再指定文字坐标:
ts
const polylineConfig: CesiumEntityConfig = {
type: "polyline",
polyline: polylineOptions,
label: {
position: [121.48, 31.24, 0],
text: "巡检路线",
placement: "top",
},
};label.position 决定文字放在线路的哪个位置,placement: "top" 表示文字相对该位置向上偏移。
面实体
面实体只需要 polygon,边界坐标写在 polygon.hierarchy 中,不需要顶层 position。
vue
<CesiumEntity :config="polygonConfig" />ts
import type { CesiumEntityConfig } from "scene-mapping-gis/3d";
const polygonConfig: CesiumEntityConfig = {
type: "polygon",
name: "业务地块",
polygon: {
hierarchy: [
[121.45, 31.22],
[121.50, 31.22],
[121.50, 31.18],
[121.45, 31.18],
],
material: "rgba(249, 115, 22, 0.5)",
outline: true,
outlineColor: "#f97316",
},
};面上的文字默认显示在多边形的地表中心,不需要再填写坐标:
ts
const polygonConfig: CesiumEntityConfig = {
type: "polygon",
polygon: polygonOptions,
label: {
text: "业务地块",
},
};需要让文字在屏幕上稍微偏到面上方时,加上 placement: "top" 即可;只有明确指定业务经纬度时才需要填写 label.position。地图缩放和旋转不会改变标签对应的地块位置。
config 公共字段
| 属性 | 实际传值 | 默认值 | 用途 |
|---|---|---|---|
type | "point" | "polyline" | "polygon" | 必填 | 决定当前配置是点、线还是面 |
position | [经度, 纬度, 高度?] 或 { longitude, latitude, height? } | 点必填 | 点、图片和点标签共用的位置 |
id | string | Cesium 自动生成 | 实体唯一 ID |
show | boolean | true | 是否显示实体 |
name | string | — | 实体名称 |
description | string | — | 点击实体时使用的描述内容 |
point | 下方 point 配置对象 | — | 在点配置的 position 位置显示圆点;图片标记或纯文字可以不传 |
label | 下方 label 配置对象 | — | 点使用点坐标,线需指定文字坐标,面自动居中 |
billboard | { image, width?, height?, ... } | — | 在 position 位置显示图片图标 |
polyline | 下方 polyline 配置对象 | — | 根据自身 positions 绘制线,不使用顶层 position |
polygon | 下方 polygon 配置对象 | — | 根据自身 hierarchy 绘制面,不使用顶层 position |
properties | { [业务字段]: 任意值 } | — | 保存业务数据,拾取实体时读取 |
旧的平铺 Props 写法仍然兼容,但新项目推荐统一使用 config:
vue
<!-- 兼容旧写法,不推荐新项目继续使用 -->
<CesiumEntity
:position="[121.4737, 31.2304, 0]"
:point="{ pixelSize: 16, color: Color.RED }"
:label="{ text: '旧写法' }"
/>point 参数
point 只能绘制在顶层 position 指定的位置。
| 字段 | 类型或示例 | 说明 |
|---|---|---|
pixelSize | 16 | 点直径,单位 px |
color | "#ef4444"、"rgb(239, 68, 68)" 或 Color.RED | 点填充色 |
outlineColor | "#fff"、"rgba(255, 255, 255, 0.8)" 或 Color.WHITE | 描边颜色 |
outlineWidth | 3 | 描边宽度 |
heightReference | "none" | "clamp-to-ground" | "relative-to-ground" | 普通高度、贴地或相对地面高度 |
alwaysVisible | true | 是否始终显示,不被地形或模型遮挡 |
billboard 参数
billboard 用图片代替圆点,并与点、标签共用顶层 position。
| 字段 | 类型或示例 | 说明 |
|---|---|---|
image | 图片 URL、Data URL 或 Canvas | 必填的图标内容 |
width / height | 32 / 47 | 图标显示尺寸,单位 px |
scale | 1 | 图标缩放比例 |
color | "#fff"、"rgba(...)" 或 Color.WHITE | 与图片颜色混合,白色表示保持原图 |
pixelOffset | [0, -20] | 相对坐标点的屏幕像素偏移 |
horizontalOrigin | "left" | "center" | "right" | 水平对齐方式 |
verticalOrigin | "top" | "center" | "bottom" | "baseline" | 垂直对齐方式 |
heightReference | "none" | "clamp-to-ground" | "relative-to-ground" | 普通高度、贴地或相对地面高度 |
alwaysVisible | true | 是否始终显示,不被地形或模型遮挡 |
label 参数
label 可以和点、线、面放在同一个 Entity 中。它已有常用默认样式:白色文字、黑色描边、16px 字号并始终显示在地图之上,通常只写 text 即可。
style 不需要使用难懂的 Cesium 枚举:fill 表示只显示文字填充,outline 表示只显示轮廓,fill-and-outline 表示同时显示文字和描边。原来的 LabelStyle.FILL_AND_OUTLINE 仍然兼容。
| 字段 | 类型或示例 | 说明 |
|---|---|---|
text | '地块 01' | 显示文字 |
font | '16px sans-serif' | 字体 |
style | "fill" | "outline" | "fill-and-outline" | 文字显示方式,推荐使用直观字符串 |
fillColor | "#fff"、"rgb(...)"、"rgba(...)" 或 Color.WHITE | 文字颜色 |
outlineColor | "#000"、"rgb(...)"、"rgba(...)" 或 Color.BLACK | 文字描边色 |
outlineWidth | 3 | 文字描边宽度 |
placement | "center" | "top" | "bottom" | "left" | "right" | 标签相对图形的方向,默认 center |
position | [经度, 纬度, 高度?] | 可选的准确坐标,覆盖线或面的自动位置 |
pixelOffset | [0, -28] | 精确的屏幕像素偏移,会覆盖 placement 的默认偏移 |
alwaysVisible | true | 是否始终显示文字,不被地形或模型遮挡;替代难懂的 disableDepthTestDistance |
heightReference | "none" | "clamp-to-ground" | "relative-to-ground" | 普通高度、贴地或相对地面高度 |
horizontalOrigin | "left" | "center" | "right" | 水平对齐方向 |
verticalOrigin | "top" | "center" | "bottom" | "baseline" | 垂直对齐方向 |
polyline 传什么
ts
{
positions: [
[经度1, 纬度1, 高度?],
[经度2, 纬度2, 高度?],
],
width: 6,
material: "#06b6d4",
clampToGround: true,
}positions 必填且至少包含两个坐标点。width 是像素宽度,material 是颜色,clampToGround 控制是否贴地。
polygon 传什么
ts
{
hierarchy: [
[经度1, 纬度1, 高度?],
[经度2, 纬度2, 高度?],
[经度3, 纬度3, 高度?],
],
material: "rgba(34, 197, 94, 0.45)",
outline: true,
outlineColor: "rgb(34, 197, 94)",
height: 0,
extrudedHeight: 300,
}hierarchy 必填且至少包含三个边界点。Cesium 会自动连接最后一个点和第一个点。height 是面离地高度;只有需要立体拉伸时才传 extrudedHeight。
CesiumEntity 事件与方法
| 名称 | 返回内容 | 说明 |
|---|---|---|
load | Entity | Entity 创建并加入 Viewer 后触发 |
getEntity() | Entity | null | 组件 ref 方法,获取当前原生 Entity |
坐标、点线面样式和显隐变化都会同步更新,组件卸载时只移除自身创建的 Entity。
CesiumDropMarker:业务点位列表
vue
<CesiumDropMarker
ref="markerRef"
:points="markerPoints"
:label-style="{ pixelOffset: [0, 48], outlineColor: '#ff551e' }"
@click="onMarkerClick"
@position-update="popupPosition = $event"
/>ts
const markerPoints = [{
id: "site-001", longitude: 116.4074, latitude: 39.9042,
text: "北京站点", status: "online",
}];| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
points | MarkerPoint[] | 必填 | 原始业务点位数组 |
defaultImage | string | 内置图标 | 默认 Marker 图片 |
iconWidth / iconHeight | number | 32 / 47 | 图标尺寸 |
showLabel | boolean | true | 是否显示文字 |
hoverScale | number | 1.18 | 鼠标悬停时的图标缩放比例,设为 1 可关闭 |
labelStyle | MarkerLabelStyle | {} | 全局标签样式 |
MarkerPoint 点位字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
longitude | number | 必填 | 经度,单位为度 |
latitude | number | 必填 | 纬度,单位为度 |
height | number | 0 | 离地高度,单位为米 |
image | string | defaultImage | 当前点位自己的图标,会覆盖组件默认图标 |
text | string | 空字符串 | Marker 旁显示的文字 |
labelStyle | MarkerLabelStyle | {} | 当前点位自己的标签样式,优先于组件级样式 |
id | string | number | — | 业务 ID,点击时原样返回 |
| 其他业务字段 | 任意 | — | 状态、名称等字段都会原样保留并在点击时返回 |
MarkerLabelStyle 标签样式
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
fillColor | string | #FFFFFF | 文字颜色,支持 Hex、RGB、RGBA |
font | string | 14px Microsoft YaHei UI | CSS 字体写法 |
outlineColor | string | #000000 | 文字描边颜色 |
outlineWidth | number | 2 | 文字描边宽度 |
showBackground | boolean | false | 是否显示文字背景 |
backgroundColor | string | Cesium 默认值 | 背景颜色 |
pixelOffset | [number, number] | [0, 40] | 文字相对图标的像素偏移 |
scale | number | 1 | 文字缩放比例 |
Marker 事件与方法
| 名称 | 返回内容 | 说明 |
|---|---|---|
click | (point, screenPosition) | 点击 Marker,返回完整原始点位和 { x, y } 屏幕坐标 |
position-update | screenPosition | 相机移动时更新当前选中 Marker 的屏幕位置 |
clearSelection() | void | 组件 ref 方法,清除当前选中 Marker |
弹窗属于业务 UI,应由使用方根据屏幕坐标渲染。
useEntityManager:命令式批量管理
ts
const manager = useEntityManager({ viewer: viewerRef });
manager.addEntity({
id: "point-1",
position: [116.4, 39.9, 0],
point: { pixelSize: 10 },
});
manager.updateEntity("point-1", { position: [121.5, 31.2, 0] });
manager.removeEntityById("point-1");
manager.clearAll();| 方法 | 返回 | 说明 |
|---|---|---|
addEntity(options) | Entity | null | 添加实体;ID 冲突时替换旧实体 |
updateEntity(id, partial) | boolean | 更新位置或展示属性 |
removeEntityById(id) | boolean | 删除本管理器创建的实体 |
clearAll() | void | 清空本管理器实体,不影响其他组件 |
getEntityById(id) | Entity | undefined | 按 ID 查询 |
getAllEntities() | Entity[] | 获取当前实体快照 |
类型声明
管理器统一使用 position 表示点位。更新时会把新配置与原配置合并后重建当前实体,不再为点、线、面分别编写更新流程。