🌏【cesium系列】02.绘制点线面

1,573 阅读5分钟

🌏# 前言

上一篇文章中,介绍了怎么在vue3中集成cesium,并且成功创建了一个场景。这篇主要介绍cesium中绘制点线面相关操作。

用的版本是:

  • cesium: ^1.128.0

示例代码仓库:github.com/leixq1024/v…

前置知识

viewer 是什么?
  • 本质:Cesium的核心控制器对象(3D场景的「总管家」)
  • 核心作用
    • 初始化三维地球场景(地形、影像、天空等)
    • 管理所有图层和实体(entitiesdataSources等)
    • 控制相机视角(缩放、旋转、定位)
    • 提供交互事件系统(点击、移动等)

其实就是创建出来的地图对象,下面的这个map就是了

export const createMap = (id: string) => {
  const options: { [x: string]: boolean } = {
    geocoder: false, // 地理编码控件不显示
    homeButton: false, // 默认相机位置控件不显示
    sceneModePicker: false, // 场景模式控件不显示
    baseLayerPicker: false, // 基础图层控件不显示
    navigationHelpButton: false, // 导航帮助控件不显示
    animation: false, // 动画控件不显示
    timeline: false, // 时间线控件不显示
    fullscreenButton: false, // 全屏控件不显示
    vrButton: false, // vr控件不显示
    infoBox: false, // 信息框控件不显示,点击要素后不弹出信息栏
    selectionIndicator: false // 选择跟踪控件不显示,点击要素后不弹出锁定框
  }

  map = new Viewer(id, options)
}
entities 是什么?
  • 本质:高级实体集合管理器(场景中的「物品收纳盒」)
  • 核心特征
    • 提供声明式API(通过JSON配置创建对象)
    • 支持动态更新属性(颜色、位置等)
    • 自动处理渲染优化(适合动态交互场景)
    • 包含常见图元类型(点、线、面、模型等)

后面创建的点线面等图形都需要添加到viewer.entities这个对象里面

entities相对的还有一个Primitive,这里不做过多介绍

下面就开始做代码示例的介绍

viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(118.107358, 24.47745, 10),
  point: {
    pixelSize: 10,                       // 点大小(像素)
    color: Cesium.Color.RED,             // 填充颜色
    outlineColor: Cesium.Color.WHITE,    // 描边颜色
    outlineWidth: 2,                     // 描边宽度
    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND // 贴地模式
  }
});

相关参数介绍

参数类型说明默认值
pixelSizenumber点的直径(像素单位)1
colorColor填充颜色(支持CSS颜色字符串)Color.WHITE
outlineColorColor描边颜色Color.BLACK
heightReferenceHeightReference高度参考模式(贴地/绝对高度)HeightReference.NONE

position:点位的坐标,需要用 Cesium.Cartesian3.fromDegrees进行转换,传入经纬度和高程,其中 高程可以不用,不过建议要一个

point:表示创建的是

效果如下

image-20250506211621735

文字点

文字点和上面的创建方式不一样之处在于多了一个label属性,具体的属性功能可看描述

Viewer.entities.add({
    // 实体位置(WGS84坐标系)
    position: Cesium.Cartesian3.fromDegrees(
      118.107358, // 经度(东经)
      24.47745, // 纬度(北纬)
      50 // 高程(米,相对于椭球体高度)
    ),
    // 点样式配置
    point: {
      pixelSize: 12, // 点直径(像素单位,建议8-20)
      color: Cesium.Color.fromCssColorString('#ff3d3d'), // 点填充色(支持CSS颜色)
      outlineColor: Cesium.Color.WHITE, // 点描边颜色
      outlineWidth: 2, // 点描边宽度(像素)
      heightReference: Cesium.HeightReference.CLAMP_TO_GROUND // 高度参考模式(贴地)
    },
    // 文字标签配置
    label: {
      text: '气象观测站\n(在线)', // 显示文本(支持换行符)
      font: 'bold 14px "Microsoft YaHei", sans-serif', // 字体设置(必须指定中文字体)
      fillColor: Cesium.Color.BLACK, // 文字颜色
      backgroundColor: Cesium.Color.AQUA.withAlpha(0.7), // 背景色(带透明度)
      showBackground: true, // 显示文字背景
      style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 文字渲染样式(填充+描边)
      outlineColor: Cesium.Color.WHITE, // 文字描边颜色
      outlineWidth: 2, // 文字描边宽度(像素)
      horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // 水平定位基准点(左侧对齐)
      verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直定位基准点(中心对齐)
      pixelOffset: new Cesium.Cartesian2(25, 0), // 屏幕像素偏移(X右/Y下为正方向)
      eyeOffset: new Cesium.Cartesian3(0, 0, -100) // 视角偏移(防止被地形遮挡)
    }
  })

