terriajs
Version:
Geospatial data visualization platform.
747 lines (611 loc) • 30 kB
JavaScript
/*
* A collection of additional viewer functionality independent
* of datasets
*/
"use strict";
/*global require,console*/
var BingMapsApi = require('terriajs-cesium/Source/Core/BingMapsApi');
var Cartesian3 = require('terriajs-cesium/Source/Core/Cartesian3');
//var Cesium = require('../Models/Cesium');
var CesiumMath = require('terriajs-cesium/Source/Core/Math');
var cesiumRequestAnimationFrame = require('terriajs-cesium/Source/Core/requestAnimationFrame');
var clone = require('terriajs-cesium/Source/Core/clone');
var CesiumTerrainProvider = require('terriajs-cesium/Source/Core/CesiumTerrainProvider');
//var CesiumWidget = require('terriajs-cesium/Source/Widgets/CesiumWidget/CesiumWidget');
var createCredit = require('../Map/createCredit');
var createWorldTerrain = require('terriajs-cesium/Source/Core/createWorldTerrain');
var Credit = require('terriajs-cesium/Source/Core/Credit');
var CreditDisplay = require('terriajs-cesium/Source/Scene/CreditDisplay');
var DrawExtentHelper = require('../Map/DrawExtentHelper');
var defaultValue = require('terriajs-cesium/Source/Core/defaultValue');
var defined = require('terriajs-cesium/Source/Core/defined');
var Ellipsoid = require('terriajs-cesium/Source/Core/Ellipsoid');
var EllipsoidTerrainProvider = require('terriajs-cesium/Source/Core/EllipsoidTerrainProvider');
var EventHelper = require('terriajs-cesium/Source/Core/EventHelper');
var FeatureDetection = require('terriajs-cesium/Source/Core/FeatureDetection');
var FrameRateMonitor = require('terriajs-cesium/Source/Scene/FrameRateMonitor');
var Ion = require('terriajs-cesium/Source/Core/Ion');
var KeyboardEventModifier = require('terriajs-cesium/Source/Core/KeyboardEventModifier');
var knockout = require('terriajs-cesium/Source/ThirdParty/knockout');
var L = require('leaflet');
var Leaflet = require('../Models/Leaflet');
var LeafletDataSourceDisplay = require('../Map/LeafletDataSourceDisplay');
var LeafletVisualizer = require('../Map/LeafletVisualizer');
var Matrix3 = require('terriajs-cesium/Source/Core/Matrix3');
var Matrix4 = require('terriajs-cesium/Source/Core/Matrix4');
var runLater = require('../Core/runLater');
var ScreenSpaceEventType = require('terriajs-cesium/Source/Core/ScreenSpaceEventType');
var SingleTileImageryProvider = require('terriajs-cesium/Source/Scene/SingleTileImageryProvider');
var supportsWebGL = require('../Core/supportsWebGL');
var Transforms = require('terriajs-cesium/Source/Core/Transforms');
var Tween = require('terriajs-cesium/Source/ThirdParty/Tween');
var URI = require('urijs');
var ViewerMode = require('../Models/ViewerMode');
var NoViewer = require('../Models/NoViewer');
var when = require('terriajs-cesium/Source/ThirdParty/when');
//use our own bing maps key
BingMapsApi.defaultKey = undefined;
// Make Cesium think pixelated image rendering is supported, always.
// As a result, Cesium will honor the devicePixelRatio even in browsers (IE) that don't
// support pixelated rendering. This means the imagery may look slightly blurrier than
// in other browers, but that's better than rendering 4x the pixels in an already
// slow browser!
FeatureDetection.supportsImageRenderingPixelated = function() { return true; };
// Don't let Cesium automatically add its logo. We'll do so manually when necessary.
CreditDisplay._cesiumCreditInitialized = true;
/**
* The Terria map viewer, utilizing Cesium and Leaflet.
* @param {Terria} terria The Terria instance.
* @param {Object} options Object with the following properties:
* @param {Object} [options.developerAttribution] Attribution for the map developer, displayed at the bottom of the map. This is an
* object with two properties, `text` and `link`. `link` is optional and is the URL to open when the user
* clicks on the attribution.
* @param {String|TerrainProvider} [options.terrain] The terrain to use in the 3D view. This may be a string, in which case it is loaded using
* `CesiumTerrainProvider`, or it may be a `TerrainProvider`. If this property is undefined, STK World Terrain
* is used.
* @param {Integer} [options.maximumLeafletZoomLevel] The maximum level to which to allow Leaflet to zoom to.
If this property is undefined, Leaflet defaults to level 18.
*/
var TerriaViewer = function(terria, options) {
options = defaultValue(options, {});
this._mapContainer = defaultValue(options.mapContainer, 'cesiumContainer');
this._uiContainer = defaultValue(options.uiContainer, 'ui');
this._developerAttribution = options.developerAttribution;
this.maximumLeafletZoomLevel = options.maximumLeafletZoomLevel;
var webGLSupport = supportsWebGL(); // true, false, or 'slow'
this._slowWebGLAvailable = webGLSupport === 'slow';
this._useWebGL = webGLSupport === true;
if ((terria.viewerMode === ViewerMode.CesiumTerrain || terria.viewerMode === ViewerMode.CesiumEllipsoid) && !this._useWebGL) {
if (this._slowWebGLAvailable) {
terria.error.raiseEvent({
title : 'Poor WebGL performance',
message : 'Your web browser reports that it has performance issues displaying '+terria.appName+' in 3D, \
so you will see a limited, 2D-only experience. For the full 3D experience, please try using a different web browser, upgrading your video \
drivers, or upgrading your operating system.'
});
} else {
terria.error.raiseEvent({
title : 'WebGL not supported',
message : terria.appName+' works best with a web browser that supports <a href="http://get.webgl.org" target="_blank">WebGL</a>, \
including the latest versions of <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>, \
<a href="http://www.mozilla.org/firefox" target="_blank">Mozilla Firefox</a>, \
<a href="https://www.apple.com/au/osx/how-to-upgrade/" target="_blank">Apple Safari</a>, and \
<a href="http://www.microsoft.com/ie" target="_blank">Microsoft Internet Explorer</a>. \
Your web browser does not appear to support WebGL, so you will see a limited, 2D-only experience.'
});
}
terria.viewerMode = ViewerMode.Leaflet;
}
//TODO: perf test to set environment
this.terria = terria;
var useCesium = terria.viewerMode !== ViewerMode.Leaflet;
terria.analytics.logEvent('startup', 'initialViewer', useCesium ? 'cesium' : 'leaflet');
/** A terrain provider used when ViewerMode === ViewerMode.CesiumTerrain */
this._bumpyTerrainProvider = undefined;
/** The terrain provider currently being used - can be either a bumpy terrain provider or a smooth EllipsoidTerrainProvider */
this._terrain = options.terrain;
this._terrainProvider = undefined;
if (defined(this._terrain) && this._terrain.length === 0) {
this._terrain = undefined;
}
if (this._useWebGL) {
initializeTerrainProvider(this);
}
this.selectViewer(useCesium);
this.observeSubscriptions = [];
this.observeSubscriptions.push(knockout.getObservable(this.terria, 'viewerMode').subscribe(function() {
changeViewer(this);
}, this));
this._previousBaseMap = this.terria.baseMap;
this.observeSubscriptions.push(knockout.getObservable(this.terria, 'baseMap').subscribe(function() {
changeBaseMap(this, this.terria.baseMap);
}, this));
this.observeSubscriptions.push(knockout.getObservable(this.terria, 'fogSettings').subscribe(function() {
changeFogSettings(this);
}, this));
this.observeSubscriptions.push(knockout.getObservable(this.terria, 'selectBox').subscribe(function() {
changeSelectBox(this);
}, this));
};
TerriaViewer.create = function(terria, options) {
return new TerriaViewer(terria, options);
};
function changeSelectBox(viewer) {
var terria = viewer.terria;
var selectBox = terria.selectBox;
if (terria.viewerMode === ViewerMode.Leaflet) {
if (selectBox) {
terria.leaflet.map.dragBox.enable();
} else {
terria.leaflet.map.dragBox.disable();
}
} else {
if (selectBox) {
// Add and start a DrawExtentHelper - used by mapInteractionMode with drawRectangle
viewer._enableSelectExtent(terria.cesium.viewer.scene, false);
viewer.dragBox = new DrawExtentHelper(terria, terria.cesium.viewer.scene,
function(ext) {
var mapInteractionModeStack = this.terria.mapInteractionModeStack;
if (defined(mapInteractionModeStack) && mapInteractionModeStack.length > 0) {
if (mapInteractionModeStack[mapInteractionModeStack.length - 1].drawRectangle) {
mapInteractionModeStack[mapInteractionModeStack.length - 1].pickedFeatures = clone(ext, true);
}
}
}.bind(viewer), KeyboardEventModifier.SHIFT);
viewer.dragBox.start();
} else {
viewer.dragBox.destroy();
viewer._enableSelectExtent(terria.cesium.viewer.scene, true);
}
}
}
function changeViewer(viewer) {
var terria = viewer.terria;
var newMode = terria.viewerMode;
if (newMode === ViewerMode.Leaflet) {
if (!terria.leaflet) {
terria.analytics.logEvent('mapSettings', 'switchViewer', '2D');
viewer.selectViewer(false);
}
} else {
if (!viewer._useWebGL) {
terria.error.raiseEvent({
title : 'WebGL not supported or too slow',
message : '\
Your web browser cannot display the map in 3D, either because it does not support WebGL or because your web browser has reported that WebGL will be extremely slow. \
Please try a different web browser, such as the latest version of <a href="http://www.google.com/chrome" target="_blank">Google Chrome</a>, \
<a href="http://www.mozilla.org/firefox" target="_blank">Mozilla Firefox</a>, \
<a href="https://www.apple.com/au/osx/how-to-upgrade/" target="_blank">Apple Safari</a>, or \
<a href="http://www.microsoft.com/ie" target="_blank">Microsoft Internet Explorer</a>. In some cases, you may need to \
upgrade your computer\'s video driver or operating system in order to get the 3D view in ' + terria.appName + '.'
});
terria.viewerMode = ViewerMode.Leaflet;
} else {
if (newMode === ViewerMode.CesiumTerrain) {
terria.analytics.logEvent('mapSettings', 'switchViewer', '3D');
if (defined(terria.leaflet)) {
viewer.selectViewer(true);
} else {
terria.cesium.scene.globe.terrainProvider = viewer._bumpyTerrainProvider;
CreditDisplay._cesiumCredit = viewer._bumpyTerrainCredit;
}
} else if (newMode === ViewerMode.CesiumEllipsoid) {
terria.analytics.logEvent('mapSettings', 'switchViewer', 'Smooth 3D');
if (defined(terria.leaflet)) {
viewer.selectViewer(true);
} else {
terria.cesium.scene.globe.terrainProvider = new EllipsoidTerrainProvider();
CreditDisplay._cesiumCredit = undefined;
}
}
}
}
}
function changeBaseMap(viewer, newBaseMap) {
if (defined(viewer._previousBaseMap)) {
viewer._previousBaseMap._hide();
viewer._previousBaseMap._disable();
}
if (defined(newBaseMap)) {
newBaseMap._enable();
newBaseMap._show();
if (defined(viewer.terria.currentViewer)) {
viewer.terria.currentViewer.lowerToBottom(newBaseMap);
}
}
viewer._previousBaseMap = newBaseMap;
if (defined(viewer.terria.currentViewer)) {
viewer.terria.currentViewer.notifyRepaintRequired();
}
}
function changeFogSettings(viewer) {
if (defined(viewer.terria.fogSettings) && defined(viewer.terria.cesium)) {
var fogSettings = viewer.terria.fogSettings;
for (var settingKey in fogSettings) {
if (viewer.terria.cesium.scene.fog.hasOwnProperty(settingKey)) {
viewer.terria.cesium.scene.fog[settingKey] = fogSettings[settingKey];
}
}
}
}
// -------------------------------------------
// Region Selection
// -------------------------------------------
TerriaViewer.prototype._enableSelectExtent = function(scene, bActive) {
if (bActive) {
var that = this;
this.regionSelect = new DrawExtentHelper(that.terria, scene, function (ext) {
if (ext) {
that.terria.currentViewer.zoomTo(ext, 2.0);
}
});
this.regionSelect.start();
}
else {
this.regionSelect.destroy();
}
};
TerriaViewer.prototype._createCesiumViewer = function(container, CesiumWidget) {
var that = this;
initializeTerrainProvider(this);
var terrainProvider = that._terrainProvider;
//An arbitrary base64 encoded image used to populate the placeholder SingleTileImageryProvider
var img = 'data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA \
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO \
9TXL0Y4OHwAAAABJRU5ErkJggg==';
var options = {
dataSources: this.terria.dataSources,
clock: this.terria.clock,
terrainProvider : terrainProvider,
imageryProvider : new SingleTileImageryProvider({ url: img }),
scene3DOnly: true
};
// Workaround for Firefox bug with WebGL and printing:
// https://bugzilla.mozilla.org/show_bug.cgi?id=976173
if (FeatureDetection.isFirefox()) {
options.contextOptions = {webgl : {preserveDrawingBuffer : true}};
}
//create CesiumViewer
var viewer = new CesiumWidget(container, options);
viewer.scene.imageryLayers.removeAll();
//catch Cesium terrain provider down and switch to Ellipsoid
terrainProvider.errorEvent.addEventListener(function(err) {
console.log('Terrain provider error. ', err.message);
if (viewer.scene.terrainProvider instanceof CesiumTerrainProvider) {
console.log('Switching to EllipsoidTerrainProvider.');
that.terria.viewerMode = ViewerMode.CesiumEllipsoid;
if (!defined(that.TerrainMessageViewed)) {
that.terria.error.raiseEvent({
title : 'Terrain Server Not Responding',
message : '\
The terrain server is not responding at the moment. You can still use all the features of '+that.terria.appName+' \
but there will be no terrain detail in 3D mode. We\'re sorry for the inconvenience. Please try \
again later and the terrain server should be responding as expected. If the issue persists, please contact \
us via email at '+that.terria.supportEmail+'.'
});
that.TerrainMessageViewed = true;
}
}
});
var scene = viewer.scene;
scene.globe.depthTestAgainstTerrain = false;
var d = this._getDisclaimer();
if (d) {
scene.frameState.creditDisplay.addDefaultCredit(d);
}
if (defined(this._developerAttribution)) {
scene.frameState.creditDisplay.addDefaultCredit(createCredit(this._developerAttribution.text, this._developerAttribution.link));
}
scene.frameState.creditDisplay.addDefaultCredit(new Credit('<a href="http://cesiumjs.org" target="_blank">CESIUM</a>'));
var inputHandler = viewer.screenSpaceEventHandler;
// Add double click zoom
inputHandler.setInputAction(
function (movement) {
zoomIn(scene, movement.position);
},
ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
inputHandler.setInputAction(
function (movement) {
zoomOut(scene, movement.position);
},
ScreenSpaceEventType.LEFT_DOUBLE_CLICK, KeyboardEventModifier.SHIFT);
return viewer;
};
TerriaViewer.prototype.destroy = function () {
this.terria.beforeViewerChanged.raiseEvent();
changeBaseMap(this, undefined);
this.observeSubscriptions.forEach(subscription => subscription.dispose());
if (defined(this.terria.cesium)) {
this.destroyCesium();
} else if (defined(this.terria.leaflet)) {//
this.destroyLeaflet();
}
this.terria.currentViewer = new NoViewer(this.terria);
this.terria.afterViewerChanged.raiseEvent();
};
TerriaViewer.prototype.destroyCesium = function () {
const viewer = this.terria.cesium.viewer;
this.terria.cesium.destroy();
if (this.cesiumEventHelper) {
this.cesiumEventHelper.removeAll();
this.cesiumEventHelper = undefined;
}
this.dataSourceDisplay.destroy();//
this._enableSelectExtent(viewer.scene, false);
var inputHandler = viewer.screenSpaceEventHandler;
inputHandler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
inputHandler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
inputHandler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK, KeyboardEventModifier.SHIFT);
if (defined(this.monitor)) {
this.monitor.destroy();
this.monitor = undefined;
}
viewer.destroy();
this.terria.cesium = undefined;
};
TerriaViewer.prototype.destroyLeaflet = function() {
const map = this.terria.leaflet.map;
this.terria.leaflet.destroy();
if (this.leafletEventHelper) {
this.leafletEventHelper.removeAll();
this.leafletEventHelper = undefined;
}
this.dataSourceDisplay.destroy();
map.remove();
this.terria.leaflet = undefined;
};
TerriaViewer.prototype.selectViewer = function(cesium) {
changeBaseMap(this, undefined);
this.terria.beforeViewerChanged.raiseEvent();
var that = this;
var createViewerPromise = cesium ? this.selectCesium() : this.selectLeaflet();
createViewerPromise.then(function() {
that.terria.afterViewerChanged.raiseEvent();
changeBaseMap(that, that.terria.baseMap);
});
};
TerriaViewer.prototype.selectLeaflet = function() {
var map, rect, eventHelper;
//shut down existing cesium
if (defined(this.terria.cesium)) {
//get camera and timeline settings
try {
rect = this.terria.cesium.getCurrentExtent();
} catch (e) {
console.log('Using default screen extent', e.message);
rect = this.terria.initialView;
}
this.destroyCesium();
}
else {
rect = this.terria.initialView;
}
//create leaflet viewer
map = L.map(this._mapContainer, {
zoomControl: false,
attributionControl: false,
maxZoom: this.maximumLeafletZoomLevel,
zoomSnap: 1, // Change to 0.2 for incremental zoom when Chrome fixes canvas scaling gaps
preferCanvas: true,
worldCopyJump: true
}).setView([-28.5, 135], 5);
map.attributionControl = L.control.attribution({
position: 'bottomleft'
});
map.addControl(map.attributionControl);
map.screenSpaceEventHandler = {
setInputAction : function() {},
remoteInputAction : function() {}
};
map.destroy = function() {};
var leaflet = new Leaflet(this.terria, map);
if (!defined(this.leafletVisualizer)) {
this.leafletVisualizer = new LeafletVisualizer();
}
var d = this._getDisclaimer();
if (d) {
map.attributionControl.setPrefix(d.element.outerHTML +
(this._developerAttribution && this._developerAttribution.link ? '<a target="_blank" href="' + this._developerAttribution.link + '">' : '') +
(this._developerAttribution ? this._developerAttribution.text : '') +
(this._developerAttribution && this._developerAttribution.link ? '</a>' : '') +
(this._developerAttribution ? ' | ' : '') +
'<a target="_blank" href="http://leafletjs.com/">Leaflet</a>' // partially to avoid a dangling leading comma issue
);
}
map.on("boxzoomend", function(e) {
console.log(e.boxZoomBounds);
});
this.terria.leaflet = leaflet;
this.terria.currentViewer = this.terria.leaflet;
this.dataSourceDisplay = new LeafletDataSourceDisplay({
scene : leaflet.scene,
dataSourceCollection : this.terria.dataSources,
visualizersCallback: this.leafletVisualizer.visualizersCallback
});
eventHelper = new EventHelper();
var that = this;
eventHelper.add(that.terria.clock.onTick, function(clock) {
that.dataSourceDisplay.update(clock.currentTime);
});
this.leafletEventHelper = eventHelper;
var ticker = function() {
if (defined(that.terria.leaflet)) {
that.terria.clock.tick();
cesiumRequestAnimationFrame(ticker);
}
};
ticker();
this.terria.leaflet.zoomTo(rect, 0.0);
return when();
};
TerriaViewer.prototype.selectCesium = function() {
var deferred = when.defer();
var that = this;
require.ensure([
'terriajs-cesium/Source/Widgets/CesiumWidget/CesiumWidget',
'terriajs-cesium/Source/DataSources/DataSourceDisplay',
'../Models/Cesium'
], function() {
var CesiumWidget = require('terriajs-cesium/Source/Widgets/CesiumWidget/CesiumWidget');
var DataSourceDisplay = require('terriajs-cesium/Source/DataSources/DataSourceDisplay');
var Cesium = require('../Models/Cesium');
var viewer, rect, eventHelper;
if (defined(that.terria.leaflet)) {
rect = that.terria.leaflet.getCurrentExtent();
that.destroyLeaflet();
}
//create Cesium viewer
viewer = that._createCesiumViewer(that._mapContainer, CesiumWidget);
that._enableSelectExtent(viewer.scene, true);
that.terria.cesium = new Cesium(that.terria, viewer);
that.terria.currentViewer = that.terria.cesium;
changeFogSettings(that);
//Simple monitor to start up and switch to 2D if seem to be stuck.
if (!defined(that.checkedStartupPerformance)) {
that.checkedStartupPerformance = true;
var uri = new URI(window.location);
var params = uri.search(true);
var frameRate = (defined(params.fps)) ? params.fps : 5;
that.monitor = new FrameRateMonitor({
scene: viewer.scene,
minimumFrameRateDuringWarmup: frameRate,
minimumFrameRateAfterWarmup: 0,
samplingWindow: 2
});
that.monitor.lowFrameRate.addEventListener( function() {
if (!that.terria.cesium.stoppedRendering) {
that.terria.error.raiseEvent({
title : 'Unusually Slow Performance Detected',
message : 'It appears that your system is capable of running ' + that.terria.appName + ' \
in 3D mode, but is having significant performance issues. \
We are automatically switching to 2D mode to help resolve this issue. If you want to switch back to 3D mode you can select \
that option from the Maps button at the top of the screen.'
});
runLater(function() {
that.terria.viewerMode = ViewerMode.Leaflet;
});
}
});
}
eventHelper = new EventHelper();
eventHelper.add(that.terria.clock.onTick, function(clock) {
that.dataSourceDisplay.update(clock.currentTime);
});
that.cesiumEventHelper = eventHelper;
that.dataSourceDisplay = new DataSourceDisplay({
scene : viewer.scene,
dataSourceCollection : that.terria.dataSources
});
if (defined(rect)) {
that.terria.cesium.zoomTo(rect, 0.0);
} else {
that.terria.cesium.zoomTo(that.terria.initialView, 0.0);
}
deferred.resolve();
}, '3D');
return deferred.promise;
};
TerriaViewer.prototype._getDisclaimer = function() {
var d = this.terria.configParameters.disclaimer;
if (d) {
return createCredit(d.text, d.url);
} else {
return null;
}
};
// -------------------------------------------
// Camera management
// -------------------------------------------
function flyToPosition(scene, position, durationMilliseconds) {
var camera = scene.camera;
var startPosition = camera.position;
var endPosition = position;
durationMilliseconds = defaultValue(durationMilliseconds, 200);
var initialEnuToFixed = Transforms.eastNorthUpToFixedFrame(startPosition, Ellipsoid.WGS84);
var initialEnuToFixedRotation = new Matrix4();
Matrix4.getRotation(initialEnuToFixed, initialEnuToFixedRotation);
var initialFixedToEnuRotation = new Matrix3();
Matrix3.transpose(initialEnuToFixedRotation, initialFixedToEnuRotation);
var initialEnuUp = new Matrix3();
Matrix3.multiplyByVector(initialFixedToEnuRotation, camera.up, initialEnuUp);
var initialEnuRight = new Matrix3();
Matrix3.multiplyByVector(initialFixedToEnuRotation, camera.right, initialEnuRight);
var initialEnuDirection = new Matrix3();
Matrix3.multiplyByVector(initialFixedToEnuRotation, camera.direction, initialEnuDirection);
var controller = scene.screenSpaceCameraController;
controller.enableInputs = false;
scene.tweens.add({
duration : durationMilliseconds / 1000.0,
easingFunction : Tween.Easing.Sinusoidal.InOut,
startObject : {
time: 0.0
},
stopObject : {
time : 1.0
},
update : function(value) {
scene.camera.position.x = CesiumMath.lerp(startPosition.x, endPosition.x, value.time);
scene.camera.position.y = CesiumMath.lerp(startPosition.y, endPosition.y, value.time);
scene.camera.position.z = CesiumMath.lerp(startPosition.z, endPosition.z, value.time);
var enuToFixed = Transforms.eastNorthUpToFixedFrame(camera.position, Ellipsoid.WGS84);
var enuToFixedRotation = new Matrix3();
Matrix4.getRotation(enuToFixed, enuToFixedRotation);
camera.up = Matrix3.multiplyByVector(enuToFixedRotation, initialEnuUp, camera.up);
camera.right = Matrix3.multiplyByVector(enuToFixedRotation, initialEnuRight, camera.right);
camera.direction = Matrix3.multiplyByVector(enuToFixedRotation, initialEnuDirection, camera.direction);
},
complete : function() {
controller.enableInputs = true;
},
cancel: function() {
controller.enableInputs = true;
}
});
}
var destinationScratch = new Cartesian3();
function zoomCamera(scene, distFactor, pos) {
var camera = scene.camera;
var pickRay = camera.getPickRay(pos);
var targetCartesian = scene.globe.pick(pickRay, scene);
if (targetCartesian) {
// Zoom to the picked latitude/longitude, at a distFactor multiple
// of the height.
var destination = Cartesian3.lerp(camera.position, targetCartesian, distFactor, destinationScratch);
flyToPosition(scene, destination);
}
}
function zoomIn(scene, pos) { zoomCamera(scene, 2.0/3.0, pos); }
function zoomOut(scene, pos) { zoomCamera(scene, -2.0, pos); }
function initializeTerrainProvider(terriaViewer) {
if (defined(terriaViewer._terrainProvider)) {
return;
}
if (terriaViewer.terria.configParameters.cesiumIonAccessToken) {
Ion.defaultAccessToken = terriaViewer.terria.configParameters.cesiumIonAccessToken;
}
if (terriaViewer.terria.configParameters.useCesiumIonTerrain) {
terriaViewer._bumpyTerrainProvider = createWorldTerrain();
const logo = require('terriajs-cesium/Source/Assets/Images/ion-credit.png');
terriaViewer._bumpyTerrainCredit = new Credit('<a href="https://cesium.com/" target="_blank"><img src="' + logo + '" title="Cesium ion"/></a>', true);
} else if (typeof terriaViewer._terrain === 'string' || terriaViewer._terrain instanceof String) {
terriaViewer._bumpyTerrainProvider = new CesiumTerrainProvider({
url: terriaViewer._terrain
});
terriaViewer._bumpyTerrainCredit = undefined;
} else if (defined(terriaViewer._terrain)) {
terriaViewer._bumpyTerrainProvider = terriaViewer._terrain;
terriaViewer._bumpyTerrainCredit = undefined;
} else {
terriaViewer._bumpyTerrainProvider = new EllipsoidTerrainProvider();
terriaViewer._bumpyTerrainCredit = undefined;
}
var terria = terriaViewer.terria;
if (terria.viewerMode === ViewerMode.CesiumTerrain) {
terriaViewer._terrainProvider = terriaViewer._bumpyTerrainProvider;
CreditDisplay._cesiumCredit = terriaViewer._bumpyTerrainCredit;
} else if (terria.viewerMode === ViewerMode.CesiumEllipsoid) {
terriaViewer._terrainProvider = new EllipsoidTerrainProvider();
CreditDisplay._cesiumCredit = undefined;
}
}
module.exports = TerriaViewer;