UNPKG

terriajs

Version:

Geospatial data visualization platform.

99 lines (84 loc) 3.75 kB
"use strict"; var CesiumClock = require('terriajs-cesium/Source/Core/Clock'); var TimeInterval = require('terriajs-cesium/Source/Core/TimeInterval'); var inherit = require('../Core/inherit'); var defined = require('terriajs-cesium/Source/Core/defined'); /** * Extension of the standard Clock provided by Cesium customised to deal with Terria-level abstractions like * {@link CatalogItem}s. * @param options see {@link terriajs-cesium/Source/Core/Clock} * @constructor */ var Clock = function(options) { CesiumClock.call(this, options); var baseProperty = Object.getOwnPropertyDescriptor(CesiumClock.prototype, 'currentTime'); Object.defineProperty(this, 'currentTime', { get: function() { return baseProperty.get.call(this); }, set: function(newTime) { var gap = this.determineGap(newTime); baseProperty.set.call(this, defined(gap) ? gap.stop : newTime); } }); this.onTick.addEventListener(function() { var newTime = this.currentTime; var gap = this.determineGap(newTime); this._currentTime = defined(gap) ? gap.stop : newTime; }, this); }; inherit(CesiumClock, Clock); /** * Set the {@link CatalogItem} that this clock is currently tracking. * * @param {CatalogItem} item */ Clock.prototype.setCatalogItem = function(item) { this.catalogItem = item; // The next line "gets" the value of item.clock into "this". // Ie. it copies startTime, stopTime, currentTime, clockRange, multiplier and clockStep from the datasource clock onto "this" // (which is typically the terria.clock instance). item.clock.getValue(this); }; /** * Determines whether the passed {@link JulianDate} occurs within a gap in the currently tracked {@link CatalogItem}'s * data. If so returns that gap as a {@link TimeInterval}, otherwise undefined. * * @param {JulianDate} date * @returns {TimeInterval} The gap in the data that the passed date falls within, if one exists. */ Clock.prototype.determineGap = function(date) { var intervals = this.catalogItem && this.catalogItem.intervals; if (defined(intervals)) { var matchingIntervalIndex = intervals.indexOf(date); // If an index can't be found, TimeIntervalCollection returns the (negative) bitwise complement of the next index after // where the date would fit... if (matchingIntervalIndex >= 0) { // ... so if it's >= 0 our date actually has an interval specified for it, return undefined. return; } // ... otherwise flip the bits back and use the index to figure out where the boundaries of our gap are. var gapEndIndex = ~matchingIntervalIndex; var gapStart, gapStop; if (gapEndIndex === 0) { gapStart = this.catalogItem.clock.startTime; gapStop = intervals.get(0).start; } else if (gapEndIndex === intervals.length) { gapStop = this.catalogItem.clock.stopTime; } return new TimeInterval({ // using || instead of defaultValue because we don't want the default to execute if gapStart is truthy. start: gapStart || intervals.get(gapEndIndex - 1).stop, stop: gapStop || intervals.get(gapEndIndex).start, isStartIncluded: false, isStopIncluded: false }); } }; Clock.prototype.tick = function() { CesiumClock.prototype.tick.call(this); // Return this._currentTime instead of whatever the base class tick returns. // This way we return the gap-jumped time. return this._currentTime; }; module.exports = Clock;