效果如下

image-20250506214159228

图片点

图片点这边和前面的文字点和普通点不一样,用的是billboard,在官方中叫做广告牌。不过我还是习惯叫做图片点

Viewer.entities.add({
    // 实体位置(使用WGS84经纬度坐标)
    position: Cesium.Cartesian3.fromDegrees(
      118.107358, // 经度 (东经)
      24.47745, // 纬度 (北纬)
      10 // 高度(米,相对于椭球面)
    ),
    // 广告牌配置(用于显示2D图像标记)
    billboard: {
      image: '/img/poi.png', // 图像路径(支持URI、Canvas或资源对象)
      // 推荐使用绝对路径,注意跨域问题
      // 尺寸配置
      width: 50, // 宽度(像素,当sizeInMeters=false时)
      height: 50, // 高度(像素,当sizeInMeters=false时)
      // 高级显示配置
      rotation: Cesium.Math.toRadians(0), // 旋转角度(弧度制,顺时针方向)
      // 建议使用Cesium.Math.toRadians()进行角度转换
      sizeInMeters: false, // true时尺寸单位为米(适合精确测量场景)
      // false时使用像素单位(适合UI标记)
      // 对齐方式配置
      verticalOrigin: Cesium.VerticalOrigin.CENTER, // 垂直对齐(CENTER|TOP|BOTTOM)
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平对齐(CENTER|LEFT|RIGHT)
      // 像素偏移(用于微调显示位置)
      pixelOffset: new Cesium.Cartesian2(10, 0), // X向右为正,Y向上为正
      // 可选性能优化参数
      disableDepthTestDistance: Number.POSITIVE_INFINITY // 始终显示在最前(避免被地形遮挡)
    }
  })

效果如下

图片点效果图

线

线和前面画点的操作一样,只不过用的是polyline,基本属性如下

Viewer.entities.add({
    polyline: {
      // 线的坐标
      positions: Cesium.Cartesian3.fromDegreesArray([120.9677706, 30.7985748, 110.2, 34.55]),
      // 线的颜色
      material: Cesium.Color.WHITE,
      // 线的宽度
      width: 5,
      // 恒定高度
      height: 5000
    }
  })

效果如下

image-20250506223724834

画线的坐标可以给多个

Viewer.entities.add({
    polyline: {
      // 线的坐标
      positions: Cesium.Cartesian3.fromDegreesArray([120.9677706, 30.7985748, 110.2, 34.55, 100.2, 34.55,90.2, 34.55, 100.2, 34.55]),
      // 线的颜色
      material: Cesium.Color.WHITE,
      // 线的宽度
      width: 5,
      // 恒定高度
      height: 5000
    }
  })

像这样,我给的就是多个坐标,它就会按照坐标绘制

image-20250506224512973

画面则是通过设置polygon属性来完成的,这里要注意设置height属性,不然边框线,会显示不出来

Viewer.entities.add({
    polygon: {
      height: 1,
      hierarchy: {
        positions: Cesium.Cartesian3.fromDegreesArray([120.9677706, 30.7985748, 110.2, 34.55, 120.2, 50.55])
      },
      // 边框
      outline: true,
      // 边框颜色
      outlineColor: Cesium.Color.WHITE,
      // 边框尺寸
      outlineWidth: 2,
      // 填充的颜色,withAlpha透明度
      material: Cesium.Color.GREEN.withAlpha(0.5),
      // 是否被提供的材质填充
      fill: true
    }
  })

效果如下

image-20250506224559526

镂空面

如果面的轮廓,不要里面的填充,则可以这样

Viewer.entities.add({
    polygon: {
      height: 1,
      hierarchy: {
        positions: Cesium.Cartesian3.fromDegreesArray([120.9677706, 30.7985748, 110.2, 34.55, 120.2, 50.55])
      },
      // 边框
      outline: true,
      // 边框颜色
      outlineColor: Cesium.Color.WHITE,
      // 边框尺寸
      outlineWidth: 2,
      // 填充的颜色,withAlpha透明度
      material: Cesium.Color.GREEN.withAlpha(0),
      // 是否被提供的材质填充
      fill: true
    }
  })

这里我将填充的颜色的透明度设置为0,这样就实现镂空的效果了

image-20250506224721459

结尾

到这里基本的点线面怎么添加到地图上面去的代码例子,已经展示完毕。

下一篇将介绍怎么用鼠标去绘制点线面