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