cesium-CZML描述动态场景
CZML具有两种动态可视化机制:按时间间隔和按时间戳描述动态场景变化。按时间间隔描述动态变化是指CZML属性值在一段时间内是一个固定值,而在另一段时间是另一个固定值;按时间戳描述动态变化是指每个时间节点对应一个值,通过内插算法可推算两个时间节点之间的属性值。
按时间间隔描述变化
通常情况下CZML的属性值是一个数组,数组中的每个元素对应一个不同的时间和属性值。对于时间间隔,使用interval属性,通过ISO 8601 interval格式的字面值表示,这种表示方法的好处是不需要进行时差计算,不需要换算到协调世界时。
{
"id":"myObject",
"someProperty":[
{
"interval" : "2012-04-30T12:00:00Z/13:00:00Z"
"number" : 5
},
{
"interval":"2012-04-30T13:00:00/14:00:00Z",
"number": 6
}
]
}
这里定义了一个someProperty属性,它包含两个时间间隔:第一个是从 12点到13点,属性值为5;第二个是从13点到14点,属性值为6。在时间由第一个间隔变化到第二个间隔的时候,属性值会瞬间从5变到6。
按时间戳描述变化
上文按时间间隔可描述属性的离散动态变化,但不具有连续变化效果,而按照时间截采样差值可生成光滑连续的动态变化效果。CZML(1.0版)只有数值型属性才可按时间戳描述动态变化,如position、color、scale等。CZML 提供如表7. 2中的5个属性来设定动态变化效果。
CZML插值属性:
名称 | JSON类型 | 说明 |
---|---|---|
epoch | string | 使用ISO 8601规范来表示日期和时间 |
nextTime | string或number | 在时间间隔内下一个采样的时间,可以通过ISO 8061方式,也可以通过历元秒数来定义,它决定了不同packet之间的采样是否有停顿 |
previousTime | string或number | 在时间间隔内前一个采样的时间,可以通过ISO 8061方式,也可以通过历元秒数来定义,它决定了不同packet之间的采样是否有停顿 |
InterpolationAlgorithm | string | 用于插值的算法,有LAGTANGE,HERMITE和GEODESIC方法等,默认是LAGRANGE。如果位置不在该采样区间,那么这个属性值会被忽略 |
interpolationDegree | number | 定义了用来插值所所使用的多项式次数,1表示线性差值,2表示二次插值法,默认为1。如果使用GEODESIC插值算法,那么这个属性将被忽略 |
下述示例代码表示从12点开始的2分钟内坐标变化的情况,采用拉格朗日5次多项式插值方法,形成光滑连续的变化过程。nextTime和reviousTime通常与分包(packet)结合在一起。
{
"someInterpolatableProperty": {
"epoch": "2012-04一30T12:00Z",
"cartesian": [
0.0,1.0,2.0,3.0,
60.0,4.0,5.0,6.0,
120.0,7.0,8.0,9.0
],
"interpolationAlgorithm": "LAGRANGE",
"interpolationDegree": 5
}
}
CZML流式加载
如果将整个CZML文件放在一个大JSON数组中,会使增量加载变得很困难。虽然浏览器允许访问没有读取完的流数据,但是解析不完整的数据需要漫长而烦琐的字符串操作。为了使过程更高效,CZML使用浏览器的server-sentevents(EventSource)API来处理流数据。在实际操作中,每个CZML packet会被作为单独的一个事件传输到客户端,如下所示:
event:czml
data{
// packet one
}
event:czml
data: {
// packet two
}
当览器接收到一个packet后就会发出一个事件,事件中会包含刚刚接收到的数据。此时可以通过增量方式高效地处理CAML数据。目前为止,我们都是使用packet来描述对象。packet包含了所有这个对象的图形属性。除此之外,还可以使用其他的方式,例如一个CZML文件或流可以包含多个packet,每个parcket都有相同的id。分别描述同一个对象的不同方面的属性。
事实上在大多数情况下使用两个packet来描述一个对象。 当对象属性跨越多个时间间隔,或者一个时间间隔有很多个时间戳采样时,这样做就很有用。通过将一个属性定义打包进多个packet中,可以使数据更快地传输到Cesium中,减少用户等待的时间。
分包过程中,如果CZML属性按照时间间隔变化,那么同一个packet或多个packet之间,虽然不要求属性值必须按时间递增描述,为了清晰易读还是尽量按照时间顺序描述。分包时如果CZML按时间戳内插属性值,同一个packet必须按 照时间递增顺序描述属性值,多个packet 不要求必须按时间递增记录,倘若多个packet没有按时间递增记录属性,应指定priviousTime或nextTime属性,以免造成内插错误。下面代码中packet1和packet2不连续,通过设定priviousTime和nextTime,packetl执行完后直接执行packet3,再执行packet2。
{
//packet 1
"id": "myObject1",
"someInterpolatableProperty": {
"epoch": "2012-04-30T12:00:00Z",
"cartesian": [
0.0,1.0,2.0,3.0,
1.0,4.0,5.0,6.0,
2.0,7.0,8.0,9.0,
3.0,10.1,11.0,12.0
],
"previousTime": -1.0,
"nextTime": 4.0
}
},
{
//packet 2
"id": "myObject1",
"someInterpolatableProperty": {
"cartesian":[
8.0,25.0,26.0,27.0,
9.0,28.0,29.0,30.0,
10.0,31.0,32.0,33.0],
"previousTime": 8.0,
"nextTime": 11.0
}
},
{
//packet 3
"id": "myObject1",
"someInterpolatableProperty": {
"cartesian":[
4.0,13.0,14.0,15.0,
5.0,16.0,17.0,18.0,
6.0,19.0,20.0,21.0,
7.0,22.0,23.0,24.0
],
"previousTime": 4.0,
"nextTime": 8.0
}
}
实际开发过程中时间间隔和时间戳可以混合使用,如不同时间间隔内可设定时间戳进行属性值内插。CZML的packet还有一个特别的额外属性availability ,它表示packet在什么时间段内是可用的。在此时间段则调用对应时间段的数据,否则数据不显示。同一对象若有不同packet, 默认最后一个packet的availability属性发挥作用。
轨迹数据可视化
轨迹数据视化原理则是将时刻与坐标点相对应,按照时间顺序通过某种插值方法将轨迹点连成条光滑的轨迹曲线。 为了更加通真显示轨迹动态效果,通常每条轨迹会有一个实物模型,如车辆、飞机或人物用于真实刻画不同情景下的轨迹特点。
轨迹动态可视化核心要素是时间和对应坐标点,展示地理时空动态变化特征是Cesium的一大特色。Cesium 默认添加时间控件Animation和Timeline。
轨迹可视化方法多样,但是大致原理相同。CZML是Cesium独有的用于措述动态场景的JSON语言,而且CZML扩展了clock函数,可在其中设置clock相关属性。本节直接使用CZML构建动态轨迹场景。如果动态轨迹点是以实物模型的样式展示,如飞机模型,则飞机机头方向随着轨迹走势一直变化,Cesium有专门的转向函数orientation。
示例代码如下:
//创建CZXL对象
var czml = [{
// 创建第一个package
// 固定格式
"id": "document",
// 固定版本1.0
"version" : "1.0",
// clock必须在package1中设置
"clock": {
//时间间隔
"interval": "2019-08-04T16:00:00Z/2019-08-04T16:30:00Z",
//设定当前时间节点
"currentTime": "2012-08-0416.00:00",
//设定时间速率为10
"multiplier": 10
}
},
{
//创建第二个package
//轨迹id
"id" :"7808F0",
//轨迹可视的时间间隔
"availability" :"2019-08-04T16:00Z/2019-08-0416:30:00Z",
"position": {
"epoch": " 2019-08-04T16:00:00+00:00",
//轨迹显示初始时刻点"cartographicDegrees"
"cartographicDegrees": [ //参数分别对应:时刻/秒、经度、纬度、高程
0, 114.835342, 34.490276, 10081,
4, 114.836441, 34.501282, 10088,
12, 114.837006, 34.506821, 10088,
14, 114.838486, 34.522442, 10081,
18, 114.83947, 34.532593, 10081,
33, 114.841576, 34.554005, 10081,
36, 114.842316, 34.561501, 10081,
40, 114.843674, 34.575806, 10073
]
},
//可视化模型
"model":{"gltf":"Cesium_Air.glb","scale":1,"minimumPixeSize":40},
"orientation":{
//设置模型转向方法,根据position进行四元数方向转换
"velocityReference":"# position"
}
}];
// 通过CzmlDataSource添加CZML对象
viewer.dataSources.add(Cesium.CzmlDataSource.load(czml))