我们在之前的 Cesium 中的数据加载 章节当中介绍了如何使用 Cesium
加载影像数据、地形数据、以及矢量数据,但是作为一个完整的三维系统,仅仅包括这些数据还是远远不够的,当然还需要一些比如空间可视化数据、三维数据数据等,今天我们先从空间数据的可视化开始看起
Cesium
在空间数据可视化方面提供了两种类型的 API
,如下
- 一种是面向图形开发人员的低级(原始)
API
,通过Primitive
类来进行实现 - 另一种是用于数据驱动的高级(实体)
API
,通过Entity
类实现
但是相对于 Primitive API
来说,Entity API
实现起来更简单一些,也比较容易上手,Entity API
实际上是对 Primitive API
的二次封装,底层调用的仍然是 Primitive API
,目的就是为我们提供灵活的、易学、易用的高性能可视化界面
本章内容主要介绍的是 Entity API
,关于 Primitive API
这里只是简单提及,后续会详细来进行介绍
Entity 支持的图形类型
通过文档查看 Entity 类的构造函数 我们可知,Entity
支持的图形类型都是以 Graphics
结尾的,一共有十七种类型,我们这里简单汇总一下,下图列出了 Entity
所支持的图形类型以及对应的类
下面我们就来简单看一下每种类型的 Graphic
添加方式
billboard 广告牌
描述位于包含 Entity 的位置的二维图标,详细见 new Cesium.BillboardGraphics(options)
1 | var entity = viewer.entities.add({ |
这里关于两种对齐方式简单说明一下,其中水平对齐方式
- 默认值为
HorizontalOrigin.CENTER
- 其中
CENTER
表示原点在对象的水平中心 LEFT
表示原点在对象的左侧RIGHT
表示原点在对象的右侧
而垂直对齐方式
- 默认值为
VerticalOrigin.CENTER
BASELINE
表示如果对象包含文本,则原点位于文本的基线,否则原点位于对象的底部CENTER
表示原点位于BASELINE
和TOP
之间的垂直中心TOP
表示原点在对象的顶部BOTTOM
表示原点在对象的底部
box 盒子
描述一个盒子,中心位置和方向由包含的 Entity 确定,详细见 new Cesium.BoxGraphics(options)
1 | var entity = viewer.entities.add({ |
这里的 heightReference
有三个取值
Cesium.HeightReference.NONE
表示位置绝对Cesium.HeightReference.CLAMP_TO_GROUND
表示位置固定在地形上Cesium.HeightReference.RELATIVE_TO_GROUND
表示位置高度是指地形上方的高度
corridor 走廊
走廊是由中心线和宽度定义的形状符合地球的曲率,它可以放置在地面上或高空并可以选择挤出成一个体积,详细见 new Cesium.CorridorGraphics(options)
1 | var entity = viewer.entities.add({ |
cylinder 圆柱、圆锥
描述圆柱体,圆锥台或由长度,顶部半径和底部半径定义的圆锥,中心位置和方向由包含的 Entity 确定,详细见 new Cesium.CylinderGraphics(options)
1 | var entity = viewer.entities.add({ |
ellipse 椭圆或拉伸的椭圆
描述由中心点,半长轴和半短轴定义的椭圆,椭圆符合地球的曲率,可以放置在表面或可以选择将其挤出成一定体积,中心点由包含的 Entity 确定,详细见 new Cesium.EllipseGraphics(options)
1 | var entity = viewer.entities.add({ |
ellipsoid 椭球体
描述一个椭球或球体,中心位置和方向由包含的 Entity 确定,详细见 new Cesium.EllipsoidGraphics(options)
1 | var entity = viewer.entities.add({ |
label 标签
描述位于包含位置的二维标签,详细见 new Cesium.LabelGraphics(options)
1 | var entity = viewer.entities.add({ |
model 模型
基于 glTF 的 3D
模型,模型的位置和方向由包含的 Entity 确定,不过 Cesium
虽然包括对 glTF
几何,材质,动画和蒙皮的支持,但是目前不支持照相机和灯光,详细见 new Cesium.ModelGraphics(options)
1 | var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 5000.0) |
path 路径
描述一条折线,该折线定义为 Entity 随着时间的推移所形成的路径,详细见 new Cesium.PathGraphics(options)
1 | var entityPath = viewer.entities.add({ |
plane 平面
描述一处平面,详细见 new Cesium.PlaneGraphics(options)
1 | var bluePlane = viewer.entities.add({ |
point 点
描述位于包含 Entity 的位置的图形点,详细见 new Cesium.PointGraphics(options)
1 | var point = viewer.entities.add({ |
polygon 多边形
描述由构成外部形状和任何嵌套孔的线性环的层次结构定义的多边形,多边形符合地球的曲率,可以放置在表面或可以选择将其挤出成一定体积,详细见 new Cesium.PolygonGraphics(options)
1 | var redPolygon = viewer.entities.add({ |
polyline 多线段
描述折线,前两个位置定义线段,并且每个其他位置都从前一个位置定义了一个线段,细分可以是线性连接点,大弧或固定在地形上,详细见 new Cesium.PolylineGraphics(options)
1 | var redLine = viewer.entities.add({ |
polylineVolume 多线段柱体
描述折线体积,该折线体积定义为线带和沿其拉伸的相应二维形状,生成的体积符合地球的曲率,详细见 new Cesium.PolylineVolumeGraphics(options)
1 | function computeCircle(radius) { |
rectangle 矩形
描述 Rectangle 的图形,矩形符合地球的曲率,可以放置在表面或可以选择将其挤出成一定体积,详细见 new Cesium.RectangleGraphics(options)
1 | var redRectangle = viewer.entities.add({ |
wall 墙
描述定义为线带和可选的最大和最小高度的二维墙,墙符合地球仪的曲率,可以沿着地面或在高处放置,详细见 new Cesium.WallGraphics(options)
1 | var redWall = viewer.entities.add({ |
tileset 3D Tiles 瓦片集
一个 3D Tiles
的图块集,用于流式传输海量 3D
地理空间数据集,详细见 new Cesium.Cesium3DTileset(options) 和 3d-tiles
1 | var tileset = viewer.entities.add({ |
Entity 聚合
同时,针对 Billboard
、Label
、Point
,Cesium
提供了 EntityCluster
类用于实现聚合效果,但必须结合 PinBuilder
类实现,下面为实现聚合效果的核心代码
1 | var options = { |
效果是下面这样的
Entity 管理
我们在上面介绍了 Entity
的图形类型,有这么多类型的实体,Cesium
是如何管理这些实体对象的呢?这就需要我们从初始化 Viewer
对象开始说起了
当我们初始化 Viewer
类之后,会得到一个实例化对象 viewer
,这个 viewer
会包含一个属性 entities
,它的类型是 EntityCollection
,也就是 Entity
的集合,它包括了 EntityCollection
类里面的所有属性和方法,所以 Cesium
管理 Entity
本质上是通过 EntityCollection
类进行管理的,比如下面这些方法
add
- 添加Entity
contains
- 是否存在某个Entity
getById
- 通过ID
获取Entity
remove
- 移除某个Entity
removeAll
- 移除所有的Entity
removeById
- 通过ID
移除Entity
下面是一个简单的示例
1 | var point = viewer.entities.add({ |
Entity 拾取
在三维场景中,有一种比较常见的交互方式,那就就是鼠标点击三维场景种某一个几何图形,查看该图形的包含的属性信息,并显示在对应的信息窗体中,单击事件通过 ScreenSpaceEventHandler
类注册,拾取到的信息可通过以下两种方式获取
scene.pick
- 获取窗体坐标处最顶部的实体scene.drillPick
- 窗体坐标处的实体列表
下面是一个简单的示例
1 | // 添加拾取事件 |
Entity 固定
在实际的应用系统中,会有这样的需求,要求画的实体附着在地形表面、或三维建筑表面(比如视频融合),这时候就需要设置 xxGraphics
的相关属性了,可通过 heightReference
或 classificationType
这两个属性去控制
关于 heightReference
属性值有三个取值
NONE
- 位置绝对(默认值)CLAMP_TO_GROUND
- 位置固定在地形上RELATIVE_TO_GROUND
- 位置高度是指地形上方的高度
关于 classificationType
属性值有三个取值
TERRAIN
- 将仅对地形进行分类;CESIUM_3D_TILE
- 将仅对3D Tiles
进行分类BOTH
- 将同时对Terrain
和3D Tiles
进行分类
但是有两点需要注意
- 其中
corridor
、ellipse
、polygon
、polyline
、rectangle
可通过设置classificationType
属性值显示仅贴地、仅贴建筑或者两者都贴的效果 - 而
billboard
、box
、corridor
、cylinder
、ellipse
、ellipsoid
、label
、model
、point
、polygon
、tectangle
则是通过设置heightReference
属性值为CLAMP_TO_GROUND
显示贴地效果
这里需要注意的是,如果是 polyline
则必须设置 clampToGround
属性为 true
1 | // 其中 corridor ellipse polygon retangle 会自动贴地 |
效果是下面这样的
1 | var polygon = viewer.entities.add({ |
效果是下面这样的