Skip to content

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: truedisableDepthTestDistance: 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、pointlabel、billboardpoint、label 和 billboard 共用同一个 position
图片标记type: "point"、position、billboardlabel、point图片和文字都显示在 position 附近
线type: "polyline"、polylinelabel、name、properties线直接渲染;添加标签时填写 label.position
面type: "polygon"、polygonlabel、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? }点必填点、图片和点标签共用的位置
idstringCesium 自动生成实体唯一 ID
showbooleantrue是否显示实体
namestring—实体名称
descriptionstring—点击实体时使用的描述内容
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 指定的位置。

字段类型或示例说明
pixelSize16点直径,单位 px
color"#ef4444"、"rgb(239, 68, 68)" 或 Color.RED点填充色
outlineColor"#fff"、"rgba(255, 255, 255, 0.8)" 或 Color.WHITE描边颜色
outlineWidth3描边宽度
heightReference"none" | "clamp-to-ground" | "relative-to-ground"普通高度、贴地或相对地面高度
alwaysVisibletrue是否始终显示,不被地形或模型遮挡

billboard 参数 ​

billboard 用图片代替圆点,并与点、标签共用顶层 position。

字段类型或示例说明
image图片 URL、Data URL 或 Canvas必填的图标内容
width / height32 / 47图标显示尺寸,单位 px
scale1图标缩放比例
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"普通高度、贴地或相对地面高度
alwaysVisibletrue是否始终显示,不被地形或模型遮挡

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文字描边色
outlineWidth3文字描边宽度
placement"center" | "top" | "bottom" | "left" | "right"标签相对图形的方向,默认 center
position[经度, 纬度, 高度?]可选的准确坐标,覆盖线或面的自动位置
pixelOffset[0, -28]精确的屏幕像素偏移,会覆盖 placement 的默认偏移
alwaysVisibletrue是否始终显示文字,不被地形或模型遮挡;替代难懂的 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 事件与方法 ​

名称返回内容说明
loadEntityEntity 创建并加入 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",
}];
名称类型默认值说明
pointsMarkerPoint[]必填原始业务点位数组
defaultImagestring内置图标默认 Marker 图片
iconWidth / iconHeightnumber32 / 47图标尺寸
showLabelbooleantrue是否显示文字
hoverScalenumber1.18鼠标悬停时的图标缩放比例,设为 1 可关闭
labelStyleMarkerLabelStyle{}全局标签样式

MarkerPoint 点位字段 ​

字段类型默认值说明
longitudenumber必填经度,单位为度
latitudenumber必填纬度,单位为度
heightnumber0离地高度,单位为米
imagestringdefaultImage当前点位自己的图标,会覆盖组件默认图标
textstring空字符串Marker 旁显示的文字
labelStyleMarkerLabelStyle{}当前点位自己的标签样式,优先于组件级样式
idstring | number—业务 ID,点击时原样返回
其他业务字段任意—状态、名称等字段都会原样保留并在点击时返回

MarkerLabelStyle 标签样式 ​

字段类型默认值说明
fillColorstring#FFFFFF文字颜色,支持 Hex、RGB、RGBA
fontstring14px Microsoft YaHei UICSS 字体写法
outlineColorstring#000000文字描边颜色
outlineWidthnumber2文字描边宽度
showBackgroundbooleanfalse是否显示文字背景
backgroundColorstringCesium 默认值背景颜色
pixelOffset[number, number][0, 40]文字相对图标的像素偏移
scalenumber1文字缩放比例

Marker 事件与方法 ​

名称返回内容说明
click(point, screenPosition)点击 Marker,返回完整原始点位和 { x, y } 屏幕坐标
position-updatescreenPosition相机移动时更新当前选中 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 表示点位。更新时会把新配置与原配置合并后重建当前实体,不再为点、线、面分别编写更新流程。