diff --git a/Apps/CesiumViewer/CesiumViewer.js b/Apps/CesiumViewer/CesiumViewer.js index 4385dce1d989..52144900acbd 100644 --- a/Apps/CesiumViewer/CesiumViewer.js +++ b/Apps/CesiumViewer/CesiumViewer.js @@ -101,13 +101,6 @@ define([ source.loadUrl(endUserOptions.source).then(function() { viewer.dataSources.add(source); - var dataClock = source.getClock(); - if (defined(dataClock)) { - dataClock.clone(viewer.clock); - viewer.timeline.updateFromClock(); - viewer.timeline.zoomTo(dataClock.startTime, dataClock.stopTime); - } - if (defined(endUserOptions.lookAt)) { var dynamicObject = source.getDynamicObjectCollection().getObject(endUserOptions.lookAt); if (defined(dynamicObject)) { @@ -140,4 +133,4 @@ define([ } } } -}); \ No newline at end of file +}); diff --git a/Apps/Sandcastle/gallery/CZML.html b/Apps/Sandcastle/gallery/CZML.html new file mode 100644 index 000000000000..8318fd81b0bf --- /dev/null +++ b/Apps/Sandcastle/gallery/CZML.html @@ -0,0 +1,195 @@ + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + diff --git a/Apps/Sandcastle/gallery/Simple CZML Demo.jpg b/Apps/Sandcastle/gallery/CZML.jpg similarity index 100% rename from Apps/Sandcastle/gallery/Simple CZML Demo.jpg rename to Apps/Sandcastle/gallery/CZML.jpg diff --git a/Apps/Sandcastle/gallery/Simple CZML Demo.html b/Apps/Sandcastle/gallery/Simple CZML Demo.html deleted file mode 100644 index 2195d88e25f5..000000000000 --- a/Apps/Sandcastle/gallery/Simple CZML Demo.html +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - Cesium Demo - - - - - - -
-

Loading...

-
- - - diff --git a/CHANGES.md b/CHANGES.md index 70827048f6ab..e66f184f15f4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ Beta Releases ### b20 - 2013-09-01 * Breaking changes: - * ... + * `DataSourceDisplay` now requires a `DataSourceCollection` to be passed into its constructor. * Fixed broken surface rendering in Columbus View when using the `EllipsoidTerrainProvider`. * Optimized polyline bounding spheres. * Upgraded Knockout from version 2.2.1 to 2.3.0. @@ -15,6 +15,7 @@ Beta Releases * Improved `WallGeometry` to follow the curvature of the earth. * Added `PolylinePipeline.scaleToSurface`. * Added `PolylinePipeline.scaleToGeodeticHeight`. +* `Viewer` now automatically sets its clock to that of the first added `DataSource`, regardless of how it was added to the `DataSourceCollection`. Previously, this was only done for dropped files by `viewerDragDropMixin`. ### b19 - 2013-08-01 diff --git a/Source/DynamicScene/DataSourceDisplay.js b/Source/DynamicScene/DataSourceDisplay.js index 31c292507791..19a334216fd3 100644 --- a/Source/DynamicScene/DataSourceDisplay.js +++ b/Source/DynamicScene/DataSourceDisplay.js @@ -5,7 +5,6 @@ define([ '../Core/destroyObject', '../Core/DeveloperError', '../Core/EventHelper', - './DataSourceCollection', './DynamicBillboardVisualizer', './DynamicEllipsoidVisualizer', './DynamicConeVisualizerUsingCustomSensor', @@ -22,7 +21,6 @@ define([ destroyObject, DeveloperError, EventHelper, - DataSourceCollection, DynamicBillboardVisualizer, DynamicEllipsoidVisualizer, DynamicConeVisualizerUsingCustomSensor, @@ -51,16 +49,19 @@ define([ * @constructor * * @param {Scene} scene The scene in which to display the data. + * @param {DataSourceCollection} dataSourceCollection The data sources to display. * @param {Array} [visualizerTypes] The array of visualizer constructor functions that will be created for each data source. If undefined, All standard visualizers will be used. * * @exception {DeveloperError} scene is required. + * @exception {DeveloperError} dataSourceCollection is required. */ - var DataSourceDisplay = function(scene, visualizerTypes) { + var DataSourceDisplay = function(scene, dataSourceCollection, visualizerTypes) { if (!defined(scene)) { throw new DeveloperError('scene is required.'); } - - var dataSourceCollection = new DataSourceCollection(); + if (typeof dataSourceCollection === 'undefined') { + throw new DeveloperError('dataSourceCollection is required.'); + } this._eventHelper = new EventHelper(); this._eventHelper.add(dataSourceCollection.dataSourceAdded, this._onDataSourceAdded, this); @@ -71,6 +72,10 @@ define([ this._timeVaryingSources = []; this._staticSourcesToUpdate = []; this._visualizersTypes = defaultValue(visualizerTypes, defaultVisualizerTypes).slice(0); + + for ( var i = 0, len = dataSourceCollection.getLength(); i < len; i++) { + this._onDataSourceAdded(dataSourceCollection, dataSourceCollection.get(i)); + } }; /** @@ -133,13 +138,7 @@ define([ var dataSourceCollection = this._dataSourceCollection; for ( var i = 0, length = dataSourceCollection.getLength(); i < length; ++i) { - var dataSource = dataSourceCollection.get(i); - - this._onDataSourceRemoved(this._dataSourceCollection, dataSource); - - if (typeof dataSource.destroy === 'function') { - dataSource.destroy(); - } + this._onDataSourceRemoved(this._dataSourceCollection, dataSourceCollection.get(i)); } return destroyObject(this); @@ -229,4 +228,4 @@ define([ }; return DataSourceDisplay; -}); \ No newline at end of file +}); diff --git a/Source/Widgets/Viewer/Viewer.js b/Source/Widgets/Viewer/Viewer.js index 81893e89724f..5d368abaa1da 100644 --- a/Source/Widgets/Viewer/Viewer.js +++ b/Source/Widgets/Viewer/Viewer.js @@ -10,6 +10,7 @@ define([ '../../Core/EventHelper', '../../Core/requestAnimationFrame', '../../Core/ScreenSpaceEventType', + '../../DynamicScene/DataSourceCollection', '../../DynamicScene/DataSourceDisplay', '../Animation/Animation', '../Animation/AnimationViewModel', @@ -34,6 +35,7 @@ define([ EventHelper, requestAnimationFrame, ScreenSpaceEventType, + DataSourceCollection, DataSourceDisplay, Animation, AnimationViewModel, @@ -188,20 +190,11 @@ Either specify options.imageryProvider instead or set options.baseLayerPicker to useDefaultRenderLoop : false }); - //Data source display - var dataSourceDisplay = new DataSourceDisplay(cesiumWidget.scene); - this._dataSourceDisplay = dataSourceDisplay; + var dataSourceCollection = new DataSourceCollection(); + var dataSourceDisplay = new DataSourceDisplay(cesiumWidget.scene, dataSourceCollection); var clock = cesiumWidget.clock; - - this._eventHelper = new EventHelper(); - - function updateDataSourceDisplay(clock) { - dataSourceDisplay.update(clock.currentTime); - } - this._eventHelper.add(clock.onTick, updateDataSourceDisplay); - - this._clockViewModel = new ClockViewModel(clock); + var clockViewModel = new ClockViewModel(clock); var toolbar = document.createElement('div'); toolbar.className = 'cesium-viewer-toolbar'; @@ -246,7 +239,7 @@ Either specify options.imageryProvider instead or set options.baseLayerPicker to var animationContainer = document.createElement('div'); animationContainer.className = 'cesium-viewer-animationContainer'; viewerContainer.appendChild(animationContainer); - animation = new Animation(animationContainer, new AnimationViewModel(this._clockViewModel)); + animation = new Animation(animationContainer, new AnimationViewModel(clockViewModel)); } //Timeline @@ -287,9 +280,35 @@ Either specify options.imageryProvider instead or set options.baseLayerPicker to timeline.container.style.right = 0; } + var eventHelper = new EventHelper(); + + function updateDataSourceDisplay(clock) { + dataSourceDisplay.update(clock.currentTime); + } + + eventHelper.add(clock.onTick, updateDataSourceDisplay); + + function setClockFromDataSource(dataSourceCollection, dataSource) { + if (dataSourceCollection.getLength() === 1) { + var dataSourceClock = dataSource.getClock(); + if (typeof dataSourceClock !== 'undefined') { + dataSourceClock.clone(clock); + if (typeof timeline !== 'undefined') { + timeline.updateFromClock(); + timeline.zoomTo(dataSourceClock.startTime, dataSourceClock.stopTime); + } + } + } + } + + eventHelper.add(dataSourceCollection.dataSourceAdded, setClockFromDataSource); + this._container = container; this._viewerContainer = viewerContainer; this._cesiumWidget = cesiumWidget; + this._dataSourceCollection = dataSourceCollection; + this._dataSourceDisplay = dataSourceDisplay; + this._clockViewModel = clockViewModel; this._toolbar = toolbar; this._homeButton = homeButton; this._sceneModePicker = sceneModePicker; @@ -297,6 +316,7 @@ Either specify options.imageryProvider instead or set options.baseLayerPicker to this._animation = animation; this._timeline = timeline; this._fullscreenButton = fullscreenButton; + this._eventHelper = eventHelper; this._lastWidth = 0; this._lastHeight = 0; this._useDefaultRenderLoop = undefined; @@ -414,7 +434,7 @@ Either specify options.imageryProvider instead or set options.baseLayerPicker to */ dataSources : { get : function() { - return this._dataSourceDisplay.getDataSources(); + return this._dataSourceCollection; } }, @@ -696,6 +716,8 @@ Either specify options.imageryProvider instead or set options.baseLayerPicker to this._dataSourceDisplay = this._dataSourceDisplay.destroy(); this._cesiumWidget = this._cesiumWidget.destroy(); + this._dataSourceCollection = this._dataSourceCollection.destroy(); + return destroyObject(this); }; diff --git a/Source/Widgets/Viewer/viewerDragDropMixin.js b/Source/Widgets/Viewer/viewerDragDropMixin.js index 2415150f2b0c..7989986e2940 100644 --- a/Source/Widgets/Viewer/viewerDragDropMixin.js +++ b/Source/Widgets/Viewer/viewerDragDropMixin.js @@ -158,7 +158,7 @@ define([ for ( var i = 0; i < length; i++) { var f = files[i]; var reader = new FileReader(); - reader.onload = createOnLoadCallback(viewer, f.name, i === 0); + reader.onload = createOnLoadCallback(viewer, f.name); reader.onerror = createOnDropErrorCallback(viewer, f.name); reader.readAsText(f); } @@ -204,7 +204,7 @@ define([ return (suffixLength < strLength) && (str.indexOf(suffix, strLength - suffixLength) !== -1); } - function createOnLoadCallback(viewer, source, firstTime) { + function createOnLoadCallback(viewer, source) { var DataSource; var sourceUpperCase = source.toUpperCase(); if (endsWith(sourceUpperCase, ".CZML")) { @@ -222,16 +222,6 @@ define([ try { when(dataSource.load(JSON.parse(evt.target.result), source), function() { viewer.dataSources.add(dataSource); - if (firstTime) { - var dataClock = dataSource.getClock(); - if (defined(dataClock)) { - dataClock.clone(viewer.clock); - if (defined(viewer.timeline)) { - viewer.timeline.updateFromClock(); - viewer.timeline.zoomTo(dataClock.startTime, dataClock.stopTime); - } - } - } }, function(error) { viewer.onDropError.raiseEvent(viewer, source, error); }); @@ -248,4 +238,4 @@ define([ } return viewerDragDropMixin; -}); \ No newline at end of file +}); diff --git a/Specs/DynamicScene/DataSourceDisplaySpec.js b/Specs/DynamicScene/DataSourceDisplaySpec.js index ef4a6c66554e..454b2f4bf383 100644 --- a/Specs/DynamicScene/DataSourceDisplaySpec.js +++ b/Specs/DynamicScene/DataSourceDisplaySpec.js @@ -3,6 +3,7 @@ defineSuite([ 'DynamicScene/DataSourceDisplay', 'Core/Iso8601', 'Core/JulianDate', + 'DynamicScene/DataSourceCollection', 'Specs/createScene', 'Specs/destroyScene', 'Specs/MockDataSource' @@ -10,15 +11,18 @@ defineSuite([ DataSourceDisplay, Iso8601, JulianDate, + DataSourceCollection, createScene, destroyScene, MockDataSource) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + var dataSourceCollection; var scene; beforeAll(function() { scene = createScene(); + dataSourceCollection = new DataSourceCollection(); }); afterAll(function() { @@ -63,29 +67,25 @@ defineSuite([ it('constructor sets expected values', function() { var visualizerTypes = [MockVisualizer]; - var display = new DataSourceDisplay(scene, visualizerTypes); + var display = new DataSourceDisplay(scene, dataSourceCollection, visualizerTypes); expect(display.getScene()).toBe(scene); expect(display.getVisualizerTypes()).toEqual(visualizerTypes); - expect(display.getDataSources().getLength()).toEqual(0); + expect(display.getDataSources()).toBe(dataSourceCollection); expect(display.isDestroyed()).toEqual(false); display.destroy(); }); - it('destroy destroys underlying data sources', function() { - var display = new DataSourceDisplay(scene); + it('destroy does not destroy underlying data sources', function() { var dataSource = new MockDataSource(); - var dataSourceNoDestroy = new MockDataSource(); - delete dataSourceNoDestroy.destroy; - display.getDataSources().add(dataSource); - display.getDataSources().add(dataSourceNoDestroy); + dataSourceCollection.add(dataSource); + + var display = new DataSourceDisplay(scene, dataSourceCollection); expect(dataSource.destroyed).toEqual(false); - expect(dataSourceNoDestroy.destroyed).toEqual(false); display.destroy(); - expect(dataSource.destroyed).toEqual(true); - expect(dataSourceNoDestroy.destroyed).toEqual(false); + expect(dataSource.destroyed).toEqual(false); expect(display.isDestroyed()).toEqual(true); }); @@ -94,9 +94,9 @@ defineSuite([ var dynamicSource = new MockDataSource(); dynamicSource.isTimeVarying = true; - var display = new DataSourceDisplay(scene, [MockVisualizer]); - display.getDataSources().add(staticSource); - display.getDataSources().add(dynamicSource); + var display = new DataSourceDisplay(scene, dataSourceCollection, [MockVisualizer]); + dataSourceCollection.add(staticSource); + dataSourceCollection.add(dynamicSource); var staticSourceVisualizer = staticSource._visualizerCollection.getVisualizers()[0]; expect(staticSourceVisualizer).toBeInstanceOf(MockVisualizer); @@ -137,9 +137,9 @@ defineSuite([ it('a static source can become dynamic (and vice versa)', function() { var source = new MockDataSource(); + dataSourceCollection.add(source); - var display = new DataSourceDisplay(scene, [MockVisualizer]); - display.getDataSources().add(source); + var display = new DataSourceDisplay(scene, dataSourceCollection, [MockVisualizer]); var sourceVisualizer = source._visualizerCollection.getVisualizers()[0]; expect(sourceVisualizer).toBeInstanceOf(MockVisualizer); @@ -174,7 +174,6 @@ defineSuite([ expect(sourceVisualizer.lastUpdateTime).toBe(newTime); expect(sourceVisualizer.updatesCalled).toEqual(3); - //Switch back to static source.isTimeVarying = false; source.getChangedEvent().raiseEvent(source); @@ -195,12 +194,18 @@ defineSuite([ it('constructor throws if scene undefined', function() { expect(function(){ - return new DataSourceDisplay(undefined, []); + return new DataSourceDisplay(undefined, dataSourceCollection, []); + }).toThrow(); + }); + + it('constructor throws if dataSourceCollection undefined', function() { + expect(function(){ + return new DataSourceDisplay(scene, undefined, []); }).toThrow(); }); it('update throws if time undefined', function() { - var display = new DataSourceDisplay(scene); + var display = new DataSourceDisplay(scene, dataSourceCollection); expect(function(){ return display.update(); }).toThrow(); diff --git a/Specs/Widgets/Viewer/ViewerSpec.js b/Specs/Widgets/Viewer/ViewerSpec.js index 15778ac7faef..191b5d7e5eb5 100644 --- a/Specs/Widgets/Viewer/ViewerSpec.js +++ b/Specs/Widgets/Viewer/ViewerSpec.js @@ -9,10 +9,15 @@ defineSuite([ 'Widgets/HomeButton/HomeButton', 'Widgets/SceneModePicker/SceneModePicker', 'Widgets/Timeline/Timeline', + 'Core/ClockRange', + 'Core/ClockStep', + 'Core/JulianDate', 'DynamicScene/DataSourceDisplay', 'DynamicScene/DataSourceCollection', + 'DynamicScene/DynamicClock', 'Scene/EllipsoidTerrainProvider', - 'Scene/SceneMode' + 'Scene/SceneMode', + 'Specs/MockDataSource' ], function( Viewer, Animation, @@ -23,10 +28,15 @@ defineSuite([ HomeButton, SceneModePicker, Timeline, + ClockRange, + ClockStep, + JulianDate, DataSourceDisplay, DataSourceCollection, + DynamicClock, EllipsoidTerrainProvider, - SceneMode) { + SceneMode, + MockDataSource) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -359,4 +369,25 @@ defineSuite([ expect(viewer.useDefaultRenderLoop).toEqual(false); }); }); + + it('sets the clock and timeline based on the first data source', function() { + var dataSource = new MockDataSource(); + dataSource.clock = new DynamicClock(); + dataSource.clock.startTime = JulianDate.fromIso8601('2013-08-01T18:00Z'); + dataSource.clock.stopTime = JulianDate.fromIso8601('2013-08-21T02:00Z'); + dataSource.clock.currentTime = JulianDate.fromIso8601('2013-08-02T00:00Z'); + dataSource.clock.clockRange = ClockRange.CLAMPED; + dataSource.clock.clockStep = ClockStep.TICK_DEPENDENT; + dataSource.clock.multiplier = 20.0; + + viewer = new Viewer(container); + viewer.dataSources.add(dataSource); + + expect(viewer.clock.startTime).toEqual(dataSource.clock.startTime); + expect(viewer.clock.stopTime).toEqual(dataSource.clock.stopTime); + expect(viewer.clock.currentTime).toEqual(dataSource.clock.currentTime); + expect(viewer.clock.clockRange).toEqual(dataSource.clock.clockRange); + expect(viewer.clock.clockStep).toEqual(dataSource.clock.clockStep); + expect(viewer.clock.multiplier).toEqual(dataSource.clock.multiplier); + }); }); \ No newline at end of file