UNPKG

ol-cesium

Version:

OpenLayers Cesium integration library

1,568 lines (1,317 loc) 207 kB
var olcs_unused_var = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./src/index.library.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./src/index.library.js": /*!******************************!*\ !*** ./src/index.library.js ***! \******************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var _olcs_OLCesium_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./olcs/OLCesium.js */ "./src/olcs/OLCesium.js"); /* harmony import */ var _olcs_AbstractSynchronizer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./olcs/AbstractSynchronizer.js */ "./src/olcs/AbstractSynchronizer.js"); /* harmony import */ var _olcs_RasterSynchronizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./olcs/RasterSynchronizer.js */ "./src/olcs/RasterSynchronizer.js"); /* harmony import */ var _olcs_VectorSynchronizer_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./olcs/VectorSynchronizer.js */ "./src/olcs/VectorSynchronizer.js"); /* harmony import */ var _olcs_core_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./olcs/core.js */ "./src/olcs/core.js"); /* harmony import */ var _olcs_core_OLImageryProvider_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./olcs/core/OLImageryProvider.js */ "./src/olcs/core/OLImageryProvider.js"); /* harmony import */ var _olcs_core_VectorLayerCounterpart_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./olcs/core/VectorLayerCounterpart.js */ "./src/olcs/core/VectorLayerCounterpart.js"); /* harmony import */ var _olcs_contrib_LazyLoader_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./olcs/contrib/LazyLoader.js */ "./src/olcs/contrib/LazyLoader.js"); /* harmony import */ var _olcs_contrib_Manager_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./olcs/contrib/Manager.js */ "./src/olcs/contrib/Manager.js"); /* harmony default export */ __webpack_exports__["default"] = (_olcs_OLCesium_js__WEBPACK_IMPORTED_MODULE_0__["default"]); // Using var for phantomJS // eslint-disable-next-line no-var var olcs = window['olcs'] = {}; olcs.OLCesium = _olcs_OLCesium_js__WEBPACK_IMPORTED_MODULE_0__["default"]; olcs.AbstractSynchronizer = _olcs_AbstractSynchronizer_js__WEBPACK_IMPORTED_MODULE_1__["default"]; olcs.RasterSynchronizer = _olcs_RasterSynchronizer_js__WEBPACK_IMPORTED_MODULE_2__["default"]; olcs.VectorSynchronizer = _olcs_VectorSynchronizer_js__WEBPACK_IMPORTED_MODULE_3__["default"]; olcs.core = _olcs_core_js__WEBPACK_IMPORTED_MODULE_4__["default"]; olcs.core.OLImageryProvider = _olcs_core_OLImageryProvider_js__WEBPACK_IMPORTED_MODULE_5__["default"]; olcs.core.VectorLayerCounterpart = _olcs_core_VectorLayerCounterpart_js__WEBPACK_IMPORTED_MODULE_6__["default"]; olcs.contrib = {}; olcs.contrib.LazyLoader = _olcs_contrib_LazyLoader_js__WEBPACK_IMPORTED_MODULE_7__["default"]; olcs.contrib.Manager = _olcs_contrib_Manager_js__WEBPACK_IMPORTED_MODULE_8__["default"]; /***/ }), /***/ "./src/olcs/AbstractSynchronizer.js": /*!******************************************!*\ !*** ./src/olcs/AbstractSynchronizer.js ***! \******************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/Observable.js */ "ol/Observable.js"); /* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/layer/Group.js */ "ol/layer/Group.js"); /* harmony import */ var ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js"); /** * @module olcs.AbstractSynchronizer */ var AbstractSynchronizer = /*#__PURE__*/ function () { /** * @param {!ol.Map} map * @param {!Cesium.Scene} scene * @template T * @abstract * @api */ function AbstractSynchronizer(map, scene) { /** * @type {!ol.Map} * @protected */ this.map = map; /** * @type {ol.View} * @protected */ this.view = map.getView(); /** * @type {!Cesium.Scene} * @protected */ this.scene = scene; /** * @type {ol.Collection.<ol.layer.Base>} * @protected */ this.olLayers = map.getLayerGroup().getLayers(); /** * @type {ol.layer.Group} */ this.mapLayerGroup = map.getLayerGroup(); /** * Map of OpenLayers layer ids (from getUid) to the Cesium ImageryLayers. * Null value means, that we are unable to create equivalent layers. * @type {Object.<string, ?Array.<T>>} * @protected */ this.layerMap = {}; /** * Map of listen keys for OpenLayers layer layers ids (from getUid). * @type {!Object.<string, Array<ol.EventsKey>>} * @protected */ this.olLayerListenKeys = {}; /** * Map of listen keys for OpenLayers layer groups ids (from getUid). * @type {!Object.<string, !Array.<ol.EventsKey>>} * @private */ this.olGroupListenKeys_ = {}; } /** * Destroy all and perform complete synchronization of the layers. * @api */ var _proto = AbstractSynchronizer.prototype; _proto.synchronize = function synchronize() { this.destroyAll(); this.addLayers_(this.mapLayerGroup); } /** * Order counterparts using the same algorithm as the Openlayers renderer: * z-index then original sequence order. * @protected */ ; _proto.orderLayers = function orderLayers() {} // Ordering logics is handled in subclasses. /** * Add a layer hierarchy. * @param {ol.layer.Base} root * @private */ ; _proto.addLayers_ = function addLayers_(root) { var _this = this; /** @type {Array<import('olsc/core.js').LayerWithParents>} */ var fifo = [{ layer: root, parents: [] }]; var _loop = function _loop() { var olLayerWithParents = fifo.splice(0, 1)[0]; var olLayer = olLayerWithParents.layer; var olLayerId = Object(_util_js__WEBPACK_IMPORTED_MODULE_2__["getUid"])(olLayer).toString(); _this.olLayerListenKeys[olLayerId] = []; console.assert(!_this.layerMap[olLayerId]); var cesiumObjects = null; if (olLayer instanceof ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1___default.a) { _this.listenForGroupChanges_(olLayer); if (olLayer !== _this.mapLayerGroup) { cesiumObjects = _this.createSingleLayerCounterparts(olLayerWithParents); } if (!cesiumObjects) { olLayer.getLayers().forEach(function (l) { if (l) { var newOlLayerWithParents = { layer: l, parents: olLayer === _this.mapLayerGroup ? [] : [olLayerWithParents.layer].concat(olLayerWithParents.parents) }; fifo.push(newOlLayerWithParents); } }); } } else { cesiumObjects = _this.createSingleLayerCounterparts(olLayerWithParents); if (!cesiumObjects) { // keep an eye on the layers that once failed to be added (might work when the layer is updated) // for example when a source is set after the layer is added to the map var layerId = olLayerId; var layerWithParents = olLayerWithParents; var onLayerChange = function onLayerChange(e) { var cesiumObjs = _this.createSingleLayerCounterparts(layerWithParents); if (cesiumObjs) { // unsubscribe event listener layerWithParents.layer.un('change', onLayerChange); _this.addCesiumObjects_(cesiumObjs, layerId, layerWithParents.layer); _this.orderLayers(); } }; _this.olLayerListenKeys[olLayerId].push(Object(_util_js__WEBPACK_IMPORTED_MODULE_2__["olcsListen"])(layerWithParents.layer, 'change', onLayerChange)); } } // add Cesium layers if (cesiumObjects) { _this.addCesiumObjects_(cesiumObjects, olLayerId, olLayer); } }; while (fifo.length > 0) { _loop(); } this.orderLayers(); } /** * Add Cesium objects. * @param {Array.<T>} cesiumObjects * @param {string} layerId * @param {ol.layer.Base} layer * @private */ ; _proto.addCesiumObjects_ = function addCesiumObjects_(cesiumObjects, layerId, layer) { var _this2 = this; this.layerMap[layerId] = cesiumObjects; this.olLayerListenKeys[layerId].push(Object(_util_js__WEBPACK_IMPORTED_MODULE_2__["olcsListen"])(layer, 'change:zIndex', function () { return _this2.orderLayers(); })); cesiumObjects.forEach(function (cesiumObject) { _this2.addCesiumObject(cesiumObject); }); } /** * Remove and destroy a single layer. * @param {ol.layer.Layer} layer * @return {boolean} counterpart destroyed * @private */ ; _proto.removeAndDestroySingleLayer_ = function removeAndDestroySingleLayer_(layer) { var _this3 = this; var uid = Object(_util_js__WEBPACK_IMPORTED_MODULE_2__["getUid"])(layer).toString(); var counterparts = this.layerMap[uid]; if (!!counterparts) { counterparts.forEach(function (counterpart) { _this3.removeSingleCesiumObject(counterpart, false); _this3.destroyCesiumObject(counterpart); }); this.olLayerListenKeys[uid].forEach(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__["unByKey"]); delete this.olLayerListenKeys[uid]; } delete this.layerMap[uid]; return !!counterparts; } /** * Unlisten a single layer group. * @param {ol.layer.Group} group * @private */ ; _proto.unlistenSingleGroup_ = function unlistenSingleGroup_(group) { if (group === this.mapLayerGroup) { return; } var uid = Object(_util_js__WEBPACK_IMPORTED_MODULE_2__["getUid"])(group).toString(); var keys = this.olGroupListenKeys_[uid]; keys.forEach(function (key) { Object(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__["unByKey"])(key); }); delete this.olGroupListenKeys_[uid]; delete this.layerMap[uid]; } /** * Remove layer hierarchy. * @param {ol.layer.Base} root * @private */ ; _proto.removeLayer_ = function removeLayer_(root) { var _this4 = this; if (!!root) { (function () { var fifo = [root]; while (fifo.length > 0) { var olLayer = fifo.splice(0, 1)[0]; var done = _this4.removeAndDestroySingleLayer_(olLayer); if (olLayer instanceof ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1___default.a) { _this4.unlistenSingleGroup_(olLayer); if (!done) { // No counterpart for the group itself so removing // each of the child layers. olLayer.getLayers().forEach(function (l) { fifo.push(l); }); } } } })(); } } /** * Register listeners for single layer group change. * @param {ol.layer.Group} group * @private */ ; _proto.listenForGroupChanges_ = function listenForGroupChanges_(group) { var uuid = Object(_util_js__WEBPACK_IMPORTED_MODULE_2__["getUid"])(group).toString(); console.assert(this.olGroupListenKeys_[uuid] === undefined); var listenKeyArray = []; this.olGroupListenKeys_[uuid] = listenKeyArray; // only the keys that need to be relistened when collection changes var contentKeys = []; var listenAddRemove = function () { var _this5 = this; var collection = group.getLayers(); if (collection) { contentKeys = [collection.on('add', function (event) { _this5.addLayers_(event.element); }), collection.on('remove', function (event) { _this5.removeLayer_(event.element); })]; listenKeyArray.push.apply(listenKeyArray, contentKeys); } }.bind(this); listenAddRemove(); listenKeyArray.push(group.on('change:layers', function (e) { contentKeys.forEach(function (el) { var i = listenKeyArray.indexOf(el); if (i >= 0) { listenKeyArray.splice(i, 1); } Object(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__["unByKey"])(el); }); listenAddRemove(); })); } /** * Destroys all the created Cesium objects. * @protected */ ; _proto.destroyAll = function destroyAll() { this.removeAllCesiumObjects(true); // destroy var objKey; for (objKey in this.olGroupListenKeys_) { var keys = this.olGroupListenKeys_[objKey]; keys.forEach(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__["unByKey"]); } for (objKey in this.olLayerListenKeys) { this.olLayerListenKeys[objKey].forEach(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__["unByKey"]); } this.olGroupListenKeys_ = {}; this.olLayerListenKeys = {}; this.layerMap = {}; } /** * Adds a single Cesium object to the collection. * @param {!T} object * @abstract * @protected */ ; _proto.addCesiumObject = function addCesiumObject(object) {} /** * @param {!T} object * @abstract * @protected */ ; _proto.destroyCesiumObject = function destroyCesiumObject(object) {} /** * Remove single Cesium object from the collection. * @param {!T} object * @param {boolean} destroy * @abstract * @protected */ ; _proto.removeSingleCesiumObject = function removeSingleCesiumObject(object, destroy) {} /** * Remove all Cesium objects from the collection. * @param {boolean} destroy * @abstract * @protected */ ; _proto.removeAllCesiumObjects = function removeAllCesiumObjects(destroy) {} /** * @param {import('olsc/core.js').LayerWithParents} olLayerWithParents * @return {?Array.<T>} * @abstract * @protected */ ; _proto.createSingleLayerCounterparts = function createSingleLayerCounterparts(olLayerWithParents) {}; return AbstractSynchronizer; }(); /* harmony default export */ __webpack_exports__["default"] = (AbstractSynchronizer); /***/ }), /***/ "./src/olcs/AutoRenderLoop.js": /*!************************************!*\ !*** ./src/olcs/AutoRenderLoop.js ***! \************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /** * @module olcs.AutoRenderLoop */ var AutoRenderLoop = /*#__PURE__*/ function () { /** * @constructor * @param {olcs.OLCesium} ol3d */ function AutoRenderLoop(ol3d) { this.ol3d = ol3d; this.scene_ = ol3d.getCesiumScene(); this.canvas_ = this.scene_.canvas; this._boundNotifyRepaintRequired = this.notifyRepaintRequired.bind(this); this.repaintEventNames_ = ['mousemove', 'mousedown', 'mouseup', 'touchstart', 'touchend', 'touchmove', 'pointerdown', 'pointerup', 'pointermove', 'wheel']; this.enable(); } /** * Enable. */ var _proto = AutoRenderLoop.prototype; _proto.enable = function enable() { this.scene_.requestRenderMode = true; this.scene_.maximumRenderTimeChange = 1000; for (var _iterator = this.repaintEventNames_, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var repaintKey = _ref; this.canvas_.addEventListener(repaintKey, this._boundNotifyRepaintRequired, false); } window.addEventListener('resize', this._boundNotifyRepaintRequired, false); // Listen for changes on the layer group this.ol3d.getOlMap().getLayerGroup().on('change', this._boundNotifyRepaintRequired); } /** * Disable. */ ; _proto.disable = function disable() { for (var _iterator2 = this.repaintEventNames_, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { var _ref2; if (_isArray2) { if (_i2 >= _iterator2.length) break; _ref2 = _iterator2[_i2++]; } else { _i2 = _iterator2.next(); if (_i2.done) break; _ref2 = _i2.value; } var repaintKey = _ref2; this.canvas_.removeEventListener(repaintKey, this._boundNotifyRepaintRequired, false); } window.removeEventListener('resize', this._boundNotifyRepaintRequired, false); this.ol3d.getOlMap().getLayerGroup().un('change', this._boundNotifyRepaintRequired); this.scene_.requestRenderMode = false; } /** * Restart render loop. * Force a restart of the render loop. * @api */ ; _proto.restartRenderLoop = function restartRenderLoop() { this.notifyRepaintRequired(); }; _proto.notifyRepaintRequired = function notifyRepaintRequired() { this.scene_.requestRender(); }; return AutoRenderLoop; }(); /* harmony default export */ __webpack_exports__["default"] = (AutoRenderLoop); /***/ }), /***/ "./src/olcs/Camera.js": /*!****************************!*\ !*** ./src/olcs/Camera.js ***! \****************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/Observable.js */ "ol/Observable.js"); /* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math.js */ "./src/olcs/math.js"); /* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ol/proj.js */ "ol/proj.js"); /* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ol_proj_js__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./core.js */ "./src/olcs/core.js"); /** * @module olcs.Camera */ var Camera = /*#__PURE__*/ function () { /** * This object takes care of additional 3d-specific properties of the view and * ensures proper synchronization with the underlying raw Cesium.Camera object. * @param {!Cesium.Scene} scene * @param {!ol.Map} map * @api */ function Camera(scene, map) { var _this = this; /** * @type {!Cesium.Scene} * @private */ this.scene_ = scene; /** * @type {!Cesium.Camera} * @private */ this.cam_ = scene.camera; /** * @type {!ol.Map} * @private */ this.map_ = map; /** * @type {?ol.View} * @private */ this.view_ = null; /** * @type {?ol.EventsKey} * @private */ this.viewListenKey_ = null; /** * @type {!ol.TransformFunction} * @private */ this.toLonLat_ = Camera.identityProjection; /** * @type {!ol.TransformFunction} * @private */ this.fromLonLat_ = Camera.identityProjection; /** * 0 -- topdown, PI/2 -- the horizon * @type {number} * @private */ this.tilt_ = 0; /** * @type {number} * @private */ this.distance_ = 0; /** * @type {?Cesium.Matrix4} * @private */ this.lastCameraViewMatrix_ = null; /** * This is used to discard change events on view caused by updateView method. * @type {boolean} * @private */ this.viewUpdateInProgress_ = false; this.map_.on('change:view', function (e) { _this.setView_(_this.map_.getView()); }); this.setView_(this.map_.getView()); } /** * @param {Array.<number>} input Input coordinate array. * @param {Array.<number>=} opt_output Output array of coordinate values. * @param {number=} opt_dimension Dimension. * @return {Array.<number>} Input coordinate array (same array as input). */ Camera.identityProjection = function identityProjection(input, opt_output, opt_dimension) { var dim = opt_dimension || input.length; if (opt_output) { for (var i = 0; i < dim; ++i) { opt_output[i] = input[i]; } } return input; } /** * @param {?ol.View} view New view to use. * @private */ ; var _proto = Camera.prototype; _proto.setView_ = function setView_(view) { var _this2 = this; if (this.view_) { Object(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__["unByKey"])(this.viewListenKey_); this.viewListenKey_ = null; } this.view_ = view; if (view) { var toLonLat = Object(ol_proj_js__WEBPACK_IMPORTED_MODULE_2__["getTransform"])(view.getProjection(), 'EPSG:4326'); var fromLonLat = Object(ol_proj_js__WEBPACK_IMPORTED_MODULE_2__["getTransform"])('EPSG:4326', view.getProjection()); console.assert(toLonLat && fromLonLat); this.toLonLat_ = toLonLat; this.fromLonLat_ = fromLonLat; this.viewListenKey_ = view.on('propertychange', function (e) { return _this2.handleViewEvent_(e); }); this.readFromView(); } else { this.toLonLat_ = Camera.identityProjection; this.fromLonLat_ = Camera.identityProjection; } } /** * @param {?} e * @private */ ; _proto.handleViewEvent_ = function handleViewEvent_(e) { if (!this.viewUpdateInProgress_) { this.readFromView(); } } /** * @param {number} heading In radians. * @api */ ; _proto.setHeading = function setHeading(heading) { if (!this.view_) { return; } this.view_.setRotation(heading); } /** * @return {number|undefined} Heading in radians. * @api */ ; _proto.getHeading = function getHeading() { if (!this.view_) { return undefined; } var rotation = this.view_.getRotation(); return rotation || 0; } /** * @param {number} tilt In radians. * @api */ ; _proto.setTilt = function setTilt(tilt) { this.tilt_ = tilt; this.updateCamera_(); } /** * @return {number} Tilt in radians. * @api */ ; _proto.getTilt = function getTilt() { return this.tilt_; } /** * @param {number} distance In meters. * @api */ ; _proto.setDistance = function setDistance(distance) { this.distance_ = distance; this.updateCamera_(); this.updateView(); } /** * @return {number} Distance in meters. * @api */ ; _proto.getDistance = function getDistance() { return this.distance_; } /** * Shortcut for ol.View.setCenter(). * @param {!ol.Coordinate} center Same projection as the ol.View. * @api */ ; _proto.setCenter = function setCenter(center) { if (!this.view_) { return; } this.view_.setCenter(center); } /** * Shortcut for ol.View.getCenter(). * @return {ol.Coordinate|undefined} Same projection as the ol.View. * @api */ ; _proto.getCenter = function getCenter() { if (!this.view_) { return undefined; } return this.view_.getCenter(); } /** * Sets the position of the camera. * @param {!ol.Coordinate} position Same projection as the ol.View. * @api */ ; _proto.setPosition = function setPosition(position) { if (!this.toLonLat_) { return; } var ll = this.toLonLat_(position); console.assert(ll); var carto = new Cesium.Cartographic(Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toRadians"])(ll[0]), Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toRadians"])(ll[1]), this.getAltitude()); this.cam_.setView({ destination: Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto) }); this.updateView(); } /** * Calculates position under the camera. * @return {!ol.Coordinate|undefined} Same projection as the ol.View. * @api */ ; _proto.getPosition = function getPosition() { if (!this.fromLonLat_) { return undefined; } var carto = Cesium.Ellipsoid.WGS84.cartesianToCartographic(this.cam_.position); var pos = this.fromLonLat_([Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toDegrees"])(carto.longitude), Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toDegrees"])(carto.latitude)]); console.assert(pos); return pos; } /** * @param {number} altitude In meters. * @api */ ; _proto.setAltitude = function setAltitude(altitude) { var carto = Cesium.Ellipsoid.WGS84.cartesianToCartographic(this.cam_.position); carto.height = altitude; this.cam_.position = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto); this.updateView(); } /** * @return {number} Altitude in meters. * @api */ ; _proto.getAltitude = function getAltitude() { var carto = Cesium.Ellipsoid.WGS84.cartesianToCartographic(this.cam_.position); return carto.height; } /** * Updates the state of the underlying Cesium.Camera * according to the current values of the properties. * @private */ ; _proto.updateCamera_ = function updateCamera_() { if (!this.view_ || !this.toLonLat_) { return; } var center = this.view_.getCenter(); if (!center) { return; } var ll = this.toLonLat_(center); console.assert(ll); var carto = new Cesium.Cartographic(Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toRadians"])(ll[0]), Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toRadians"])(ll[1])); if (this.scene_.globe) { var height = this.scene_.globe.getHeight(carto); carto.height = height || 0; } var destination = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto); /** @type {Cesium.optionsOrientation} */ var orientation = { pitch: this.tilt_ - Cesium.Math.PI_OVER_TWO, heading: -this.view_.getRotation(), roll: undefined }; this.cam_.setView({ destination: destination, orientation: orientation }); this.cam_.moveBackward(this.distance_); this.checkCameraChange(true); } /** * Calculates the values of the properties from the current ol.View state. * @api */ ; _proto.readFromView = function readFromView() { if (!this.view_ || !this.toLonLat_) { return; } var center = this.view_.getCenter(); if (center === undefined || center === null) { return; } var ll = this.toLonLat_(center); console.assert(ll); var resolution = this.view_.getResolution(); this.distance_ = this.calcDistanceForResolution(resolution || 0, Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toRadians"])(ll[1])); this.updateCamera_(); } /** * Calculates the values of the properties from the current Cesium.Camera state. * Modifies the center, resolution and rotation properties of the view. * @api */ ; _proto.updateView = function updateView() { if (!this.view_ || !this.fromLonLat_) { return; } this.viewUpdateInProgress_ = true; // target & distance var ellipsoid = Cesium.Ellipsoid.WGS84; var scene = this.scene_; var target = _core_js__WEBPACK_IMPORTED_MODULE_3__["default"].pickCenterPoint(scene); var bestTarget = target; if (!bestTarget) { //TODO: how to handle this properly ? var globe = scene.globe; var carto = this.cam_.positionCartographic.clone(); var height = globe.getHeight(carto); carto.height = height || 0; bestTarget = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto); } this.distance_ = Cesium.Cartesian3.distance(bestTarget, this.cam_.position); var bestTargetCartographic = ellipsoid.cartesianToCartographic(bestTarget); this.view_.setCenter(this.fromLonLat_([Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toDegrees"])(bestTargetCartographic.longitude), Object(_math_js__WEBPACK_IMPORTED_MODULE_1__["toDegrees"])(bestTargetCartographic.latitude)])); // resolution this.view_.setResolution(this.calcResolutionForDistance(this.distance_, bestTargetCartographic ? bestTargetCartographic.latitude : 0)); /* * Since we are positioning the target, the values of heading and tilt * need to be calculated _at the target_. */ if (target) { var pos = this.cam_.position; // normal to the ellipsoid at the target var targetNormal = new Cesium.Cartesian3(); ellipsoid.geocentricSurfaceNormal(target, targetNormal); // vector from the target to the camera var targetToCamera = new Cesium.Cartesian3(); Cesium.Cartesian3.subtract(pos, target, targetToCamera); Cesium.Cartesian3.normalize(targetToCamera, targetToCamera); // HEADING var up = this.cam_.up; var right = this.cam_.right; var normal = new Cesium.Cartesian3(-target.y, target.x, 0); // what is it? var heading = Cesium.Cartesian3.angleBetween(right, normal); var cross = Cesium.Cartesian3.cross(target, up, new Cesium.Cartesian3()); var orientation = cross.z; this.view_.setRotation(orientation < 0 ? heading : -heading); // TILT var tiltAngle = Math.acos(Cesium.Cartesian3.dot(targetNormal, targetToCamera)); this.tilt_ = isNaN(tiltAngle) ? 0 : tiltAngle; } else { // fallback when there is no target this.view_.setRotation(this.cam_.heading); this.tilt_ = -this.cam_.pitch + Math.PI / 2; } this.viewUpdateInProgress_ = false; } /** * Check if the underlying camera state has changed and ensure synchronization. * @param {boolean=} opt_dontSync Do not synchronize the view. */ ; _proto.checkCameraChange = function checkCameraChange(opt_dontSync) { var old = this.lastCameraViewMatrix_; var current = this.cam_.viewMatrix; if (!old || !Cesium.Matrix4.equalsEpsilon(old, current, 1e-5)) { this.lastCameraViewMatrix_ = current.clone(); if (opt_dontSync !== true) { this.updateView(); } } } /** * calculate the distance between camera and centerpoint based on the resolution and latitude value * @param {number} resolution Number of map units per pixel. * @param {number} latitude Latitude in radians. * @return {number} The calculated distance. * @api */ ; _proto.calcDistanceForResolution = function calcDistanceForResolution(resolution, latitude) { var canvas = this.scene_.canvas; var fovy = this.cam_.frustum.fovy; // vertical field of view console.assert(!isNaN(fovy)); var metersPerUnit = this.view_.getProjection().getMetersPerUnit(); // number of "map units" visible in 2D (vertically) var visibleMapUnits = resolution * canvas.clientHeight; // The metersPerUnit does not take latitude into account, but it should // be lower with increasing latitude -- we have to compensate. // In 3D it is not possible to maintain the resolution at more than one point, // so it only makes sense to use the latitude of the "target" point. var relativeCircumference = Math.cos(Math.abs(latitude)); // how many meters should be visible in 3D var visibleMeters = visibleMapUnits * metersPerUnit * relativeCircumference; // distance required to view the calculated length in meters // // fovy/2 // |\ // x | \ // |--\ // visibleMeters/2 var requiredDistance = visibleMeters / 2 / Math.tan(fovy / 2); // NOTE: This calculation is not absolutely precise, because metersPerUnit // is a great simplification. It does not take ellipsoid/terrain into account. return requiredDistance; } /** * calculate the resolution based on a distance(camera to position) and latitude value * @param {number} distance * @param {number} latitude * @return {number} The calculated resolution. * @api */ ; _proto.calcResolutionForDistance = function calcResolutionForDistance(distance, latitude) { // See the reverse calculation (calcDistanceForResolution) for details var canvas = this.scene_.canvas; var fovy = this.cam_.frustum.fovy; var metersPerUnit = this.view_.getProjection().getMetersPerUnit(); var visibleMeters = 2 * distance * Math.tan(fovy / 2); var relativeCircumference = Math.cos(Math.abs(latitude)); var visibleMapUnits = visibleMeters / metersPerUnit / relativeCircumference; var resolution = visibleMapUnits / canvas.clientHeight; return resolution; }; return Camera; }(); /* harmony default export */ __webpack_exports__["default"] = (Camera); /***/ }), /***/ "./src/olcs/FeatureConverter.js": /*!**************************************!*\ !*** ./src/olcs/FeatureConverter.js ***! \**************************************/ /*! exports provided: default */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony import */ var ol_geom_Geometry_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/geom/Geometry.js */ "ol/geom/Geometry.js"); /* harmony import */ var ol_geom_Geometry_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_geom_Geometry_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var ol_style_Icon_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/style/Icon.js */ "ol/style/Icon.js"); /* harmony import */ var ol_style_Icon_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_style_Icon_js__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ol/source/Vector.js */ "ol/source/Vector.js"); /* harmony import */ var ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ol/source/Cluster.js */ "ol/source/Cluster.js"); /* harmony import */ var ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var ol_geom_Polygon_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ol/geom/Polygon.js */ "ol/geom/Polygon.js"); /* harmony import */ var ol_geom_Polygon_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(ol_geom_Polygon_js__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var ol_extent_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ol/extent.js */ "ol/extent.js"); /* harmony import */ var ol_extent_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(ol_extent_js__WEBPACK_IMPORTED_MODULE_5__); /* harmony import */ var ol_geom_SimpleGeometry_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ol/geom/SimpleGeometry.js */ "ol/geom/SimpleGeometry.js"); /* harmony import */ var ol_geom_SimpleGeometry_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(ol_geom_SimpleGeometry_js__WEBPACK_IMPORTED_MODULE_6__); /* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./core.js */ "./src/olcs/core.js"); /* harmony import */ var _core_VectorLayerCounterpart_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./core/VectorLayerCounterpart.js */ "./src/olcs/core/VectorLayerCounterpart.js"); /* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js"); /** * @module olcs.FeatureConverter */ /** * @typedef {Object} ModelStyle * @property {Cesium.Matrix4} [debugModelMatrix] * @property {Cesium.ModelFromGltfOptions} cesiumOptions */ var FeatureConverter = /*#__PURE__*/ function () { /** * Concrete base class for converting from OpenLayers3 vectors to Cesium * primitives. * Extending this class is possible provided that the extending class and * the library are compiled together by the closure compiler. * @param {!Cesium.Scene} scene Cesium scene. * @constructor * @api */ function FeatureConverter(scene) { /** * @protected */ this.scene = scene; /** * Bind once to have a unique function for using as a listener * @type {function(ol.source.Vector.Event)} * @private */ this.boundOnRemoveOrClearFeatureListener_ = this.onRemoveOrClearFeature_.bind(this); /** * @type {Cesium.Cartesian3} * @private */ this.defaultBillboardEyeOffset_ = new Cesium.Cartesian3(0, 0, 10); } /** * @param {ol.source.Vector.Event} evt * @private */ var _proto = FeatureConverter.prototype; _proto.onRemoveOrClearFeature_ = function onRemoveOrClearFeature_(evt) { var source = evt.target; console.assert(source instanceof ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_2___default.a); var cancellers = _util_js__WEBPACK_IMPORTED_MODULE_9__["default"].obj(source)['olcs_cancellers']; if (cancellers) { var feature = evt.feature; if (feature) { // remove var id = Object(_util_js__WEBPACK_IMPORTED_MODULE_9__["getUid"])(feature); var canceller = cancellers[id]; if (canceller) { canceller(); delete cancellers[id]; } } else { // clear for (var key in cancellers) { if (cancellers.hasOwnProperty(key)) { cancellers[key](); } } _util_js__WEBPACK_IMPORTED_MODULE_9__["default"].obj(source)['olcs_cancellers'] = {}; } } } /** * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature. * @param {!Cesium.Primitive|Cesium.Label|Cesium.Billboard} primitive * @protected */ ; _proto.setReferenceForPicking = function setReferenceForPicking(layer, feature, primitive) { primitive.olLayer = layer; primitive.olFeature = feature; } /** * Basics primitive creation using a color attribute. * Note that Cesium has 'interior' and outline geometries. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature. * @param {!ol.geom.Geometry} olGeometry OpenLayers geometry. * @param {!Cesium.Geometry} geometry * @param {!Cesium.Color} color * @param {number=} opt_lineWidth * @return {Cesium.Primitive} * @protected */ ; _proto.createColoredPrimitive = function createColoredPrimitive(layer, feature, olGeometry, geometry, color, opt_lineWidth) { var createInstance = function createInstance(geometry, color) { var instance = new Cesium.GeometryInstance({ // always update Cesium externs before adding a property geometry: geometry }); if (color && !(color instanceof Cesium.ImageMaterialProperty)) { instance.attributes = { color: Cesium.ColorGeometryInstanceAttribute.fromColor(color) }; } return instance; }; var options = { // always update Cesium externs before adding a property flat: true, // work with all geometries renderState: { depthTest: { enabled: true } } }; if (opt_lineWidth !== undefined) { if (!options.renderState) { options.renderState = {}; } options.renderState.lineWidth = opt_lineWidth; } var instances = createInstance(geometry, color); var heightReference = this.getHeightReference(layer, feature, olGeometry); var primitive; if (heightReference === Cesium.HeightReference.CLAMP_TO_GROUND) { var ctor = instances.geometry.constructor; if (ctor && !ctor['createShadowVolume']) { return null; } primitive = new Cesium.GroundPrimitive({ geometryInstances: instances }); } else { primitive = new Cesium.Primitive({ geometryInstances: instances }); } if (color instanceof Cesium.ImageMaterialProperty) { var dataUri = color.image.getValue().toDataURL(); primitive.appearance = new Cesium.MaterialAppearance({ flat: true, renderState: { depthTest: { enabled: true } }, material: new Cesium.Material({ fabric: { type: 'Image', uniforms: { image: dataUri } } }) }); } else { primitive.appearance = new Cesium.PerInstanceColorAppearance(options); } this.setReferenceForPicking(layer, feature, primitive); return primitive; } /** * Return the fill or stroke color from a plain ol style. * @param {!ol.style.Style|ol.style.Text} style * @param {boolean} outline * @return {!Cesium.Color} * @protected */ ; _proto.extractColorFromOlStyle = function extractColorFromOlStyle(style, outline) { var fillColor = style.getFill() ? style.getFill().getColor() : null; var strokeColor = style.getStroke() ? style.getStroke().getColor() : null; var olColor = 'black'; if (strokeColor && outline) { olColor = strokeColor; } else if (fillColor) { olColor = fillColor; } return _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].convertColorToCesium(olColor); } /** * Return the width of stroke from a plain ol style. * @param {!ol.style.Style|ol.style.Text} style * @return {number} * @protected */ ; _proto.extractLineWidthFromOlStyle = function extractLineWidthFromOlStyle(style) { // Handling of line width WebGL limitations is handled by Cesium. var width = style.getStroke() ? style.getStroke().getWidth() : undefined; return width !== undefined ? width : 1; } /** * Create a primitive collection out of two Cesium geometries. * Only the OpenLayers style colors will be used. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature. * @param {!ol.geom.Geometry} olGeometry OpenLayers geometry. * @param {!Cesium.Geometry} fillGeometry * @param {!Cesium.Geometry} outlineGeometry * @param {!ol.style.Style} olStyle * @return {!Cesium.PrimitiveCollection} * @protected */ ; _proto.wrapFillAndOutlineGeometries = function wrapFillAndOutlineGeometries(layer, feature, olGeometry, fillGeometry, outlineGeometry, olStyle) { var fillColor = this.extractColorFromOlStyle(olStyle, false); var outlineColor = this.extractColorFromOlStyle(olStyle, true); var primitives = new Cesium.PrimitiveCollection(); if (olStyle.getFill()) { var p1 = this.createColoredPrimitive(layer, feature, olGeometry, fillGeometry, fillColor); console.assert(!!p1); primitives.add(p1); } if (olStyle.getStroke() && outlineGeometry) { var width = this.extractLineWidthFromOlStyle(olStyle); var p2 = this.createColoredPrimitive(layer, feature, olGeometry, outlineGeometry, outlineColor, width); if (p2) { // Some outline geometries are not supported by Cesium in clamp to ground // mode. These primitives are skipped. primitives.add(p2); } } return primitives; } // Geometry converters /** * Create a Cesium primitive if style has a text component. * Eventually return a PrimitiveCollection including current primitive. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Geometry} geometry * @param {!ol.style.Style} style * @param {!Cesium.Primitive} primitive current primitive * @return {!Cesium.PrimitiveCollection} * @protected */ ; _proto.addTextStyle = function addTextStyle(layer, feature, geometry, style, primitive) { var primitives; if (!(primitive instanceof Cesium.PrimitiveCollection)) { primitives = new Cesium.PrimitiveCollection(); primitives.add(primitive); } else { primitives = primitive; } if (!style.getText()) { return primitives; } var text = /** @type {!ol.style.Text} */ style.getText(); var label = this.olGeometry4326TextPartToCesium(layer, feature, geometry, text); if (label) { primitives.add(label); } return primitives; } /** * Add a billboard to a Cesium.BillboardCollection. * Overriding this wrapper allows manipulating the billboard options. * @param {!Cesium.BillboardCollection} billboards * @param {!Cesium.optionsBillboardCollectionAdd} bbOptions * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature. * @param {!ol.geom.Geometry} geometry * @param {!ol.style.Style} style * @return {!Cesium.Billboard} newly created billboard * @api */ ; _proto.csAddBillboard = function csAddBillboard(billboards, bbOptions, layer, feature, geometry, style) { if (!bbOptions.eyeOffset) { bbOptions.eyeOffset = this.defaultBillboardEyeOffset_; } var bb = billboards.add(bbOptions); this.setReferenceForPicking(layer, feature, bb); return bb; } /** * Convert an OpenLayers circle geometry to Cesium. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Circle} olGeometry OpenLayers circle geometry. * @param {!ol.ProjectionLike} projection * @param {!ol.style.Style} olStyle * @return {!Cesium.PrimitiveCollection} primitives * @api */ ; _proto.olCircleGeometryToCesium = function olCircleGeometryToCesium(layer, feature, olGeometry, projection, olStyle) { var _this = this; olGeometry = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].olGeometryCloneTo4326(olGeometry, projection); console.assert(olGeometry.getType() == 'Circle'); // ol.Coordinate var center = olGeometry.getCenter(); var height = center.length == 3 ? center[2] : 0.0; var point =