terriajs
Version:
Geospatial data visualization platform.
169 lines (142 loc) • 6.55 kB
JavaScript
/*global require*/
"use strict";
var CallbackProperty = require('terriajs-cesium/Source/DataSources/CallbackProperty');
var CesiumMath = require('terriajs-cesium/Source/Core/Math');
var Color = require('terriajs-cesium/Source/Core/Color');
var CustomDataSource = require('terriajs-cesium/Source/DataSources/CustomDataSource');
var defaultValue = require('terriajs-cesium/Source/Core/defaultValue');
var defined = require('terriajs-cesium/Source/Core/defined');
var KeyboardEventModifier = require('terriajs-cesium/Source/Core/KeyboardEventModifier');
var Rectangle = require('terriajs-cesium/Source/Core/Rectangle');
var ScreenSpaceEventHandler = require('terriajs-cesium/Source/Core/ScreenSpaceEventHandler');
var ScreenSpaceEventType = require('terriajs-cesium/Source/Core/ScreenSpaceEventType');
// -------------------------------------------
// DrawExtentHelper from the cesium sample code
// modified to be available with a keyboard modifier
// on left-click - default is SHIFT
// -------------------------------------------
var DrawExtentHelper = function (terria, scene, handler, keyboardModifier) {
this._terria = terria;
this._scene = scene;
this._ellipsoid = scene.globe.ellipsoid;
this._finishHandler = handler;
this._mouseHandler = new ScreenSpaceEventHandler(scene.canvas, false);
this._stopHandler = undefined;
this._interHandler = undefined;
this._dataSource = undefined;
this._click1 = undefined;
this._click2 = undefined;
this.active = false;
this.keyboardModifier = defaultValue(keyboardModifier, KeyboardEventModifier.SHIFT);
};
DrawExtentHelper.prototype.enableInput = function () {
var controller = this._scene.screenSpaceCameraController;
controller.enableInputs = true;
};
DrawExtentHelper.prototype.disableInput = function () {
var controller = this._scene.screenSpaceCameraController;
controller.enableInputs = false;
};
DrawExtentHelper.prototype.getExtent = function (mn, mx) {
// Re-order south < north
var south = Math.min(mn.latitude, mx.latitude);
var north = Math.max(mn.latitude, mx.latitude);
var west = Math.min(mn.longitude, mx.longitude);
var east = Math.max(mn.longitude, mx.longitude);
// If east-west is more than half the world, flip them.
if (east - west > Math.PI) {
west = Math.max(mn.longitude, mx.longitude);
east = Math.min(mn.longitude, mx.longitude);
}
// Check for approx equal (shouldn't require abs due to re-order)
var epsilon = CesiumMath.EPSILON6;
if (Math.abs(east - west) < epsilon) {
east += epsilon * 2.0;
}
if (Math.abs(north - south) < epsilon) {
north += epsilon * 2.0;
}
return new Rectangle(west, south, east, north);
};
DrawExtentHelper.prototype.handleRegionStop = function (movement) {
if (defined(this._dataSource)) {
this._terria.dataSources.remove(this._dataSource, true);
this._dataSource = undefined;
}
this._mouseHandler.removeInputAction(ScreenSpaceEventType.LEFT_UP, this.keyboardModifier);
this._mouseHandler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE, this.keyboardModifier);
this._mouseHandler.removeInputAction(ScreenSpaceEventType.LEFT_UP);
this._mouseHandler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
this.enableInput();
var ext;
if (movement) {
var pickRay = this._scene.camera.getPickRay(movement.position);
var cartesian = this._scene.globe.pick(pickRay, this._scene);
if (cartesian) {
this._click2 = this._ellipsoid.cartesianToCartographic(cartesian);
}
ext = this.getExtent(this._click1, this._click2);
}
this._scene.primitives.remove(this._extentPrimitive);
this.active = false;
this._finishHandler(ext);
};
DrawExtentHelper.prototype.handleRegionInter = function (movement) {
var pickRay = this._scene.camera.getPickRay(movement.endPosition);
var cartesian = this._scene.globe.pick(pickRay, this._scene);
if (cartesian) {
var cartographic = this._ellipsoid.cartesianToCartographic(cartesian);
this._click2 = cartographic;
}
};
DrawExtentHelper.prototype.handleRegionStart = function (movement) {
var pickRay = this._scene.camera.getPickRay(movement.position);
var cartesian = this._scene.globe.pick(pickRay, this._scene);
if (cartesian) {
this.disableInput();
this.active = true;
if (!defined(this._dataSource)) {
var that = this;
this._click1 = undefined;
this._click2 = undefined;
this._dataSource = new CustomDataSource('Draw Extent');
this._dataSource.entities.add({
name: 'Extent',
rectangle: {
coordinates: new CallbackProperty(function(date, result) {
if (defined(that._click1) && defined(that._click2)) {
return that.getExtent(that._click1, that._click2);
}
}, false),
material: new Color(1.0, 1.0, 1.0, 0.5)
}
});
this._terria.dataSources.add(this._dataSource);
}
this._click1 = this._ellipsoid.cartesianToCartographic(cartesian);
this._mouseHandler.setInputAction(function (movement) {
that.handleRegionStop(movement);
}, ScreenSpaceEventType.LEFT_UP, this.keyboardModifier);
this._mouseHandler.setInputAction(function (movement) {
that.handleRegionInter(movement);
}, ScreenSpaceEventType.MOUSE_MOVE, this.keyboardModifier);
this._mouseHandler.setInputAction(function (movement) {
that.handleRegionStop(movement);
}, ScreenSpaceEventType.LEFT_UP);
this._mouseHandler.setInputAction(function (movement) {
that.handleRegionInter(movement);
}, ScreenSpaceEventType.MOUSE_MOVE);
}
};
DrawExtentHelper.prototype.start = function () {
var that = this;
// Now wait for start
this._mouseHandler.setInputAction(function (movement) {
that.handleRegionStart(movement);
}, ScreenSpaceEventType.LEFT_DOWN, this.keyboardModifier);
};
DrawExtentHelper.prototype.destroy = function () {
this._mouseHandler.destroy();
this._scene = undefined;
};
module.exports = DrawExtentHelper;