前面已经写了两篇博客介绍 Cesium,一篇整体上简单介绍了 Cesium 如何上手,还有一篇介绍了如何将 Cesium 与分布式地理信息处理框架 Geotrellis 相结合。Cesium 的强大之处也在于其可以将时间运用到 3 维地球上,可以根据此时间进行动画、轨迹记录、地球的光照等等所有与时间相关的可视化效果。本文介绍 Cesium 中的 Clock 控件以及如何动态加载时间序列瓦片。
这里说的 Clock 控件包含两部分,Animation 控件和 Timeline 控件,这二者基本是同时出现或隐藏的。如下图所示:
在 Cesium 中 Viewer 默认开启这两个控件,如果你想要不显示这两个控件,可以在 Viewer 初始化中设置其为 false,代码如下:
- var viewer = new Cesium.Viewer('cesiumContainer', {
- animation: false,
- timeline: false
- });
但这种方式只能在初始化时设置,无法动态的切换显示状态,灵活度上稍显不足。如下方式可以动态控制显示和隐藏,会动态调整布局。
- viewer.animation.container.style.visibility = 'visible';
- viewer.animation.container.style.visibility = 'hidden';
- viewer.timeline.container.style.visibility = 'visible';
- viewer.timeline.container.style.visibility = 'hidden';
Clock 中默认开始时间(startTime)为当前时间,终止时间(stopTime)为 24 小时后,并能获取当前时间(currentTime)。当然我们也可以通过如下代码手动设置时间轴上的时间范围:
- var start = Cesium.JulianDate.fromIso8601('2015-07-30');
- var end = Cesium.JulianDate.fromIso8601('2017-06-17');
- viewer.timeline.zoomTo(start, end);
- var clock = viewer.clock;
- clock.startTime = start;
- clock.endTime = end;
- clock.currentTime = start;
- clock.clockRange = Cesium.ClockRange.LOOP_STOP;
- clock.multiplier = 86400;
其中 start 和 end 分别代表起始和结束时间。multiplier 表示时间轴进行速度,就是说此值表示真实世界时间进度与 Cesium 中的关系,值越大时间轴就走的越快,86400 表示真实世界走过 1s 在 Cesium 中刻度走过 1 天,怎么有点南柯一梦的感觉。clockRange 属性表示时间轴达到终点之后的行为,用户可以根据自己的需要来设置,默认为: UNBOUNDED
所谓时间序列瓦片是指存在多套瓦片,每套瓦片不是单独的,与时间有关。比如我们每天拍摄一遍地球影像,然后把每天的影像都做成一套瓦片,那么一年下来就会有 365 套瓦片,采用传统方案我们只能写 365 个页面每个页面加载一天的瓦片。这样非常麻烦,并且没有一个动态变化的效果也无法进行对比。我前面介绍过如何使用 Geotrellis 生成时间序列瓦片(见 geotrellis 使用(二十三)动态加载时间序列数据 ),当然也不一定非要使用此种方式,简单的方式也可以是直接生成多套瓦片,每套瓦片的请求方式与其时间对应即可。
在前面已经介绍了如何使用 Cesium 加载我们自己的瓦片,大致如下:
- var imageryLayers = viewer.imageryLayers;
- imageryLayers.addImageryProvider(provider);
其中 provider 为我们自己创建的图层对象,时间序列瓦片与普通瓦片的区别正在此处。其创建时需要多指定与时间有关的参数。如下:
- var provider = new Cesium.webMapTileServiceImageryProvider({
- url : 'https://gibs.earthdata.nasa.gov/wmts/epsg4326/{best}/{Layer}/{Style}/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png',
- layer : 'AMSR2_Snow_Water_Equivalent',
- style : 'default',
- tileMatrixSetID : '2km',
- maximumLevel : 5,
- format : 'image/png',
- clock: viewer.clock,
- times: times,
- credit : new Cesium.Credit({text: 'NASA Global Imagery Browse Services for EOSDIS'}),
- dimensions: {
- Layer : 'AMSR2_Snow_Water_Equivalent',
- best: 'best'
- }
- });
style 参数会替换掉 url 中的 {Style} 字符串;tileMatrixSetID 会替换掉 {TileMatrixSet} 字符串;{TileMatrix}/{TileRow}/{TileCol}表示 z、x、y,无需手动设置;clock 表示所使用的时钟,直接设置为系统时钟;cedit 表示版权信息;dimensions 里面的参数只要出现在 url 中全部会被其 value 替换掉。
重点就是其中的 times,需要传入一个 TimeIntervalCollection 对象。其创建方式如下:
- var times = Cesium.TimeIntervalCollection.fromIso8601({
- iso8601: '2015-07-30/2017-06-16/P20D',
- leadingInterval: true,
- trailingInterval: true,
- isStopIncluded: false,
- dataCallback: dataCallback
- });
iso8601 参数为时间范围及间隔,用'/'分割,第一个表示开始时间,第二个表示结束时间,P20D 表示间隔 20 天,还可以是 P1M、P1Y、P1Y3M5DT6H7M30S 等,代表不同的时间间隔。
dataCallback 表示在每个时间段内如何取值,比如时间间隔为 20 天,那么我们可以取第一天为请求瓦片的时间,也可以是最后一天,乃至范围内甚至是范围外的任意一天,这个就由 dataCallback 函数进行设置。示例如下:
- function dataCallback(interval, index) {
- console.log(index);
- var time;
- if (index === 0) {
- time = Cesium.JulianDate.toIso8601(interval.stop);
- } else {
- time = Cesium.JulianDate.toIso8601(interval.start);
- }
- return {
- Time: time
- };
- }
interval 表示传入的时间区间,index 表示是第几个区间,这两个参数也就分割了 times 中的完整时间段,所以我们可以给 time 赋值为任意想要设置的值。最后返回的是 key、value 形式,此处 Time 为 key,而其必须与创建图层时候的 {Time} 字符串一致,否则请求的时候无法替换时间信息。
本文简单介绍了 Clock 控件以及如何动态加载时间序列瓦片。合理运用 Cesium 中的 Clock 控件能够做出很多漂亮的可视化效果,甚至如同 Flash 一样只需要指定几个时间点对象的位置,Cesium 就会自动插值成动画,这些我们在后面介绍。
最后希望大家能在 2017 年度全网原创 IT 博主评选活动投票:http://www.itbang.me/goVote/215 投上宝贵的一票(最勤奋博主:wsf),谢谢!
来源: http://www.cnblogs.com/shoufengwei/p/8046529.html