|
|
var olcs_unused_var;/******/ (() => { // webpackBootstrap
/******/ "use strict";/******/ var __webpack_modules__ = ({
/***/ "./src/olcs/AbstractSynchronizer.js":/*!******************************************!*\ !*** ./src/olcs/AbstractSynchronizer.js ***! \******************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* 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 */
class AbstractSynchronizer { /** * @param {!ol.Map} map * @param {!Cesium.Scene} scene * @template T * @abstract * @api */ constructor(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 */ synchronize() { this.destroyAll(); this.addLayers_(this.mapLayerGroup); }
/** * Order counterparts using the same algorithm as the Openlayers renderer: * z-index then original sequence order. * @protected */ orderLayers() { // Ordering logics is handled in subclasses.
}
/** * Add a layer hierarchy. * @param {ol.layer.Base} root * @private */ addLayers_(root) { /** @type {Array<import('olsc/core.js').LayerWithParents>} */ const fifo = [{ layer: root, parents: [] }]; while (fifo.length > 0) { const olLayerWithParents = fifo.splice(0, 1)[0]; const olLayer = olLayerWithParents.layer; const olLayerId = (0,_util_js__WEBPACK_IMPORTED_MODULE_2__.getUid)(olLayer).toString(); this.olLayerListenKeys[olLayerId] = []; console.assert(!this.layerMap[olLayerId]);
let cesiumObjects = null; if (olLayer instanceof (ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1___default())) { this.listenForGroupChanges_(olLayer); if (olLayer !== this.mapLayerGroup) { cesiumObjects = this.createSingleLayerCounterparts(olLayerWithParents); } if (!cesiumObjects) { olLayer.getLayers().forEach((l) => { if (l) { const 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
const layerId = olLayerId; const layerWithParents = olLayerWithParents; const onLayerChange = (e) => { const 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((0,_util_js__WEBPACK_IMPORTED_MODULE_2__.olcsListen)(layerWithParents.layer, 'change', onLayerChange)); } } // add Cesium layers
if (cesiumObjects) { this.addCesiumObjects_(cesiumObjects, olLayerId, olLayer); } }
this.orderLayers(); }
/** * Add Cesium objects. * @param {Array.<T>} cesiumObjects * @param {string} layerId * @param {ol.layer.Base} layer * @private */ addCesiumObjects_(cesiumObjects, layerId, layer) { this.layerMap[layerId] = cesiumObjects; this.olLayerListenKeys[layerId].push((0,_util_js__WEBPACK_IMPORTED_MODULE_2__.olcsListen)(layer, 'change:zIndex', () => this.orderLayers())); cesiumObjects.forEach((cesiumObject) => { this.addCesiumObject(cesiumObject); }); }
/** * Remove and destroy a single layer. * @param {ol.layer.Layer} layer * @return {boolean} counterpart destroyed * @private */ removeAndDestroySingleLayer_(layer) { const uid = (0,_util_js__WEBPACK_IMPORTED_MODULE_2__.getUid)(layer).toString(); const counterparts = this.layerMap[uid]; if (!!counterparts) { counterparts.forEach((counterpart) => { this.removeSingleCesiumObject(counterpart, false); this.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 */ unlistenSingleGroup_(group) { if (group === this.mapLayerGroup) { return; } const uid = (0,_util_js__WEBPACK_IMPORTED_MODULE_2__.getUid)(group).toString(); const keys = this.olGroupListenKeys_[uid]; keys.forEach((key) => { (0,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 */ removeLayer_(root) { if (!!root) { const fifo = [root]; while (fifo.length > 0) { const olLayer = fifo.splice(0, 1)[0]; const done = this.removeAndDestroySingleLayer_(olLayer); if (olLayer instanceof (ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_1___default())) { this.unlistenSingleGroup_(olLayer); if (!done) { // No counterpart for the group itself so removing
// each of the child layers.
olLayer.getLayers().forEach((l) => { fifo.push(l); }); } } } } }
/** * Register listeners for single layer group change. * @param {ol.layer.Group} group * @private */ listenForGroupChanges_(group) { const uuid = (0,_util_js__WEBPACK_IMPORTED_MODULE_2__.getUid)(group).toString();
console.assert(this.olGroupListenKeys_[uuid] === undefined);
const listenKeyArray = []; this.olGroupListenKeys_[uuid] = listenKeyArray;
// only the keys that need to be relistened when collection changes
let contentKeys = []; const listenAddRemove = (function() { const collection = group.getLayers(); if (collection) { contentKeys = [ collection.on('add', (event) => { this.addLayers_(event.element); }), collection.on('remove', (event) => { this.removeLayer_(event.element); }) ]; listenKeyArray.push(...contentKeys); } }).bind(this);
listenAddRemove();
listenKeyArray.push(group.on('change:layers', (e) => { contentKeys.forEach((el) => { const i = listenKeyArray.indexOf(el); if (i >= 0) { listenKeyArray.splice(i, 1); } (0,ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__.unByKey)(el); }); listenAddRemove(); })); }
/** * Destroys all the created Cesium objects. * @protected */ destroyAll() { this.removeAllCesiumObjects(true); // destroy
let objKey; for (objKey in this.olGroupListenKeys_) { const 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 */ addCesiumObject(object) {}
/** * @param {!T} object * @abstract * @protected */ destroyCesiumObject(object) {}
/** * Remove single Cesium object from the collection. * @param {!T} object * @param {boolean} destroy * @abstract * @protected */ removeSingleCesiumObject(object, destroy) {}
/** * Remove all Cesium objects from the collection. * @param {boolean} destroy * @abstract * @protected */ removeAllCesiumObjects(destroy) {}
/** * @param {import('olsc/core.js').LayerWithParents} olLayerWithParents * @return {?Array.<T>} * @abstract * @protected */ createSingleLayerCounterparts(olLayerWithParents) {}}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AbstractSynchronizer);
/***/ }),
/***/ "./src/olcs/AutoRenderLoop.js":/*!************************************!*\ !*** ./src/olcs/AutoRenderLoop.js ***! \************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/** * @module olcs.AutoRenderLoop */
class AutoRenderLoop { /** * @constructor * @param {olcs.OLCesium} ol3d */ constructor(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. */ enable() { this.scene_.requestRenderMode = true; this.scene_.maximumRenderTimeChange = 1000; for (const repaintKey of this.repaintEventNames_) { 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. */ disable() { for (const repaintKey of this.repaintEventNames_) { 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 */ restartRenderLoop() { this.notifyRepaintRequired(); }
notifyRepaintRequired() { this.scene_.requestRender(); }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AutoRenderLoop);
/***/ }),
/***/ "./src/olcs/Camera.js":/*!****************************!*\ !*** ./src/olcs/Camera.js ***! \****************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* 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 */
class Camera { /** * 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 */ constructor(scene, map) { /** * @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', (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). */ static identityProjection(input, opt_output, opt_dimension) { const dim = opt_dimension || input.length; if (opt_output) { for (let i = 0; i < dim; ++i) { opt_output[i] = input[i]; } } return input; }
/** * @param {?ol.View} view New view to use. * @private */ setView_(view) { if (this.view_) { (0,ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__.unByKey)(this.viewListenKey_); this.viewListenKey_ = null; }
this.view_ = view; if (view) { const toLonLat = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_2__.getTransform)(view.getProjection(), 'EPSG:4326'); const fromLonLat = (0,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', e => this.handleViewEvent_(e));
this.readFromView(); } else { this.toLonLat_ = Camera.identityProjection; this.fromLonLat_ = Camera.identityProjection; } }
/** * @param {?} e * @private */ handleViewEvent_(e) { if (!this.viewUpdateInProgress_) { this.readFromView(); } }
/** * @param {number} heading In radians. * @api */ setHeading(heading) { if (!this.view_) { return; }
this.view_.setRotation(heading); }
/** * @return {number|undefined} Heading in radians. * @api */ getHeading() { if (!this.view_) { return undefined; } const rotation = this.view_.getRotation(); return rotation || 0; }
/** * @param {number} tilt In radians. * @api */ setTilt(tilt) { this.tilt_ = tilt; this.updateCamera_(); }
/** * @return {number} Tilt in radians. * @api */ getTilt() { return this.tilt_; }
/** * @param {number} distance In meters. * @api */ setDistance(distance) { this.distance_ = distance; this.updateCamera_(); this.updateView(); }
/** * @return {number} Distance in meters. * @api */ getDistance() { return this.distance_; }
/** * Shortcut for ol.View.setCenter(). * @param {!ol.Coordinate} center Same projection as the ol.View. * @api */ 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 */ 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 */ setPosition(position) { if (!this.toLonLat_) { return; } const ll = this.toLonLat_(position); console.assert(ll);
const carto = new Cesium.Cartographic( (0,_math_js__WEBPACK_IMPORTED_MODULE_1__.toRadians)(ll[0]), (0,_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 */ getPosition() { if (!this.fromLonLat_) { return undefined; } const carto = Cesium.Ellipsoid.WGS84.cartesianToCartographic(this.cam_.position);
const pos = this.fromLonLat_([ (0,_math_js__WEBPACK_IMPORTED_MODULE_1__.toDegrees)(carto.longitude), (0,_math_js__WEBPACK_IMPORTED_MODULE_1__.toDegrees)(carto.latitude) ]); console.assert(pos); return pos; }
/** * @param {number} altitude In meters. * @api */ setAltitude(altitude) { const 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 */ getAltitude() { const 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 */ updateCamera_() { if (!this.view_ || !this.toLonLat_) { return; } const center = this.view_.getCenter(); if (!center) { return; } const ll = this.toLonLat_(center); console.assert(ll);
const carto = new Cesium.Cartographic((0,_math_js__WEBPACK_IMPORTED_MODULE_1__.toRadians)(ll[0]), (0,_math_js__WEBPACK_IMPORTED_MODULE_1__.toRadians)(ll[1])); if (this.scene_.globe) { const height = this.scene_.globe.getHeight(carto); carto.height = height || 0; }
const destination = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto);
/** @type {Cesium.optionsOrientation} */ const orientation = { pitch: this.tilt_ - Cesium.Math.PI_OVER_TWO, heading: -this.view_.getRotation(), roll: undefined }; this.cam_.setView({ destination, orientation });
this.cam_.moveBackward(this.distance_);
this.checkCameraChange(true); }
/** * Calculates the values of the properties from the current ol.View state. * @api */ readFromView() { if (!this.view_ || !this.toLonLat_) { return; } const center = this.view_.getCenter(); if (center === undefined || center === null) { return; } const ll = this.toLonLat_(center); console.assert(ll);
const resolution = this.view_.getResolution(); this.distance_ = this.calcDistanceForResolution( resolution || 0, (0,_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 */ updateView() { if (!this.view_ || !this.fromLonLat_) { return; } this.viewUpdateInProgress_ = true;
// target & distance
const ellipsoid = Cesium.Ellipsoid.WGS84; const scene = this.scene_; const target = _core_js__WEBPACK_IMPORTED_MODULE_3__["default"].pickCenterPoint(scene);
let bestTarget = target; if (!bestTarget) { //TODO: how to handle this properly ?
const globe = scene.globe; const carto = this.cam_.positionCartographic.clone(); const height = globe.getHeight(carto); carto.height = height || 0; bestTarget = Cesium.Ellipsoid.WGS84.cartographicToCartesian(carto); } this.distance_ = Cesium.Cartesian3.distance(bestTarget, this.cam_.position); const bestTargetCartographic = ellipsoid.cartesianToCartographic(bestTarget); this.view_.setCenter(this.fromLonLat_([ (0,_math_js__WEBPACK_IMPORTED_MODULE_1__.toDegrees)(bestTargetCartographic.longitude), (0,_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) { const pos = this.cam_.position;
// normal to the ellipsoid at the target
const targetNormal = new Cesium.Cartesian3(); ellipsoid.geocentricSurfaceNormal(target, targetNormal);
// vector from the target to the camera
const targetToCamera = new Cesium.Cartesian3(); Cesium.Cartesian3.subtract(pos, target, targetToCamera); Cesium.Cartesian3.normalize(targetToCamera, targetToCamera);
// HEADING
const up = this.cam_.up; const right = this.cam_.right; const normal = new Cesium.Cartesian3(-target.y, target.x, 0); // what is it?
const heading = Cesium.Cartesian3.angleBetween(right, normal); const cross = Cesium.Cartesian3.cross(target, up, new Cesium.Cartesian3()); const orientation = cross.z;
this.view_.setRotation((orientation < 0 ? heading : -heading));
// TILT
const 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. */ checkCameraChange(opt_dontSync) { const old = this.lastCameraViewMatrix_; const 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 */ calcDistanceForResolution(resolution, latitude) { return (0,_core_js__WEBPACK_IMPORTED_MODULE_3__.calcDistanceForResolution)(resolution, latitude, this.scene_, this.view_.getProjection()); }
/** * 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 */ calcResolutionForDistance(distance, latitude) { return (0,_core_js__WEBPACK_IMPORTED_MODULE_3__.calcResolutionForDistance)(distance, latitude, this.scene_, this.view_.getProjection()); }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Camera);
/***/ }),
/***/ "./src/olcs/FeatureConverter.js":/*!**************************************!*\ !*** ./src/olcs/FeatureConverter.js ***! \**************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* 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");/* 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 */
class FeatureConverter { /** * 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 */ constructor(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 */ onRemoveOrClearFeature_(evt) { const source = evt.target; console.assert(source instanceof (ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_2___default()));
const cancellers = _util_js__WEBPACK_IMPORTED_MODULE_9__["default"].obj(source)['olcs_cancellers']; if (cancellers) { const feature = evt.feature; if (feature) { // remove
const id = (0,_util_js__WEBPACK_IMPORTED_MODULE_9__.getUid)(feature); const canceller = cancellers[id]; if (canceller) { canceller(); delete cancellers[id]; } } else { // clear
for (const 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 */ 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 */ createColoredPrimitive(layer, feature, olGeometry, geometry, color, opt_lineWidth) { const createInstance = function(geometry, color) { const instance = new Cesium.GeometryInstance({ // always update Cesium externs before adding a property
geometry }); if (color && !(color instanceof Cesium.ImageMaterialProperty)) { instance.attributes = { color: Cesium.ColorGeometryInstanceAttribute.fromColor(color) }; } return instance; };
const 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; }
const instances = createInstance(geometry, color);
const heightReference = this.getHeightReference(layer, feature, olGeometry);
let primitive;
if (heightReference === Cesium.HeightReference.CLAMP_TO_GROUND) { const 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) { const 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 */ extractColorFromOlStyle(style, outline) { const fillColor = style.getFill() ? style.getFill().getColor() : null; const strokeColor = style.getStroke() ? style.getStroke().getColor() : null;
let 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 */ extractLineWidthFromOlStyle(style) { // Handling of line width WebGL limitations is handled by Cesium.
const 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 */ wrapFillAndOutlineGeometries(layer, feature, olGeometry, fillGeometry, outlineGeometry, olStyle) { const fillColor = this.extractColorFromOlStyle(olStyle, false); const outlineColor = this.extractColorFromOlStyle(olStyle, true);
const primitives = new Cesium.PrimitiveCollection(); if (olStyle.getFill()) { const p1 = this.createColoredPrimitive(layer, feature, olGeometry, fillGeometry, fillColor); console.assert(!!p1); primitives.add(p1); }
if (olStyle.getStroke() && outlineGeometry) { const width = this.extractLineWidthFromOlStyle(olStyle); const 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 */ addTextStyle(layer, feature, geometry, style, primitive) { let primitives; if (!(primitive instanceof Cesium.PrimitiveCollection)) { primitives = new Cesium.PrimitiveCollection(); primitives.add(primitive); } else { primitives = primitive; }
if (!style.getText()) { return primitives; }
const text = /** @type {!ol.style.Text} */ (style.getText()); const 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 */ csAddBillboard(billboards, bbOptions, layer, feature, geometry, style) { if (!bbOptions.eyeOffset) { bbOptions.eyeOffset = this.defaultBillboardEyeOffset_; } const 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 */ olCircleGeometryToCesium(layer, feature, olGeometry, projection, olStyle) {
olGeometry = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].olGeometryCloneTo4326(olGeometry, projection); console.assert(olGeometry.getType() == 'Circle');
// ol.Coordinate
let center = olGeometry.getCenter(); const height = center.length == 3 ? center[2] : 0.0; let point = center.slice(); point[0] += olGeometry.getRadius();
// Cesium
center = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateToCesiumCartesian(center); point = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateToCesiumCartesian(point);
// Accurate computation of straight distance
const radius = Cesium.Cartesian3.distance(center, point);
const fillGeometry = new Cesium.CircleGeometry({ // always update Cesium externs before adding a property
center, radius, height });
let outlinePrimitive, outlineGeometry; if (this.getHeightReference(layer, feature, olGeometry) === Cesium.HeightReference.CLAMP_TO_GROUND) { const width = this.extractLineWidthFromOlStyle(olStyle); if (width) { const circlePolygon = (0,ol_geom_Polygon_js__WEBPACK_IMPORTED_MODULE_4__.circular)(olGeometry.getCenter(), radius); const positions = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateArrayToCsCartesians(circlePolygon.getLinearRing(0).getCoordinates()); if (!(0,_util_js__WEBPACK_IMPORTED_MODULE_9__.isGroundPolylinePrimitiveSupported)(this.scene)) { const color = this.extractColorFromOlStyle(olStyle, true); outlinePrimitive = this.createStackedGroundCorridors(layer, feature, width, color, positions); } else { outlinePrimitive = new Cesium.GroundPolylinePrimitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.GroundPolylineGeometry({positions, width}), }), appearance: new Cesium.PolylineMaterialAppearance({ material: this.olStyleToCesium(feature, olStyle, true), }), classificationType: Cesium.ClassificationType.TERRAIN, }); outlinePrimitive.readyPromise.then(() => { this.setReferenceForPicking(layer, feature, outlinePrimitive._primitive); }); } } } else { outlineGeometry = new Cesium.CircleOutlineGeometry({ // always update Cesium externs before adding a property
center, radius, extrudedHeight: height, height }); }
const primitives = this.wrapFillAndOutlineGeometries( layer, feature, olGeometry, fillGeometry, outlineGeometry, olStyle);
if (outlinePrimitive) { primitives.add(outlinePrimitive); } return this.addTextStyle(layer, feature, olGeometry, olStyle, primitives); }
/** * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!number} width The width of the line. * @param {!Cesium.Color} color The color of the line. * @param {!Array<Cesium.Cartesian3>|Array<Array<Cesium.Cartesian3>>} positions The vertices of the line(s). * @return {!Cesium.GroundPrimitive} primitive */ createStackedGroundCorridors(layer, feature, width, color, positions) { // Convert positions to an Array if it isn't
if (!Array.isArray(positions[0])) { positions = [positions]; } width = Math.max(3, width); // A <3px width is too small for ground primitives
const geometryInstances = []; let previousDistance = 0; // A stack of ground lines with increasing width (in meters) are created.
// Only one of these lines is displayed at any time giving a feeling of continuity.
// The values for the distance and width factor are more or less arbitrary.
// Applications can override this logics by subclassing the FeatureConverter class.
for (const distance of [1000, 4000, 16000, 64000, 254000, 1000000, 10000000]) { width *= 2.14; const geometryOptions = { // always update Cesium externs before adding a property
width, vertexFormat: Cesium.VertexFormat.POSITION_ONLY }; for (const linePositions of positions) { geometryOptions.positions = linePositions; geometryInstances.push(new Cesium.GeometryInstance({ geometry: new Cesium.CorridorGeometry(geometryOptions), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(color), distanceDisplayCondition: new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(previousDistance, distance - 1) } })); } previousDistance = distance; } return new Cesium.GroundPrimitive({ // always update Cesium externs before adding a property
geometryInstances }); }
/** * Convert an OpenLayers line string geometry to Cesium. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.LineString} olGeometry OpenLayers line string geometry. * @param {!ol.ProjectionLike} projection * @param {!ol.style.Style} olStyle * @return {!Cesium.PrimitiveCollection} primitives * @api */ olLineStringGeometryToCesium(layer, feature, olGeometry, projection, olStyle) {
olGeometry = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].olGeometryCloneTo4326(olGeometry, projection); console.assert(olGeometry.getType() == 'LineString');
const positions = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateArrayToCsCartesians(olGeometry.getCoordinates()); const width = this.extractLineWidthFromOlStyle(olStyle);
let outlinePrimitive; const heightReference = this.getHeightReference(layer, feature, olGeometry);
if (heightReference === Cesium.HeightReference.CLAMP_TO_GROUND && !(0,_util_js__WEBPACK_IMPORTED_MODULE_9__.isGroundPolylinePrimitiveSupported)(this.scene)) { const color = this.extractColorFromOlStyle(olStyle, true); outlinePrimitive = this.createStackedGroundCorridors(layer, feature, width, color, positions); } else { const appearance = new Cesium.PolylineMaterialAppearance({ // always update Cesium externs before adding a property
material: this.olStyleToCesium(feature, olStyle, true) }); const geometryOptions = { // always update Cesium externs before adding a property
positions, width, }; const primitiveOptions = { // always update Cesium externs before adding a property
appearance }; if (heightReference === Cesium.HeightReference.CLAMP_TO_GROUND) { const geometry = new Cesium.GroundPolylineGeometry(geometryOptions); primitiveOptions.geometryInstances = new Cesium.GeometryInstance({ geometry }), outlinePrimitive = new Cesium.GroundPolylinePrimitive(primitiveOptions); outlinePrimitive.readyPromise.then(() => { this.setReferenceForPicking(layer, feature, outlinePrimitive._primitive); }); } else { geometryOptions.vertexFormat = appearance.vertexFormat; const geometry = new Cesium.PolylineGeometry(geometryOptions); primitiveOptions.geometryInstances = new Cesium.GeometryInstance({ geometry }), outlinePrimitive = new Cesium.Primitive(primitiveOptions); } }
this.setReferenceForPicking(layer, feature, outlinePrimitive);
return this.addTextStyle(layer, feature, olGeometry, olStyle, outlinePrimitive); }
/** * Convert an OpenLayers polygon geometry to Cesium. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Polygon} olGeometry OpenLayers polygon geometry. * @param {!ol.ProjectionLike} projection * @param {!ol.style.Style} olStyle * @return {!Cesium.PrimitiveCollection} primitives * @api */ olPolygonGeometryToCesium(layer, feature, olGeometry, projection, olStyle) {
olGeometry = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].olGeometryCloneTo4326(olGeometry, projection); console.assert(olGeometry.getType() == 'Polygon');
const heightReference = this.getHeightReference(layer, feature, olGeometry);
let fillGeometry, outlineGeometry, outlinePrimitive; if ((olGeometry.getCoordinates()[0].length == 5) && (feature.getGeometry().get('olcs.polygon_kind') === 'rectangle')) { // Create a rectangle according to the longitude and latitude curves
const coordinates = olGeometry.getCoordinates()[0]; // Extract the West, South, East, North coordinates
const extent = (0,ol_extent_js__WEBPACK_IMPORTED_MODULE_5__.boundingExtent)(coordinates); const rectangle = Cesium.Rectangle.fromDegrees(extent[0], extent[1], extent[2], extent[3]);
// Extract the average height of the vertices
let maxHeight = 0.0; if (coordinates[0].length == 3) { for (let c = 0; c < coordinates.length; c++) { maxHeight = Math.max(maxHeight, coordinates[c][2]); } }
// Render the cartographic rectangle
fillGeometry = new Cesium.RectangleGeometry({ ellipsoid: Cesium.Ellipsoid.WGS84, rectangle, height: maxHeight });
outlineGeometry = new Cesium.RectangleOutlineGeometry({ ellipsoid: Cesium.Ellipsoid.WGS84, rectangle, height: maxHeight }); } else { const rings = olGeometry.getLinearRings(); // always update Cesium externs before adding a property
const hierarchy = {}; const polygonHierarchy = hierarchy; console.assert(rings.length > 0);
for (let i = 0; i < rings.length; ++i) { const olPos = rings[i].getCoordinates(); const positions = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateArrayToCsCartesians(olPos); console.assert(positions && positions.length > 0); if (i == 0) { hierarchy.positions = positions; } else { if (!hierarchy.holes) { hierarchy.holes = []; } hierarchy.holes.push({ positions }); } }
fillGeometry = new Cesium.PolygonGeometry({ // always update Cesium externs before adding a property
polygonHierarchy, perPositionHeight: true });
// Since Cesium doesn't yet support Polygon outlines on terrain yet (coming soon...?)
// we don't create an outline geometry if clamped, but instead do the polyline method
// for each ring. Most of this code should be removeable when Cesium adds
// support for Polygon outlines on terrain.
if (heightReference === Cesium.HeightReference.CLAMP_TO_GROUND) { const width = this.extractLineWidthFromOlStyle(olStyle); if (width > 0) { const positions = [hierarchy.positions]; if (hierarchy.holes) { for (let i = 0; i < hierarchy.holes.length; ++i) { positions.push(hierarchy.holes[i].positions); } } if (!(0,_util_js__WEBPACK_IMPORTED_MODULE_9__.isGroundPolylinePrimitiveSupported)(this.scene)) { const color = this.extractColorFromOlStyle(olStyle, true); outlinePrimitive = this.createStackedGroundCorridors(layer, feature, width, color, positions); } else { const appearance = new Cesium.PolylineMaterialAppearance({ // always update Cesium externs before adding a property
material: this.olStyleToCesium(feature, olStyle, true) }); const geometryInstances = []; for (const linePositions of positions) { const polylineGeometry = new Cesium.GroundPolylineGeometry({positions: linePositions, width}); geometryInstances.push(new Cesium.GeometryInstance({ geometry: polylineGeometry })); } const primitiveOptions = { // always update Cesium externs before adding a property
appearance, geometryInstances }; outlinePrimitive = new Cesium.GroundPolylinePrimitive(primitiveOptions); outlinePrimitive.readyPromise.then(() => { this.setReferenceForPicking(layer, feature, outlinePrimitive._primitive); }); } } } else { // Actually do the normal polygon thing. This should end the removable
// section of code described above.
outlineGeometry = new Cesium.PolygonOutlineGeometry({ // always update Cesium externs before adding a property
polygonHierarchy: hierarchy, perPositionHeight: true }); } }
const primitives = this.wrapFillAndOutlineGeometries( layer, feature, olGeometry, fillGeometry, outlineGeometry, olStyle);
if (outlinePrimitive) { primitives.add(outlinePrimitive); }
return this.addTextStyle(layer, feature, olGeometry, olStyle, primitives); }
/** * @param {ol.layer.Vector|ol.layer.Image} layer * @param {ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Geometry} geometry * @return {!Cesium.HeightReference} * @api */ getHeightReference(layer, feature, geometry) {
// Read from the geometry
let altitudeMode = geometry.get('altitudeMode');
// Or from the feature
if (altitudeMode === undefined) { altitudeMode = feature.get('altitudeMode'); }
// Or from the layer
if (altitudeMode === undefined) { altitudeMode = layer.get('altitudeMode'); }
let heightReference = Cesium.HeightReference.NONE; if (altitudeMode === 'clampToGround') { heightReference = Cesium.HeightReference.CLAMP_TO_GROUND; } else if (altitudeMode === 'relativeToGround') { heightReference = Cesium.HeightReference.RELATIVE_TO_GROUND; }
return heightReference; }
/** * Convert a point geometry to a Cesium BillboardCollection. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Point} olGeometry OpenLayers point geometry. * @param {!ol.ProjectionLike} projection * @param {!ol.style.Style} style * @param {!ol.style.Image} imageStyle * @param {!Cesium.BillboardCollection} billboards * @param {function(!Cesium.Billboard)=} opt_newBillboardCallback Called when the new billboard is added. * @api */ createBillboardFromImage( layer, feature, olGeometry, projection, style, imageStyle, billboards, opt_newBillboardCallback ) {
if (imageStyle instanceof (ol_style_Icon_js__WEBPACK_IMPORTED_MODULE_1___default())) { // make sure the image is scheduled for load
imageStyle.load(); }
const image = imageStyle.getImage(1); // get normal density
const isImageLoaded = function(image) { return image.src != '' && image.naturalHeight != 0 && image.naturalWidth != 0 && image.complete; }; const reallyCreateBillboard = (function() { if (!image) { return; } if (!(image instanceof HTMLCanvasElement || image instanceof Image || image instanceof HTMLImageElement)) { return; } const center = olGeometry.getCoordinates(); const position = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateToCesiumCartesian(center); let color; const opacity = imageStyle.getOpacity(); if (opacity !== undefined) { color = new Cesium.Color(1.0, 1.0, 1.0, opacity); }
const scale = imageStyle.getScale(); const heightReference = this.getHeightReference(layer, feature, olGeometry);
const bbOptions = /** @type {Cesium.optionsBillboardCollectionAdd} */ ({ // always update Cesium externs before adding a property
image, color, scale, heightReference, position });
// merge in cesium options from openlayers feature
Object.assign(bbOptions, feature.get('cesiumOptions'));
if (imageStyle instanceof (ol_style_Icon_js__WEBPACK_IMPORTED_MODULE_1___default())) { const anchor = imageStyle.getAnchor(); if (anchor) { bbOptions.pixelOffset = new Cesium.Cartesian2((image.width / 2 - anchor[0]) * scale, (image.height / 2 - anchor[1]) * scale); } }
const bb = this.csAddBillboard(billboards, bbOptions, layer, feature, olGeometry, style); if (opt_newBillboardCallback) { opt_newBillboardCallback(bb); } }).bind(this);
if (image instanceof Image && !isImageLoaded(image)) { // Cesium requires the image to be loaded
let cancelled = false; const source = layer.getSource(); const canceller = function() { cancelled = true; }; source.on(['removefeature', 'clear'], this.boundOnRemoveOrClearFeatureListener_); let cancellers = _util_js__WEBPACK_IMPORTED_MODULE_9__["default"].obj(source)['olcs_cancellers']; if (!cancellers) { cancellers = _util_js__WEBPACK_IMPORTED_MODULE_9__["default"].obj(source)['olcs_cancellers'] = {}; }
const fuid = (0,_util_js__WEBPACK_IMPORTED_MODULE_9__.getUid)(feature); if (cancellers[fuid]) { // When the feature change quickly, a canceller may still be present so
// we cancel it here to prevent creation of a billboard.
cancellers[fuid](); } cancellers[fuid] = canceller;
const listener = function() { image.removeEventListener('load', listener); if (!billboards.isDestroyed() && !cancelled) { // Create billboard if the feature is still displayed on the map.
reallyCreateBillboard(); } };
image.addEventListener('load', listener); } else { reallyCreateBillboard(); } }
/** * Convert a point geometry to a Cesium BillboardCollection. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Point} olGeometry OpenLayers point geometry. * @param {!ol.ProjectionLike} projection * @param {!ol.style.Style} style * @param {!Cesium.BillboardCollection} billboards * @param {function(!Cesium.Billboard)=} opt_newBillboardCallback Called when * the new billboard is added. * @return {Cesium.Primitive} primitives * @api */ olPointGeometryToCesium( layer, feature, olGeometry, projection, style, billboards, opt_newBillboardCallback ) { console.assert(olGeometry.getType() == 'Point'); olGeometry = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].olGeometryCloneTo4326(olGeometry, projection);
let modelPrimitive = null; const imageStyle = style.getImage(); if (imageStyle) { const olcsModelFunction = /** @type {function():olcsx.ModelStyle} */ (olGeometry.get('olcs_model') || feature.get('olcs_model')); if (olcsModelFunction) { const olcsModel = olcsModelFunction(); const options = /** @type {Cesium.ModelFromGltfOptions} */ (Object.assign({}, {scene: this.scene}, olcsModel.cesiumOptions)); const model = Cesium.Model.fromGltf(options); modelPrimitive = new Cesium.PrimitiveCollection(); modelPrimitive.add(model); if (olcsModel.debugModelMatrix) { modelPrimitive.add(new Cesium.DebugModelMatrixPrimitive({ modelMatrix: olcsModel.debugModelMatrix })); } } else { this.createBillboardFromImage(layer, feature, olGeometry, projection, style, imageStyle, billboards, opt_newBillboardCallback); } }
if (style.getText()) { return this.addTextStyle(layer, feature, olGeometry, style, modelPrimitive || new Cesium.Primitive()); } else { return modelPrimitive; } }
/** * Convert an OpenLayers multi-something geometry to Cesium. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Geometry} geometry OpenLayers geometry. * @param {!ol.ProjectionLike} projection * @param {!ol.style.Style} olStyle * @param {!Cesium.BillboardCollection} billboards * @param {function(!Cesium.Billboard)=} opt_newBillboardCallback Called when * the new billboard is added. * @return {Cesium.Primitive} primitives * @api */ olMultiGeometryToCesium( layer, feature, geometry, projection, olStyle, billboards, opt_newBillboardCallback ) { // Do not reproject to 4326 now because it will be done later.
// FIXME: would be better to combine all child geometries in one primitive
// instead we create n primitives for simplicity.
const accumulate = function(geometries, functor) { const primitives = new Cesium.PrimitiveCollection(); geometries.forEach((geometry) => { primitives.add(functor(layer, feature, geometry, projection, olStyle)); }); return primitives; };
let subgeos; switch (geometry.getType()) { case 'MultiPoint': geometry = /** @type {!ol.geom.MultiPoint} */ (geometry); subgeos = geometry.getPoints(); if (olStyle.getText()) { const primitives = new Cesium.PrimitiveCollection(); subgeos.forEach((geometry) => { console.assert(geometry); const result = this.olPointGeometryToCesium(layer, feature, geometry, projection, olStyle, billboards, opt_newBillboardCallback); if (result) { primitives.add(result); } }); return primitives; } else { subgeos.forEach((geometry) => { console.assert(geometry); this.olPointGeometryToCesium(layer, feature, geometry, projection, olStyle, billboards, opt_newBillboardCallback); }); return null; } case 'MultiLineString': geometry = /** @type {!ol.geom.MultiLineString} */ (geometry); subgeos = geometry.getLineStrings(); return accumulate(subgeos, this.olLineStringGeometryToCesium.bind(this)); case 'MultiPolygon': geometry = /** @type {!ol.geom.MultiPolygon} */ (geometry); subgeos = geometry.getPolygons(); return accumulate(subgeos, this.olPolygonGeometryToCesium.bind(this)); default: console.assert(false, `Unhandled multi geometry type${geometry.getType()}`); } }
/** * Convert an OpenLayers text style to Cesium. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature.. * @param {!ol.geom.Geometry} geometry * @param {!ol.style.Text} style * @return {Cesium.LabelCollection} Cesium primitive * @api */ olGeometry4326TextPartToCesium(layer, feature, geometry, style) { const text = style.getText(); if (!text) { return null; }
const labels = new Cesium.LabelCollection({scene: this.scene}); // TODO: export and use the text draw position from OpenLayers .
// See src/ol/render/vector.js
const extentCenter = (0,ol_extent_js__WEBPACK_IMPORTED_MODULE_5__.getCenter)(geometry.getExtent()); if (geometry instanceof (ol_geom_SimpleGeometry_js__WEBPACK_IMPORTED_MODULE_6___default())) { const first = geometry.getFirstCoordinate(); extentCenter[2] = first.length == 3 ? first[2] : 0.0; } const options = /** @type {Cesium.optionsLabelCollection} */ ({});
options.position = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].ol4326CoordinateToCesiumCartesian(extentCenter);
options.text = text;
options.heightReference = this.getHeightReference(layer, feature, geometry);
const offsetX = style.getOffsetX(); const offsetY = style.getOffsetY(); if (offsetX != 0 && offsetY != 0) { const offset = new Cesium.Cartesian2(offsetX, offsetY); options.pixelOffset = offset; }
options.font = style.getFont() || '10px sans-serif'; // OpenLayers default
let labelStyle = undefined; if (style.getFill()) { options.fillColor = this.extractColorFromOlStyle(style, false); labelStyle = Cesium.LabelStyle.FILL; } if (style.getStroke()) { options.outlineWidth = this.extractLineWidthFromOlStyle(style); options.outlineColor = this.extractColorFromOlStyle(style, true); labelStyle = Cesium.LabelStyle.OUTLINE; } if (style.getFill() && style.getStroke()) { labelStyle = Cesium.LabelStyle.FILL_AND_OUTLINE; } options.style = labelStyle;
let horizontalOrigin; switch (style.getTextAlign()) { case 'left': horizontalOrigin = Cesium.HorizontalOrigin.LEFT; break; case 'right': horizontalOrigin = Cesium.HorizontalOrigin.RIGHT; break; case 'center': default: horizontalOrigin = Cesium.HorizontalOrigin.CENTER; } options.horizontalOrigin = horizontalOrigin;
if (style.getTextBaseline()) { let verticalOrigin; switch (style.getTextBaseline()) { case 'top': verticalOrigin = Cesium.VerticalOrigin.TOP; break; case 'middle': verticalOrigin = Cesium.VerticalOrigin.CENTER; break; case 'bottom': verticalOrigin = Cesium.VerticalOrigin.BOTTOM; break; case 'alphabetic': verticalOrigin = Cesium.VerticalOrigin.TOP; break; case 'hanging': verticalOrigin = Cesium.VerticalOrigin.BOTTOM; break; default: console.assert(false, `unhandled baseline ${style.getTextBaseline()}`); } options.verticalOrigin = verticalOrigin; }
const l = labels.add(options); this.setReferenceForPicking(layer, feature, l); return labels; }
/** * Convert an OpenLayers style to a Cesium Material. * @param {ol.Feature} feature OpenLayers feature.. * @param {!ol.style.Style} style * @param {boolean} outline * @return {Cesium.Material} * @api */ olStyleToCesium(feature, style, outline) { const fill = style.getFill(); const stroke = style.getStroke(); if ((outline && !stroke) || (!outline && !fill)) { return null; // FIXME use a default style? Developer error?
}
let color = outline ? stroke.getColor() : fill.getColor(); color = _core_js__WEBPACK_IMPORTED_MODULE_7__["default"].convertColorToCesium(color);
if (outline && stroke.getLineDash()) { return Cesium.Material.fromType('Stripe', { // always update Cesium externs before adding a property
horizontal: false, repeat: 500, // TODO how to calculate this?
evenColor: color, oddColor: new Cesium.Color(0, 0, 0, 0) // transparent
}); } else { return Cesium.Material.fromType('Color', { // always update Cesium externs before adding a property
color }); }
}
/** * Compute OpenLayers plain style. * Evaluates style function, blend arrays, get default style. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature * @param {ol.StyleFunction|undefined} fallbackStyleFunction * @param {number} resolution * @return {Array.<!ol.style.Style>} null if no style is available * @api */ computePlainStyle(layer, feature, fallbackStyleFunction, resolution) { /** * @type {ol.FeatureStyleFunction|undefined} */ const featureStyleFunction = feature.getStyleFunction();
/** * @type {ol.style.Style|Array.<ol.style.Style>} */ let style = null;
if (featureStyleFunction) { style = featureStyleFunction(feature, resolution); }
if (!style && fallbackStyleFunction) { style = fallbackStyleFunction(feature, resolution); }
if (!style) { // The feature must not be displayed
return null; }
// FIXME combine materials as in cesium-materials-pack?
// then this function must return a custom material
// More simply, could blend the colors like described in
// http://en.wikipedia.org/wiki/Alpha_compositing
return Array.isArray(style) ? style : [style]; }
/** * @protected * @param {!ol.Feature} feature * @param {!ol.style.Style} style * @param {!ol.geom.Geometry=} opt_geom Geometry to be converted. * @return {ol.geom.Geometry|undefined} */ getGeometryFromFeature(feature, style, opt_geom) { if (opt_geom) { return opt_geom; }
const geom3d = /** @type {!ol.geom.Geometry} */(feature.get('olcs.3d_geometry')); if (geom3d && geom3d instanceof (ol_geom_Geometry_js__WEBPACK_IMPORTED_MODULE_0___default())) { return geom3d; }
if (style) { const geomFuncRes = style.getGeometryFunction()(feature); if (geomFuncRes instanceof (ol_geom_Geometry_js__WEBPACK_IMPORTED_MODULE_0___default())) { return geomFuncRes; } }
return feature.getGeometry(); }
/** * Convert one OpenLayers feature up to a collection of Cesium primitives. * @param {ol.layer.Vector|ol.layer.Image} layer * @param {!ol.Feature} feature OpenLayers feature. * @param {!ol.style.Style} style * @param {!import('olcs/core/VectorLayerConterpart.js').OlFeatureToCesiumContext} context * @param {!ol.geom.Geometry=} opt_geom Geometry to be converted. * @return {Cesium.Primitive} primitives * @api */ olFeatureToCesium(layer, feature, style, context, opt_geom) { let geom = this.getGeometryFromFeature(feature, style, opt_geom);
if (!geom) { // OpenLayers features may not have a geometry
// See http://geojson.org/geojson-spec.html#feature-objects
return null; }
const proj = context.projection; const newBillboardAddedCallback = function(bb) { const featureBb = context.featureToCesiumMap[(0,_util_js__WEBPACK_IMPORTED_MODULE_9__.getUid)(feature)]; if (featureBb instanceof Array) { featureBb.push(bb); } else { context.featureToCesiumMap[(0,_util_js__WEBPACK_IMPORTED_MODULE_9__.getUid)(feature)] = [bb]; } };
switch (geom.getType()) { case 'GeometryCollection': const primitives = new Cesium.PrimitiveCollection(); const collection = /** @type {!ol.geom.GeometryCollection} */ (geom); // TODO: use getGeometriesArray() instead
collection.getGeometries().forEach((geom) => { if (geom) { const prims = this.olFeatureToCesium(layer, feature, style, context, geom); if (prims) { primitives.add(prims); } } }); return primitives; case 'Point': geom = /** @type {!ol.geom.Point} */ (geom); const bbs = context.billboards; const result = this.olPointGeometryToCesium(layer, feature, geom, proj, style, bbs, newBillboardAddedCallback); if (!result) { // no wrapping primitive
return null; } else { return result; } case 'Circle': geom = /** @type {!ol.geom.Circle} */ (geom); return this.olCircleGeometryToCesium(layer, feature, geom, proj, style); case 'LineString': geom = /** @type {!ol.geom.LineString} */ (geom); return this.olLineStringGeometryToCesium(layer, feature, geom, proj, style); case 'Polygon': geom = /** @type {!ol.geom.Polygon} */ (geom); return this.olPolygonGeometryToCesium(layer, feature, geom, proj, style); case 'MultiPoint': case 'MultiLineString': case 'MultiPolygon': const result2 = this.olMultiGeometryToCesium(layer, feature, geom, proj, style, context.billboards, newBillboardAddedCallback); if (!result2) { // no wrapping primitive
return null; } else { return result2; } case 'LinearRing': throw new Error('LinearRing should only be part of polygon.'); default: throw new Error(`Ol geom type not handled : ${geom.getType()}`); } }
/** * Convert an OpenLayers vector layer to Cesium primitive collection. * For each feature, the associated primitive will be stored in * `featurePrimitiveMap`. * @param {!(ol.layer.Vector|ol.layer.Image)} olLayer * @param {!ol.View} olView * @param {!Object.<number, !Cesium.Primitive>} featurePrimitiveMap * @return {!olcs.core.VectorLayerCounterpart} * @api */ olVectorLayerToCesium(olLayer, olView, featurePrimitiveMap) { const proj = olView.getProjection(); const resolution = olView.getResolution();
if (resolution === undefined || !proj) { console.assert(false, 'View not ready'); // an assertion is not enough for closure to assume resolution and proj
// are defined
throw new Error('View not ready'); }
let source = olLayer.getSource(); if (source instanceof (ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_3___default())) { source = source.getSource(); }
console.assert(source instanceof (ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_2___default())); const features = source.getFeatures(); const counterpart = new _core_VectorLayerCounterpart_js__WEBPACK_IMPORTED_MODULE_8__["default"](proj, this.scene); const context = counterpart.context; for (let i = 0; i < features.length; ++i) { const feature = features[i]; if (!feature) { continue; } /** * @type {ol.StyleFunction|undefined} */ const layerStyle = olLayer.getStyleFunction(); const styles = this.computePlainStyle(olLayer, feature, layerStyle, resolution); if (!styles || !styles.length) { // only 'render' features with a style
continue; }
/** * @type {Cesium.Primitive|null} */ let primitives = null; for (let i = 0; i < styles.length; i++) { const prims = this.olFeatureToCesium(olLayer, feature, styles[i], context); if (prims) { if (!primitives) { primitives = prims; } else if (prims) { let i = 0, prim; while ((prim = prims.get(i))) { primitives.add(prim); i++; } } } } if (!primitives) { continue; } featurePrimitiveMap[(0,_util_js__WEBPACK_IMPORTED_MODULE_9__.getUid)(feature)] = primitives; counterpart.getRootPrimitive().add(primitives); }
return counterpart; }
/** * Convert an OpenLayers feature to Cesium primitive collection. * @param {!(ol.layer.Vector|ol.layer.Image)} layer * @param {!ol.View} view * @param {!ol.Feature} feature * @param {!import('olcs/core/VectorLayerConterpart.js').OlFeatureToCesiumContext} context * @return {Cesium.Primitive} * @api */ convert(layer, view, feature, context) { const proj = view.getProjection(); const resolution = view.getResolution();
if (resolution == undefined || !proj) { return null; }
/** * @type {ol.StyleFunction|undefined} */ const layerStyle = layer.getStyleFunction();
const styles = this.computePlainStyle(layer, feature, layerStyle, resolution);
if (!styles || !styles.length) { // only 'render' features with a style
return null; }
context.projection = proj;
/** * @type {Cesium.Primitive|null} */ let primitives = null; for (let i = 0; i < styles.length; i++) { const prims = this.olFeatureToCesium(layer, feature, styles[i], context); if (!primitives) { primitives = prims; } else if (prims) { let i = 0, prim; while ((prim = prims.get(i))) { primitives.add(prim); i++; } } } return primitives; }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FeatureConverter);
/***/ }),
/***/ "./src/olcs/MVTImageryProvider.js":/*!****************************************!*\ !*** ./src/olcs/MVTImageryProvider.js ***! \****************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (/* binding */ MVTImageryProvider)/* harmony export */ });/* harmony import */ var ol_format_MVT_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/format/MVT.js */ "ol/format/MVT.js");/* harmony import */ var ol_format_MVT_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_format_MVT_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var ol_style_Style_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/style/Style.js */ "ol/style/Style.js");/* harmony import */ var ol_style_Style_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_style_Style_js__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */ var ol_style_Stroke_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ol/style/Stroke.js */ "ol/style/Stroke.js");/* harmony import */ var ol_style_Stroke_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ol_style_Stroke_js__WEBPACK_IMPORTED_MODULE_2__);/* harmony import */ var ol_render_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ol/render.js */ "ol/render.js");/* harmony import */ var ol_render_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(ol_render_js__WEBPACK_IMPORTED_MODULE_3__);/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ol/proj.js */ "ol/proj.js");/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(ol_proj_js__WEBPACK_IMPORTED_MODULE_4__);/* harmony import */ var ol_util_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ol/util.js */ "ol/util.js");/* harmony import */ var ol_util_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(ol_util_js__WEBPACK_IMPORTED_MODULE_5__);/* harmony import */ var ol_structs_LRUCache_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ol/structs/LRUCache.js */ "ol/structs/LRUCache.js");/* harmony import */ var ol_structs_LRUCache_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(ol_structs_LRUCache_js__WEBPACK_IMPORTED_MODULE_6__);/* harmony import */ var ol_tilegrid_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ol/tilegrid.js */ "ol/tilegrid.js");/* harmony import */ var ol_tilegrid_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(ol_tilegrid_js__WEBPACK_IMPORTED_MODULE_7__);/* harmony import */ var ol_tileurlfunction_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ol/tileurlfunction.js */ "ol/tileurlfunction.js");/* harmony import */ var ol_tileurlfunction_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(ol_tileurlfunction_js__WEBPACK_IMPORTED_MODULE_8__);
const format = new (ol_format_MVT_js__WEBPACK_IMPORTED_MODULE_0___default())();const styles = [new (ol_style_Style_js__WEBPACK_IMPORTED_MODULE_1___default())({ stroke: new (ol_style_Stroke_js__WEBPACK_IMPORTED_MODULE_2___default())({ color: 'blue', width: 2 })})];
class MVTImageryProvider { constructor(options) { this.urls = options.urls; this.ready = true; this.readyPromise = Promise.resolve(true); this.tileWidth = 256; this.tileHeight = 256; this.maximumLevel = options.maximumLevel || 20; this.minimumLevel = options.minimumLevel || 0; this.tilingScheme = new Cesium.WebMercatorTilingScheme; this.rectangle = options.rectangle || this.tilingScheme.rectangle; this.errorEvent = new Cesium.Event(); this.credit = options.credit; this.hasAlphaChannel = true; this.styleFunction_ = options.styleFunction || (() => styles); this.projection_ = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_4__.get)('EPSG:3857'); this.emptyCanvas_ = document.createElement('canvas'); this.emptyCanvas_.width = 1; this.emptyCanvas_.height = 1; this.tileRectangle_ = new Cesium.Rectangle(); const cacheSize = options.cacheSize !== undefined ? options.cacheSize : 50; this.tileCache = new (ol_structs_LRUCache_js__WEBPACK_IMPORTED_MODULE_6___default())(cacheSize); this.featureCache = options.featureCache || new (ol_structs_LRUCache_js__WEBPACK_IMPORTED_MODULE_6___default())(cacheSize); // to avoid too frequent cache grooming we allow x2 capacity
const tileGrid = (0,ol_tilegrid_js__WEBPACK_IMPORTED_MODULE_7__.getForProjection)(this.projection_); this.tileFunction_ = (0,ol_tileurlfunction_js__WEBPACK_IMPORTED_MODULE_8__.createFromTemplates)(this.urls, tileGrid); }
getTileCredits() { return []; }
pickFeatures() { }
getTileFeatures(z, x, y) { const cacheKey = this.getCacheKey_(z, x, y); let promise; if (this.featureCache.containsKey(cacheKey)) { promise = this.featureCache.get(cacheKey); } if (!promise) { const url = this.getUrl_(z, x, y); promise = fetch(url) .then(r => (r.ok ? r : Promise.reject(r))) .then(r => r.arrayBuffer()) .then(buffer => this.readFeaturesFromBuffer(buffer)); this.featureCache.set(cacheKey, promise); if (this.featureCache.getCount() > 2 * this.featureCache.highWaterMark) { while (this.featureCache.canExpireCache()) { this.featureCache.pop(); } } } return promise; }
readFeaturesFromBuffer(buffer) { let options; if (ol_util_js__WEBPACK_IMPORTED_MODULE_5__.VERSION <= '6.4.4') { // See https://github.com/openlayers/openlayers/pull/11540
options = { extent: [0, 0, 4096, 4096], dataProjection: format.dataProjection, featureProjection: format.dataProjection }; } const features = format.readFeatures(buffer, options); const scaleFactor = this.tileWidth / 4096; features.forEach((f) => { const flatCoordinates = f.getFlatCoordinates(); let flip = false; for (let i = 0; i < flatCoordinates.length; ++i) { flatCoordinates[i] *= scaleFactor; if (flip) { // FIXME: why do we need this now?
flatCoordinates[i] = this.tileWidth - flatCoordinates[i]; } if (ol_util_js__WEBPACK_IMPORTED_MODULE_5__.VERSION <= '6.4.4') { flip = !flip; } } });
return features; }
getUrl_(z, x, y) { const url = this.tileFunction_([z, x, y]); return url; }
getCacheKey_(z, x, y) { return `${z}_${x}_${y}`; }
requestImage(x, y, z, request) { if (z < this.minimumLevel) { return this.emptyCanvas_; }
try { const cacheKey = this.getCacheKey_(z, x, y); let promise; if (this.tileCache.containsKey(cacheKey)) { promise = this.tileCache.get(cacheKey); } if (!promise) { promise = this.getTileFeatures(z, x, y) .then((features) => { // FIXME: here we suppose the 2D projection is in meters
this.tilingScheme.tileXYToNativeRectangle(x, y, z, this.tileRectangle_); const resolution = (this.tileRectangle_.east - this.tileRectangle_.west) / this.tileWidth; return this.rasterizeFeatures(features, this.styleFunction_, resolution); }); this.tileCache.set(cacheKey, promise); if (this.tileCache.getCount() > 2 * this.tileCache.highWaterMark) { while (this.tileCache.canExpireCache()) { this.tileCache.pop(); } } } return promise; } catch (e) { console.trace(e); this.raiseEvent('could not render pbf to tile', e); } }
rasterizeFeatures(features, styleFunction, resolution) { const canvas = document.createElement('canvas'); const vectorContext = (0,ol_render_js__WEBPACK_IMPORTED_MODULE_3__.toContext)(canvas.getContext('2d'), {size: [this.tileWidth, this.tileHeight]}); features.forEach((f) => { const styles = styleFunction(f, resolution); if (styles) { styles.forEach((style) => { vectorContext.setStyle(style); vectorContext.drawGeometry(f); }); } }); return canvas; }}
/***/ }),
/***/ "./src/olcs/OLCesium.js":/*!******************************!*\ !*** ./src/olcs/OLCesium.js ***! \******************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var ol_geom_Point_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/geom/Point.js */ "ol/geom/Point.js");/* harmony import */ var ol_geom_Point_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_geom_Point_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/proj.js */ "ol/proj.js");/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_proj_js__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js");/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./core.js */ "./src/olcs/core.js");/* harmony import */ var _AutoRenderLoop_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./AutoRenderLoop.js */ "./src/olcs/AutoRenderLoop.js");/* harmony import */ var _Camera_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Camera.js */ "./src/olcs/Camera.js");/* harmony import */ var _RasterSynchronizer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./RasterSynchronizer.js */ "./src/olcs/RasterSynchronizer.js");/* harmony import */ var _VectorSynchronizer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./VectorSynchronizer.js */ "./src/olcs/VectorSynchronizer.js");/* harmony import */ var _OverlaySynchronizer_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./OverlaySynchronizer.js */ "./src/olcs/OverlaySynchronizer.js");/** * @module olcs.OLCesium */
/** * @typedef {Object} OLCesiumOptions * @property {import('ol/Map.js').default} map The OpenLayers map we want to show on a Cesium scene. * @property {Cesium.Viewer} [viewer] Cesium viewer. * @property {function(!import('ol/Map.js').default, !Cesium.Scene, !Cesium.DataSourceCollection): Array<import('olcs/AbstractSynchronizer.js').default>} * [createSynchronizers] Callback function which will be called by the {@link olcs.OLCesium} * constructor to create custom synchronizers. Receives an `ol.Map` and a `Cesium.Scene` as arguments, * and needs to return an array of {@link import('olcs/AbstractSynchronizer.js').default}. * @property {function(): Cesium.JulianDate} [time] Control the current time used by Cesium. * @property {boolean} [stopOpenLayersEventsPropagation] Prevent propagation of mouse/touch events to * OpenLayers when Cesium is active. */
class OLCesium { /** * @param {!OLCesiumOptions} options Options. * @constructor * @api */ constructor(options) {
/** * @type {olcs.AutoRenderLoop} * @private */ this.autoRenderLoop_ = null;
/** * @type {!ol.Map} * @private */ this.map_ = options.map;
/** * @type {!function(): Cesium.JulianDate} * @private */ this.time_ = options.time || function() { return Cesium.JulianDate.now(); };
/** * No change of the view projection. * @private */ this.to4326Transform_ = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_1__.getTransform)(this.map_.getView().getProjection(), 'EPSG:4326');
/** * @type {number} * @private */ this.resolutionScale_ = 1.0;
/** * @type {number} * @private */ this.canvasClientWidth_ = 0.0;
/** * @type {number} * @private */ this.canvasClientHeight_ = 0.0;
/** * @type {boolean} * @private */ this.resolutionScaleChanged_ = true; // force resize
const fillArea = 'position:absolute;top:0;left:0;width:100%;height:100%;';
/** * @type {!Element} * @private */ this.container_ = document.createElement('DIV'); const containerAttribute = document.createAttribute('style'); containerAttribute.value = `${fillArea}visibility:hidden;`; this.container_.setAttributeNode(containerAttribute);
//火星科技添加
let viewer = options.viewer
viewer.container.appendChild(this.container_);
// /**
// * Whether the Cesium container is placed over the ol map.
// * a target => side by side mode
// * no target => over map mode
// * @type {boolean}
// * @private
// */
// this.isOverMap_ = false;
// if (this.isOverMap_ && options.stopOpenLayersEventsPropagation) {
// const overlayEvents = ['click', 'dblclick', 'mousedown', 'touchstart', 'MSPointerDown', 'pointerdown', 'mousewheel', 'wheel'];
// for (let i = 0, ii = overlayEvents.length; i < ii; ++i) {
// this.container_.addEventListener(overlayEvents[i], evt => evt.stopPropagation());
// }
// }
// /**
// * @type {!HTMLCanvasElement}
// * @private
// */
// this.canvas_ = /** @type {!HTMLCanvasElement} */ (document.createElement('CANVAS'));
// const canvasAttribute = document.createAttribute('style');
// canvasAttribute.value = fillArea;
// this.canvas_.setAttributeNode(canvasAttribute);
// if (olcsUtil.supportsImageRenderingPixelated()) {
// // non standard CSS4
// this.canvas_.style['imageRendering'] = olcsUtil.imageRenderingValue();
// }
// this.canvas_.oncontextmenu = function() { return false; };
// this.canvas_.onselectstart = function() { return false; };
// this.container_.appendChild(this.canvas_);
/** * @type {boolean} * @private */ this.enabled_ = false;
/** * @type {!Array.<ol.interaction.Interaction>} * @private */ this.pausedInteractions_ = [];
/** * @type {?ol.layer.Group} * @private */ this.hiddenRootGroup_ = null;
// const sceneOptions = options.sceneOptions !== undefined ? options.sceneOptions :
// /** @type {Cesium.SceneOptions} */ ({});
// sceneOptions.canvas = this.canvas_;
// sceneOptions.scene3DOnly = true;
/** * @type {!Cesium.Scene} * @private */ this.scene_ = viewer.scene;
// const sscc = this.scene_.screenSpaceCameraController;
// sscc.tiltEventTypes.push({
// 'eventType': Cesium.CameraEventType.LEFT_DRAG,
// 'modifier': Cesium.KeyboardEventModifier.SHIFT
// });
// sscc.tiltEventTypes.push({
// 'eventType': Cesium.CameraEventType.LEFT_DRAG,
// 'modifier': Cesium.KeyboardEventModifier.ALT
// });
// sscc.enableLook = false;
// this.scene_.camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;
/** * @type {!olcs.Camera} * @private */ this.camera_ = new _Camera_js__WEBPACK_IMPORTED_MODULE_5__["default"](this.scene_, this.map_);
/** * @type {!Cesium.Globe} * @private */ this.globe_ = viewer.scene.globe; // this.globe_.baseColor = Cesium.Color.WHITE;
// this.scene_.globe = this.globe_;
// this.scene_.skyAtmosphere = new Cesium.SkyAtmosphere();
// The first layer of Cesium is special; using a 1x1 transparent image to workaround it.
// See https://github.com/AnalyticalGraphicsInc/cesium/issues/1323 for details.
// const firstImageryProvider = new Cesium.SingleTileImageryProvider({
// url: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',
// rectangle: Cesium.Rectangle.fromDegrees(0, 0, 1, 1) // the Rectangle dimensions are arbitrary
// });
// this.globe_.imageryLayers.addImageryProvider(firstImageryProvider, 0);
this.dataSourceCollection_ = viewer.dataSources this.dataSourceDisplay_ = viewer.dataSourceDisplay
const synchronizers = options.createSynchronizers ? options.createSynchronizers(this.map_, this.scene_, this.dataSourceCollection_) : [ new _RasterSynchronizer_js__WEBPACK_IMPORTED_MODULE_6__["default"](this.map_, this.scene_), new _VectorSynchronizer_js__WEBPACK_IMPORTED_MODULE_7__["default"](this.map_, this.scene_), new _OverlaySynchronizer_js__WEBPACK_IMPORTED_MODULE_8__["default"](this.map_, this.scene_) ];
// Assures correct canvas size after initialisation
// this.handleResize_();
for (let i = synchronizers.length - 1; i >= 0; --i) { synchronizers[i].synchronize(); }
// /**
// * Time of the last rendered frame, as returned by `performance.now()`.
// * @type {number}
// * @private
// */
// this.lastFrameTime_ = 0;
// /**
// * The identifier returned by `requestAnimationFrame`.
// * @type {number|undefined}
// * @private
// */
// this.renderId_ = undefined;
// /**
// * Target frame rate for the render loop.
// * @type {number}
// * @private
// */
// this.targetFrameRate_ = Number.POSITIVE_INFINITY;
// /**
// * If the Cesium render loop is being blocked.
// * @type {boolean}
// * @private
// */
// this.blockCesiumRendering_ = false;
// /**
// * If the warmup routine is active.
// * @type {boolean}
// * @private
// */
// this.warmingUp_ = false;
/** * @type {ol.Feature} * @private */ this.trackedFeature_ = null;
/** * @type {Cesium.Entity} * @private */ this.trackedEntity_ = null;
// /**
// * @type {Cesium.EntityView}
// * @private
// */
// this.entityView_ = null;
// /**
// * @type {boolean}
// * @private
// */
// this.needTrackedEntityUpdate_ = false;
// /**
// * @type {!Cesium.BoundingSphere}
// */
// this.boundingSphereScratch_ = new Cesium.BoundingSphere();
// const eventHelper = new Cesium.EventHelper();
// eventHelper.add(this.scene_.postRender, OLCesium.prototype.updateTrackedEntity_, this);
// Cesium has a mechanism to prevent the camera to go under the terrain.
// Unfortunately, it is only active when all the terrain has been loaded, which:
// - does not prevent the camera to sink under terrain anymore;
// - introduce a jumping effect once all terrain has been loaded and the position of the camera is finally fixed.
// The property below enables a workaround found in the Camptocamp Cesium fork.
// See also https://github.com/AnalyticalGraphicsInc/cesium/issues/5999.
// Cesium.Camera.enableSuspendTerrainAdjustment = false;
viewer.scene.postUpdate.addEventListener(this.onAnimationFrame_, this); }
// /**
// * Render the Cesium scene.
// * @private
// */
// render_() {
// // // if a call to `requestAnimationFrame` is pending, cancel it
// // if (this.renderId_ !== undefined) {
// // cancelAnimationFrame(this.renderId_);
// // this.renderId_ = undefined;
// // }
// // // only render if Cesium is enabled/warming and rendering hasn't been blocked
// // if ((this.enabled_ || this.warmingUp_) && !this.blockCesiumRendering_) {
// // this.renderId_ = requestAnimationFrame(this.onAnimationFrame_.bind(this));
// // }
// }
/** * Callback for `requestAnimationFrame`. * @param {number} frameTime The frame time, from `performance.now()`. * @private */ onAnimationFrame_(frameTime) { // this.renderId_ = undefined;
// // check if a frame was rendered within the target frame rate
// const interval = 1000.0 / this.targetFrameRate_;
// const delta = frameTime - this.lastFrameTime_;
// if (delta < interval) {
// // too soon, don't render yet
// this.render_();
// return;
// }
// time to render a frame, save the time
// this.lastFrameTime_ = frameTime;
// const julianDate = this.time_();
// this.scene_.initializeFrame();
// this.handleResize_();
// this.dataSourceDisplay_.update(julianDate);
// // Update tracked entity
// if (this.entityView_) {
// const trackedEntity = this.trackedEntity_;
// const trackedState = this.dataSourceDisplay_.getBoundingSphere(trackedEntity, false, this.boundingSphereScratch_);
// if (trackedState === Cesium.BoundingSphereState.DONE) {
// this.boundingSphereScratch_.radius = 1; // a radius of 1 is enough for tracking points
// this.entityView_.update(julianDate, this.boundingSphereScratch_);
// }
// }
// this.scene_.render(julianDate);
this.camera_.checkCameraChange();
// request the next render call after this one completes to ensure the browser doesn't get backed up
// this.render_();
}
/** * @private */ // updateTrackedEntity_() {
// if (!this.needTrackedEntityUpdate_) {
// return;
// }
// const trackedEntity = this.trackedEntity_;
// const scene = this.scene_;
// const state = this.dataSourceDisplay_.getBoundingSphere(trackedEntity, false, this.boundingSphereScratch_);
// if (state === Cesium.BoundingSphereState.PENDING) {
// return;
// }
// scene.screenSpaceCameraController.enableTilt = false;
// const bs = state !== Cesium.BoundingSphereState.FAILED ? this.boundingSphereScratch_ : undefined;
// if (bs) {
// bs.radius = 1;
// }
// this.entityView_ = new Cesium.EntityView(trackedEntity, scene, scene.mapProjection.ellipsoid);
// this.entityView_.update(this.time_(), bs);
// this.needTrackedEntityUpdate_ = false;
// }
// /**
// * @private
// */
// handleResize_() {
// let width = this.canvas_.clientWidth;
// let height = this.canvas_.clientHeight;
// if (width === 0 | height === 0) {
// // The canvas DOM element is not ready yet.
// return;
// }
// if (width === this.canvasClientWidth_ &&
// height === this.canvasClientHeight_ &&
// !this.resolutionScaleChanged_) {
// return;
// }
// let resolutionScale = this.resolutionScale_;
// if (!olcsUtil.supportsImageRenderingPixelated()) {
// resolutionScale *= window.devicePixelRatio || 1.0;
// }
// this.resolutionScaleChanged_ = false;
// this.canvasClientWidth_ = width;
// this.canvasClientHeight_ = height;
// width *= resolutionScale;
// height *= resolutionScale;
// this.canvas_.width = width;
// this.canvas_.height = height;
// // this.scene_.camera.frustum.aspectRatio = width / height;
// }
/** * @return {!olcs.Camera} * @api */ getCamera() { return this.camera_; }
/** * @return {!ol.Map} * @api */ getOlMap() { return this.map_; }
/** * @return {!ol.View} * @api */ getOlView() { const view = this.map_.getView(); console.assert(view); return view; }
/** * @return {!Cesium.Scene} * @api */ getCesiumScene() { return this.scene_; }
/** * @return {!Cesium.DataSourceCollection} * @api */ getDataSources() { return this.dataSourceCollection_; }
/** * @return {!Cesium.DataSourceDisplay} * @api */ getDataSourceDisplay() { return this.dataSourceDisplay_; }
/** * @return {boolean} * @api */ getEnabled() { return this.enabled_; }
/** * Enables/disables the Cesium. * This modifies the visibility style of the container element. * @param {boolean} enable * @api */ setEnabled(enable) { if (this.enabled_ === enable) { return; } this.enabled_ = enable;
// some Cesium operations are operating with canvas.clientWidth,
// so we can't remove it from DOM or even make display:none;
// this.container_.style.visibility = this.enabled_ ? 'visible' : 'hidden';
// let interactions;
if (this.enabled_) { // this.throwOnUnitializedMap_();
// if (this.isOverMap_) {
// interactions = this.map_.getInteractions();
// interactions.forEach((el, i, arr) => {
// this.pausedInteractions_.push(el);
// });
// interactions.clear();
// this.map_.addInteraction = interaction => this.pausedInteractions_.push(interaction);
// this.map_.removeInteraction = interaction =>
// this.pausedInteractions_ = this.pausedInteractions_.filter(i => i !== interaction);
// const rootGroup = this.map_.getLayerGroup();
// if (rootGroup.getVisible()) {
// this.hiddenRootGroup_ = rootGroup;
// this.hiddenRootGroup_.setVisible(false);
// }
// this.map_.getOverlayContainer().classList.add('olcs-hideoverlay');
// }
this.camera_.readFromView(); // this.render_();
} else { // if (this.isOverMap_) {
// interactions = this.map_.getInteractions();
// this.pausedInteractions_.forEach((interaction) => {
// interactions.push(interaction);
// });
// this.pausedInteractions_.length = 0;
// this.map_.addInteraction = interaction => this.map_.getInteractions().push(interaction);
// this.map_.removeInteraction = interaction => this.map_.getInteractions().remove(interaction);
// this.map_.getOverlayContainer().classList.remove('olcs-hideoverlay');
// if (this.hiddenRootGroup_) {
// this.hiddenRootGroup_.setVisible(true);
// this.hiddenRootGroup_ = null;
// }
// }
this.camera_.updateView(); } }
/** * Preload Cesium so that it is ready when transitioning from 2D to 3D. * @param {number} height Target height of the camera * @param {number} timeout Milliseconds after which the warming will stop * @api */ warmUp(height, timeout) { if (this.enabled_) { // already enabled
return; } this.throwOnUnitializedMap_(); this.camera_.readFromView(); const ellipsoid = this.globe_.ellipsoid; const csCamera = this.scene_.camera; const position = ellipsoid.cartesianToCartographic(csCamera.position); if (position.height < height) { position.height = height; csCamera.position = ellipsoid.cartographicToCartesian(position); }
// this.warmingUp_ = true;
// // this.render_();
// setTimeout(() => {
// this.warmingUp_ = false;
// }, timeout);
}
// /**
// * Block Cesium rendering to save resources.
// * @param {boolean} block True to block.
// * @api
// */
// setBlockCesiumRendering(block) {
// if (this.blockCesiumRendering_ !== block) {
// this.blockCesiumRendering_ = block;
// // reset the render loop
// this.render_();
// }
// }
/** * Render the globe only when necessary in order to save resources. * Experimental. * @api */ enableAutoRenderLoop() { if (!this.autoRenderLoop_) { this.autoRenderLoop_ = new _AutoRenderLoop_js__WEBPACK_IMPORTED_MODULE_4__["default"](this); } }
/** * Get the autorender loop. * @return {?olcs.AutoRenderLoop} * @api */ getAutoRenderLoop() { return this.autoRenderLoop_; }
/** * The 3D Cesium globe is rendered in a canvas with two different dimensions: * clientWidth and clientHeight which are the dimension on the screen and * width and height which are the dimensions of the drawing buffer. * * By using a resolution scale lower than 1.0, it is possible to render the * globe in a buffer smaller than the canvas client dimensions and improve * performance, at the cost of quality. * * Pixel ratio should also be taken into account; by default, a device with * pixel ratio of 2.0 will have a buffer surface 4 times bigger than the client * surface. * * @param {number} value * @this {olcs.OLCesium} * @api */ setResolutionScale(value) { value = Math.max(0, value); if (value !== this.resolutionScale_) { this.resolutionScale_ = Math.max(0, value); this.resolutionScaleChanged_ = true; if (this.autoRenderLoop_) { this.autoRenderLoop_.restartRenderLoop(); } } }
// /**
// * Set the target frame rate for the renderer. Set to `Number.POSITIVE_INFINITY`
// * to render as quickly as possible.
// * @param {number} value The frame rate, in frames per second.
// * @api
// */
// setTargetFrameRate(value) {
// if (this.targetFrameRate_ !== value) {
// this.targetFrameRate_ = value;
// // reset the render loop
// this.render_();
// }
// }
/** * Check if OpenLayers map is not properly initialized. * @private */ throwOnUnitializedMap_() { const map = this.map_; const view = map.getView(); const center = view.getCenter(); if (!view.isDef() || isNaN(center[0]) || isNaN(center[1])) { throw new Error(`The OpenLayers map is not properly initialized: ${center} / ${view.getResolution()}`); } }
/** * @type {ol.Feature} */ get trackedFeature() { return this.trackedFeature_; }
/** * @param {ol.Feature} feature */ set trackedFeature(feature) { if (this.trackedFeature_ !== feature) {
const scene = this.scene_;
//Stop tracking
if (!feature || !feature.getGeometry()) { // this.needTrackedEntityUpdate_ = false;
scene.screenSpaceCameraController.enableTilt = true;
if (this.trackedEntity_) { this.dataSourceDisplay_.defaultDataSource.entities.remove(this.trackedEntity_); } this.trackedEntity_ = null; this.trackedFeature_ = null; this.entityView_ = null; scene.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); return; }
this.trackedFeature_ = feature;
//We can't start tracking immediately, so we set a flag and start tracking
//when the bounding sphere is ready (most likely next frame).
// this.needTrackedEntityUpdate_ = true;
const to4326Transform = this.to4326Transform_; const toCesiumPosition = function() { const geometry = feature.getGeometry(); console.assert(geometry instanceof (ol_geom_Point_js__WEBPACK_IMPORTED_MODULE_0___default())); const coo = geometry.getCoordinates(); const coo4326 = to4326Transform(coo, undefined, coo.length); return _core_js__WEBPACK_IMPORTED_MODULE_3__["default"].ol4326CoordinateToCesiumCartesian(coo4326); };
// Create an invisible point entity for tracking.
// It is independant from the primitive/geometry created by the vector synchronizer.
const options = { 'position': new Cesium.CallbackProperty((time, result) => toCesiumPosition(), false), 'point': { 'pixelSize': 1, 'color': Cesium.Color.TRANSPARENT } };
this.trackedEntity_ = this.dataSourceDisplay_.defaultDataSource.entities.add(options); } }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (OLCesium);
/***/ }),
/***/ "./src/olcs/OverlaySynchronizer.js":/*!*****************************************!*\ !*** ./src/olcs/OverlaySynchronizer.js ***! \*****************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var _SynchronizedOverlay_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SynchronizedOverlay.js */ "./src/olcs/SynchronizedOverlay.js");/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js");/** * @module olcs.OverlaySynchronizer */
class OverlaySynchronizer { /** * @param {!ol.Map} map * @param {!Cesium.Scene} scene * @constructor * @template T * @api */ constructor(map, scene) { /** * @type {!ol.Map} * @protected */ this.map = map;
/** * @type {ol.Collection.<ol.Overlay>} * @private */ this.overlays_ = this.map.getOverlays();
/** * @type {!Cesium.Scene} * @protected */ this.scene = scene;
/** * @private * @type {!Element} */ this.overlayContainerStopEvent_ = document.createElement('DIV'); this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent'; const overlayEvents = ['click', 'dblclick', 'mousedown', 'touchstart', 'MSPointerDown', 'pointerdown', 'mousewheel', 'wheel']; overlayEvents.forEach((event) => { this.overlayContainerStopEvent_.addEventListener(event, evt => evt.stopPropagation()); }); this.scene.canvas.parentElement.appendChild(this.overlayContainerStopEvent_);
/** * @private * @type {!Element} */ this.overlayContainer_ = document.createElement('DIV'); this.overlayContainer_.className = 'ol-overlaycontainer'; this.scene.canvas.parentElement.appendChild(this.overlayContainer_);
/** * @type {!Object<?,olcs.SynchronizedOverlay>} * @private */ this.overlayMap_ = {}; }
/** * Get the element that serves as a container for overlays that don't allow * event propagation. Elements added to this container won't let mousedown and * touchstart events through to the map, so clicks and gestures on an overlay * don't trigger any {@link ol.MapBrowserEvent}. * @return {!Element} The map's overlay container that stops events. */ getOverlayContainerStopEvent() { return this.overlayContainerStopEvent_; }
/** * Get the element that serves as a container for overlays. * @return {!Element} The map's overlay container. */ getOverlayContainer() { return this.overlayContainer_; }
/** * Destroy all and perform complete synchronization of the overlays. * @api */ synchronize() { this.destroyAll(); this.addOverlays(); this.overlays_.on('add', this.addOverlayFromEvent_.bind(this)); this.overlays_.on('remove', this.removeOverlayFromEvent_.bind(this)); }
/** * @param {ol.Collection.Event} event * @private */ addOverlayFromEvent_(event) { const overlay = /** @type {ol.Overlay} */ (event.element); this.addOverlay(overlay); }
/** * @api */ addOverlays() { this.overlays_.forEach((overlay) => { this.addOverlay(overlay); }); }
/** * @param {ol.Overlay} overlay * @api */ addOverlay(overlay) { if (!overlay) { return; } const cesiumOverlay = new _SynchronizedOverlay_js__WEBPACK_IMPORTED_MODULE_0__["default"]({ scene: this.scene, synchronizer: this, parent: overlay });
const overlayId = (0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(overlay).toString(); this.overlayMap_[overlayId] = cesiumOverlay; }
/** * @param {ol.Collection.Event} event * @private */ removeOverlayFromEvent_(event) { const removedOverlay = /** @type {ol.Overlay} */ (event.element); this.removeOverlay(removedOverlay); }
/** * Removes an overlay from the scene * @param {ol.Overlay} overlay * @api */ removeOverlay(overlay) { const overlayId = (0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(overlay).toString(); const csOverlay = this.overlayMap_[overlayId]; if (csOverlay) { csOverlay.destroy(); delete this.overlayMap_[overlayId]; } }
/** * Destroys all the created Cesium objects. * @protected */ destroyAll() { Object.keys(this.overlayMap_).forEach((key) => { const overlay = this.overlayMap_[key]; overlay.destroy(); delete this.overlayMap_[key]; }); }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (OverlaySynchronizer);
/***/ }),
/***/ "./src/olcs/RasterSynchronizer.js":/*!****************************************!*\ !*** ./src/olcs/RasterSynchronizer.js ***! \****************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/layer/Group.js */ "ol/layer/Group.js");/* harmony import */ var ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js");/* harmony import */ var _AbstractSynchronizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./AbstractSynchronizer.js */ "./src/olcs/AbstractSynchronizer.js");/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./core.js */ "./src/olcs/core.js");/** * @module olcs.RasterSynchronizer */
class RasterSynchronizer extends _AbstractSynchronizer_js__WEBPACK_IMPORTED_MODULE_2__["default"] { /** * This object takes care of one-directional synchronization of * Openlayers raster layers to the given Cesium globe. * @param {!ol.Map} map * @param {!Cesium.Scene} scene * @constructor * @extends {olcsAbstractSynchronizer.<Cesium.ImageryLayer>} * @api */ constructor(map, scene) { super(map, scene);
/** * @type {!Cesium.ImageryLayerCollection} * @private */ this.cesiumLayers_ = scene.imageryLayers;
/** * @type {!Cesium.ImageryLayerCollection} * @private */ this.ourLayers_ = new Cesium.ImageryLayerCollection(); }
/** * @inheritDoc */ addCesiumObject(object) { this.cesiumLayers_.add(object); this.ourLayers_.add(object); }
/** * @inheritDoc */ destroyCesiumObject(object) { object.destroy(); }
/** * @inheritDoc */ removeSingleCesiumObject(object, destroy) { this.cesiumLayers_.remove(object, destroy); this.ourLayers_.remove(object, false); }
/** * @inheritDoc */ removeAllCesiumObjects(destroy) { for (let i = 0; i < this.ourLayers_.length; ++i) { this.cesiumLayers_.remove(this.ourLayers_.get(i), destroy); } this.ourLayers_.removeAll(false); }
/** * Creates an array of Cesium.ImageryLayer. * May be overriden by child classes to implement custom behavior. * The default implementation handles tiled imageries in EPSG:4326 or * EPSG:3859. * @param {!ol.layer.Base} olLayer * @param {!ol.proj.Projection} viewProj Projection of the view. * @return {?Array.<!Cesium.ImageryLayer>} array or null if not possible * (or supported) * @protected */ convertLayerToCesiumImageries(olLayer, viewProj) { const result = _core_js__WEBPACK_IMPORTED_MODULE_3__["default"].tileLayerToImageryLayer(this.map, olLayer, viewProj); return result ? [result] : null; }
/** * @inheritDoc */ createSingleLayerCounterparts(olLayerWithParents) { const olLayer = olLayerWithParents.layer; const uid = (0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(olLayer).toString(); const viewProj = this.view.getProjection(); console.assert(viewProj); const cesiumObjects = this.convertLayerToCesiumImageries(olLayer, viewProj); if (cesiumObjects) { const listenKeyArray = []; [olLayerWithParents.layer].concat(olLayerWithParents.parents).forEach((olLayerItem) => { listenKeyArray.push(olLayerItem.on(['change:opacity', 'change:visible'], () => { // the compiler does not seem to be able to infer this
console.assert(cesiumObjects); for (let i = 0; i < cesiumObjects.length; ++i) { _core_js__WEBPACK_IMPORTED_MODULE_3__["default"].updateCesiumLayerProperties(olLayerWithParents, cesiumObjects[i]); } })); });
if (olLayer.getStyleFunction) { let previousStyleFunction = olLayer.getStyleFunction(); // there is no convenient way to detect a style function change in OL
listenKeyArray.push(olLayer.on('change', () => { const currentStyleFunction = olLayer.getStyleFunction(); if (previousStyleFunction === currentStyleFunction) { return; } previousStyleFunction = currentStyleFunction; for (let i = 0; i < cesiumObjects.length; ++i) { const csObj = cesiumObjects[i]; // clear cache and set new style
if (csObj._imageryCache && csObj.imageryProvider.cache_) { csObj._imageryCache = {}; csObj.imageryProvider.cache_ = {}; csObj.imageryProvider.styleFunction_ = currentStyleFunction; } } this.scene.requestRender(); })); }
for (let i = 0; i < cesiumObjects.length; ++i) { _core_js__WEBPACK_IMPORTED_MODULE_3__["default"].updateCesiumLayerProperties(olLayerWithParents, cesiumObjects[i]); }
// there is no way to modify Cesium layer extent,
// we have to recreate when OpenLayers layer extent changes:
listenKeyArray.push(olLayer.on('change:extent', (e) => { for (let i = 0; i < cesiumObjects.length; ++i) { this.cesiumLayers_.remove(cesiumObjects[i], true); // destroy
this.ourLayers_.remove(cesiumObjects[i], false); } delete this.layerMap[(0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(olLayer)]; // invalidate the map entry
this.synchronize(); }));
listenKeyArray.push(olLayer.on('change', (e) => { // when the source changes, re-add the layer to force update
for (let i = 0; i < cesiumObjects.length; ++i) { const position = this.cesiumLayers_.indexOf(cesiumObjects[i]); if (position >= 0) { this.cesiumLayers_.remove(cesiumObjects[i], false); this.cesiumLayers_.add(cesiumObjects[i], position); } } }));
this.olLayerListenKeys[uid].push(...listenKeyArray); }
return Array.isArray(cesiumObjects) ? cesiumObjects : null; }
/** * Order counterparts using the same algorithm as the Openlayers renderer: * z-index then original sequence order. * @override * @protected */ orderLayers() { const layers = []; const zIndices = {}; const queue = [this.mapLayerGroup];
while (queue.length > 0) { const olLayer = queue.splice(0, 1)[0]; layers.push(olLayer); zIndices[(0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(olLayer)] = olLayer.getZIndex() || 0;
if (olLayer instanceof (ol_layer_Group_js__WEBPACK_IMPORTED_MODULE_0___default())) { const sublayers = olLayer.getLayers(); if (sublayers) { // Prepend queue with sublayers in order
queue.unshift(...sublayers.getArray()); } } }
(0,_util_js__WEBPACK_IMPORTED_MODULE_1__.stableSort)(layers, (layer1, layer2) => zIndices[(0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(layer1)] - zIndices[(0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(layer2)] );
layers.forEach((olLayer) => { const olLayerId = (0,_util_js__WEBPACK_IMPORTED_MODULE_1__.getUid)(olLayer).toString(); const cesiumObjects = this.layerMap[olLayerId]; if (cesiumObjects) { cesiumObjects.forEach((cesiumObject) => { this.raiseToTop(cesiumObject); }); } }); }
/** * @param {Cesium.ImageryLayer} counterpart */ raiseToTop(counterpart) { this.cesiumLayers_.raiseToTop(counterpart); }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (RasterSynchronizer);
/***/ }),
/***/ "./src/olcs/SynchronizedOverlay.js":/*!*****************************************!*\ !*** ./src/olcs/SynchronizedOverlay.js ***! \*****************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var ol_Overlay_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/Overlay.js */ "ol/Overlay.js");/* harmony import */ var ol_Overlay_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_Overlay_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/proj.js */ "ol/proj.js");/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_proj_js__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js");/* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ol/Observable.js */ "ol/Observable.js");/* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(ol_Observable_js__WEBPACK_IMPORTED_MODULE_3__);/** * @module olcs.SynchronizedOverlay */
/** * Options for SynchronizedOverlay * @typedef {Object} SynchronizedOverlayOptions * @property {!Cesium.Scene} scene * @property {olOverlay} parent * @property {!import('olsc/OverlaySynchronizer.js').default} synchronizer */
class SynchronizedOverlay extends (ol_Overlay_js__WEBPACK_IMPORTED_MODULE_0___default()) { /** * @param {olcsx.SynchronizedOverlayOptions} options SynchronizedOverlay Options. * @api */ constructor(options) { const parent = options.parent; super(parent.getOptions());
/** * @private * @type {?Function} */ this.scenePostRenderListenerRemover_ = null;
/** * @private * @type {!Cesium.Scene} */ this.scene_ = options.scene;
/** * @private * @type {!olcs.OverlaySynchronizer} */ this.synchronizer_ = options.synchronizer;
/** * @private * @type {!ol.Overlay} */ this.parent_ = parent;
/** * @private * @type {ol.Coordinate|undefined} */ this.positionWGS84_ = undefined;
/** * @private * @type {MutationObserver} */ this.observer_ = new MutationObserver(this.handleElementChanged.bind(this));
/** * @private * @type {Array.<MutationObserver>} */ this.attributeObserver_ = [];
/** * @private * @type {Array<ol.EventsKey>} */ this.listenerKeys_ = []; // synchronize our Overlay with the parent Overlay
const setPropertyFromEvent = event => this.setPropertyFromEvent_(event); this.listenerKeys_.push(this.parent_.on('change:position', setPropertyFromEvent)); this.listenerKeys_.push(this.parent_.on('change:element', setPropertyFromEvent)); this.listenerKeys_.push(this.parent_.on('change:offset', setPropertyFromEvent)); this.listenerKeys_.push(this.parent_.on('change:position', setPropertyFromEvent)); this.listenerKeys_.push(this.parent_.on('change:positioning', setPropertyFromEvent));
this.setProperties(this.parent_.getProperties());
this.handleMapChanged(); this.handleElementChanged(); }
/** * @param {Node} target * @private */ observeTarget_(target) { if (!this.observer_) { // not ready, skip the event (this occurs on construction)
return; } this.observer_.disconnect(); this.observer_.observe(target, { attributes: false, childList: true, characterData: true, subtree: true }); this.attributeObserver_.forEach((observer) => { observer.disconnect(); }); this.attributeObserver_.length = 0; for (let i = 0; i < target.childNodes.length; i++) { const node = target.childNodes[i]; if (node.nodeType === 1) { const observer = new MutationObserver(this.handleElementChanged.bind(this)); observer.observe(node, { attributes: true, subtree: true }); this.attributeObserver_.push(observer); } } }
/** * * @param {ol.Object.Event} event * @private */ setPropertyFromEvent_(event) { if (event.target && event.key) { this.set(event.key, event.target.get(event.key)); } }
/** * Get the scene associated with this overlay. * @see ol.Overlay.prototype.getMap * @return {!Cesium.Scene} The scene that the overlay is part of. * @api */ getScene() { return this.scene_; }
/** * @override */ handleMapChanged() { if (this.scenePostRenderListenerRemover_) { this.scenePostRenderListenerRemover_(); (0,_util_js__WEBPACK_IMPORTED_MODULE_2__.removeNode)(this.element); } this.scenePostRenderListenerRemover_ = null; const scene = this.getScene(); if (scene) { this.scenePostRenderListenerRemover_ = scene.postRender.addEventListener(this.updatePixelPosition.bind(this)); this.updatePixelPosition(); const container = this.stopEvent ? this.synchronizer_.getOverlayContainerStopEvent() : this.synchronizer_.getOverlayContainer(); if (this.insertFirst) { container.insertBefore(this.element, container.childNodes[0] || null); } else { container.appendChild(this.element); } } }
/** * @override */ handlePositionChanged() { // transform position to WGS84
const position = this.getPosition(); if (position) { const sourceProjection = this.parent_.getMap().getView().getProjection(); this.positionWGS84_ = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_1__.transform)(position, sourceProjection, 'EPSG:4326'); } else { this.positionWGS84_ = undefined; } this.updatePixelPosition(); }
/** * @override */ handleElementChanged() { function cloneNode(node, parent) { const clone = node.cloneNode(); if (node.nodeName === 'CANVAS') { const ctx = clone.getContext('2d'); ctx.drawImage(node, 0, 0); } if (parent) { parent.appendChild(clone); } if (node.nodeType != Node.TEXT_NODE) { clone.addEventListener('click', (event) => { node.dispatchEvent(new MouseEvent('click', event)); event.stopPropagation(); }); } const nodes = node.childNodes; for (let i = 0; i < nodes.length; i++) { if (!nodes[i]) { continue; } cloneNode(nodes[i], clone); } return clone; } (0,_util_js__WEBPACK_IMPORTED_MODULE_2__.removeChildren)(this.element); const element = this.getElement(); if (element) { if (element.parentNode && element.parentNode.childNodes) { for (const node of element.parentNode.childNodes) { const clonedNode = cloneNode(node, null); this.element.appendChild(clonedNode); } } } if (element.parentNode) { // set new Observer
this.observeTarget_(element.parentNode); } }
/** * @override */ updatePixelPosition() { const position = this.positionWGS84_; if (!this.scene_ || !position) { this.setVisible(false); return; } let height = 0; if (position.length === 2) { const globeHeight = this.scene_.globe.getHeight(Cesium.Cartographic.fromDegrees(position[0], position[1])); if (globeHeight && this.scene_.globe.tilesLoaded) { position[2] = globeHeight; } if (globeHeight) { height = globeHeight; } } else { height = position[2]; } const cartesian = Cesium.Cartesian3.fromDegrees(position[0], position[1], height); const camera = this.scene_.camera; const ellipsoidBoundingSphere = new Cesium.BoundingSphere(new Cesium.Cartesian3(), 6356752); const occluder = new Cesium.Occluder(ellipsoidBoundingSphere, camera.position); // check if overlay position is behind the horizon
if (!occluder.isPointVisible(cartesian)) { this.setVisible(false); return; } const cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up); // check if overlay position is visible from the camera
if (cullingVolume.computeVisibility(new Cesium.BoundingSphere(cartesian)) !== 1) { this.setVisible(false); return; } this.setVisible(true);
const pixelCartesian = this.scene_.cartesianToCanvasCoordinates(cartesian); const pixel = [pixelCartesian.x, pixelCartesian.y]; const mapSize = [this.scene_.canvas.width, this.scene_.canvas.height]; this.updateRenderedPosition(pixel, mapSize); }
/** * Destroys the overlay, removing all its listeners and elements * @api */ destroy() { if (this.scenePostRenderListenerRemover_) { this.scenePostRenderListenerRemover_(); } if (this.observer_) { this.observer_.disconnect(); } (0,ol_Observable_js__WEBPACK_IMPORTED_MODULE_3__.unByKey)(this.listenerKeys_); this.listenerKeys_.splice(0); if (this.element.removeNode) { this.element.removeNode(true); } else { this.element.remove(); } this.element = null; }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SynchronizedOverlay);
/***/ }),
/***/ "./src/olcs/VectorSynchronizer.js":/*!****************************************!*\ !*** ./src/olcs/VectorSynchronizer.js ***! \****************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/source/Vector.js */ "ol/source/Vector.js");/* harmony import */ var ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var ol_layer_Layer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/layer/Layer.js */ "ol/layer/Layer.js");/* harmony import */ var ol_layer_Layer_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Layer_js__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */ var ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ol/source/Cluster.js */ "ol/source/Cluster.js");/* harmony import */ var ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_2__);/* harmony import */ var ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ol/layer/Image.js */ "ol/layer/Image.js");/* harmony import */ var ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_3__);/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js");/* harmony import */ var ol_layer_Vector_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ol/layer/Vector.js */ "ol/layer/Vector.js");/* harmony import */ var ol_layer_Vector_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Vector_js__WEBPACK_IMPORTED_MODULE_5__);/* harmony import */ var ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ol/layer/VectorTile.js */ "ol/layer/VectorTile.js");/* harmony import */ var ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_6__);/* harmony import */ var _AbstractSynchronizer_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./AbstractSynchronizer.js */ "./src/olcs/AbstractSynchronizer.js");/* harmony import */ var _FeatureConverter_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./FeatureConverter.js */ "./src/olcs/FeatureConverter.js");/** * @module olcs.VectorSynchronizer */
class VectorSynchronizer extends _AbstractSynchronizer_js__WEBPACK_IMPORTED_MODULE_7__["default"] { /** * Unidirectionally synchronize OpenLayers vector layers to Cesium. * @param {!ol.Map} map * @param {!Cesium.Scene} scene * @param {olcs.FeatureConverter=} opt_converter * @extends {olcs.AbstractSynchronizer.<olcs.core.VectorLayerCounterpart>} * @api */ constructor(map, scene, opt_converter) { super(map, scene);
/** * @protected */ this.converter = opt_converter || new _FeatureConverter_js__WEBPACK_IMPORTED_MODULE_8__["default"](scene);
/** * @private */ this.csAllPrimitives_ = new Cesium.PrimitiveCollection(); scene.primitives.add(this.csAllPrimitives_); this.csAllPrimitives_.destroyPrimitives = false; }
/** * @inheritDoc */ addCesiumObject(counterpart) { console.assert(counterpart); counterpart.getRootPrimitive()['counterpart'] = counterpart; this.csAllPrimitives_.add(counterpart.getRootPrimitive()); }
/** * @inheritDoc */ destroyCesiumObject(object) { object.getRootPrimitive().destroy(); }
/** * @inheritDoc */ removeSingleCesiumObject(object, destroy) { object.destroy(); this.csAllPrimitives_.destroyPrimitives = destroy; this.csAllPrimitives_.remove(object.getRootPrimitive()); this.csAllPrimitives_.destroyPrimitives = false; }
/** * @inheritDoc */ removeAllCesiumObjects(destroy) { this.csAllPrimitives_.destroyPrimitives = destroy; if (destroy) { for (let i = 0; i < this.csAllPrimitives_.length; ++i) { this.csAllPrimitives_.get(i)['counterpart'].destroy(); } } this.csAllPrimitives_.removeAll(); this.csAllPrimitives_.destroyPrimitives = false; }
/** * Synchronizes the layer visibility properties * to the given Cesium Primitive. * @param {import('olsc/core.js').LayerWithParents} olLayerWithParents * @param {!Cesium.Primitive} csPrimitive */ updateLayerVisibility(olLayerWithParents, csPrimitive) { let visible = true; [olLayerWithParents.layer].concat(olLayerWithParents.parents).forEach((olLayer) => { const layerVisible = olLayer.getVisible(); if (layerVisible !== undefined) { visible &= layerVisible; } else { visible = false; } }); csPrimitive.show = visible; }
/** * @inheritDoc */ createSingleLayerCounterparts(olLayerWithParents) { const olLayer = olLayerWithParents.layer; if (!(olLayer instanceof (ol_layer_Vector_js__WEBPACK_IMPORTED_MODULE_5___default())) || olLayer instanceof (ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_6___default())) { return null; } console.assert(olLayer instanceof (ol_layer_Layer_js__WEBPACK_IMPORTED_MODULE_1___default()));
let source = olLayer.getSource(); if (source instanceof (ol_source_Cluster_js__WEBPACK_IMPORTED_MODULE_2___default())) { source = source.getSource(); }
if (!source) { return null; }
console.assert(source instanceof (ol_source_Vector_js__WEBPACK_IMPORTED_MODULE_0___default())); console.assert(this.view);
const view = this.view; const featurePrimitiveMap = {}; const counterpart = this.converter.olVectorLayerToCesium(olLayer, view, featurePrimitiveMap); const csPrimitives = counterpart.getRootPrimitive(); const olListenKeys = counterpart.olListenKeys;
[olLayerWithParents.layer].concat(olLayerWithParents.parents).forEach((olLayerItem) => { olListenKeys.push((0,_util_js__WEBPACK_IMPORTED_MODULE_4__.olcsListen)(olLayerItem, 'change:visible', () => { this.updateLayerVisibility(olLayerWithParents, csPrimitives); })); }); this.updateLayerVisibility(olLayerWithParents, csPrimitives);
const onAddFeature = (function(feature) { console.assert( (olLayer instanceof (ol_layer_Vector_js__WEBPACK_IMPORTED_MODULE_5___default())) || (olLayer instanceof (ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_3___default())) ); const context = counterpart.context; const prim = this.converter.convert(olLayer, view, feature, context); if (prim) { featurePrimitiveMap[(0,_util_js__WEBPACK_IMPORTED_MODULE_4__.getUid)(feature)] = prim; csPrimitives.add(prim); } }).bind(this);
const onRemoveFeature = (function(feature) { const id = (0,_util_js__WEBPACK_IMPORTED_MODULE_4__.getUid)(feature); const context = counterpart.context; const bbs = context.featureToCesiumMap[id]; if (bbs) { delete context.featureToCesiumMap[id]; bbs.forEach((bb) => { if (bb instanceof Cesium.Billboard) { context.billboards.remove(bb); } }); } const csPrimitive = featurePrimitiveMap[id]; delete featurePrimitiveMap[id]; if (csPrimitive) { csPrimitives.remove(csPrimitive); } }).bind(this);
olListenKeys.push((0,_util_js__WEBPACK_IMPORTED_MODULE_4__.olcsListen)(source, 'addfeature', (e) => { console.assert(e.feature); onAddFeature(e.feature); }, this));
olListenKeys.push((0,_util_js__WEBPACK_IMPORTED_MODULE_4__.olcsListen)(source, 'removefeature', (e) => { console.assert(e.feature); onRemoveFeature(e.feature); }, this));
olListenKeys.push((0,_util_js__WEBPACK_IMPORTED_MODULE_4__.olcsListen)(source, 'changefeature', (e) => { const feature = e.feature; console.assert(feature); onRemoveFeature(feature); onAddFeature(feature); }, this));
return counterpart ? [counterpart] : null; }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (VectorSynchronizer);
/***/ }),
/***/ "./src/olcs/contrib/LazyLoader.js":/*!****************************************!*\ !*** ./src/olcs/contrib/LazyLoader.js ***! \****************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (/* binding */ LazyLoader)/* harmony export */ });/** * @module olcs.contrib.LazyLoader */class LazyLoader { /** * @param {string} url * @api */ constructor(url) { /** * @type {Promise<undefined>} * @protected */ this.promise;
/** * @private * @type {string} */ this.url_ = url; }
/** * @return {Promise<undefined>} * @api */ load() { if (!this.promise) { // not yet loading
this.promise = new Promise((resolve, reject) => { const script = document.createElement('script'); script.onload = () => resolve(); script.onerror = () => reject(); document.head.appendChild(script); script.src = this.url_; }); } return this.promise; }}
/***/ }),
/***/ "./src/olcs/contrib/Manager.js":/*!*************************************!*\ !*** ./src/olcs/contrib/Manager.js ***! \*************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var _contrib_LazyLoader_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../contrib/LazyLoader.js */ "./src/olcs/contrib/LazyLoader.js");/* harmony import */ var _OLCesium_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../OLCesium.js */ "./src/olcs/OLCesium.js");/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../core.js */ "./src/olcs/core.js");/* harmony import */ var _math_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../math.js */ "./src/olcs/math.js");/* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ol/Observable.js */ "ol/Observable.js");/* harmony import */ var ol_Observable_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(ol_Observable_js__WEBPACK_IMPORTED_MODULE_4__);/** * @module olcs.contrib.Manager */
/** * @typedef {Object} ManagerOptions * @property {import('ol/Map.js').default} map * @property {import('ol/extent.js').Extent} [cameraExtentInRadians] * @property {string} [cesiumIonDefaultAccessToken] */
const Manager = class extends (ol_Observable_js__WEBPACK_IMPORTED_MODULE_4___default()) { /** * @param {string} cesiumUrl * @param {olcsx.contrib.ManagerOptions} options * @api */ constructor(cesiumUrl, {map, cameraExtentInRadians, cesiumIonDefaultAccessToken} = {}) {
super();
/** * @type {string} * @private */ this.cesiumUrl_ = cesiumUrl;
/** * @type {ol.Map} * @protected */ this.map = map;
/** * @type {ol.Extent} * @protected */ this.cameraExtentInRadians = cameraExtentInRadians || null;
/** * @private * @type {Cesium.BoundingSphere} */ this.boundingSphere_;
/** * @type {boolean} * @private */ this.blockLimiter_ = false;
/** * @type {Promise.<olcs.OLCesium>} * @private */ this.promise_;
/** * @type {string} * @private */ this.cesiumIonDefaultAccessToken_ = cesiumIonDefaultAccessToken;
/** * @type {olcs.OLCesium} * @protected */ this.ol3d;
/** * @const {number} Tilt angle in radians * @private */ this.cesiumInitialTilt_ = (0,_math_js__WEBPACK_IMPORTED_MODULE_3__.toRadians)(50);
/** * @protected * @type {number} */ this.fogDensity = 0.0001;
/** * @protected * @type {number} */ this.fogSSEFactor = 25;
/** * Limit the minimum distance to the terrain to 2m. * @protected * @type {number} */ this.minimumZoomDistance = 2;
/** * Limit the maximum distance to the earth to 10'000km. * @protected * @type {number} */ this.maximumZoomDistance = 10000000;
// when closer to 3000m, restrict the available positions harder
/** * @protected * @param {number} height */ this.limitCameraToBoundingSphereRatio = height => (height > 3000 ? 9 : 3); }
/** * @return {Promise.<olcs.OLCesium>} */ load() { if (!this.promise_) { const cesiumLazyLoader = new _contrib_LazyLoader_js__WEBPACK_IMPORTED_MODULE_0__["default"](this.cesiumUrl_); this.promise_ = cesiumLazyLoader.load().then(() => this.onCesiumLoaded()); } return this.promise_; }
/** * @protected * @return {olcs.OLCesium} */ onCesiumLoaded() { if (this.cameraExtentInRadians) { const rect = new Cesium.Rectangle(...this.cameraExtentInRadians); // Set the fly home rectangle
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = rect; this.boundingSphere_ = Cesium.BoundingSphere.fromRectangle3D(rect, Cesium.Ellipsoid.WGS84, 300); // lux mean height is 300m
}
if (this.cesiumIonDefaultAccessToken_) { Cesium.Ion.defaultAccessToken = this.cesiumIonDefaultAccessToken_; }
this.ol3d = this.instantiateOLCesium(); const scene = this.ol3d.getCesiumScene(); this.configureForUsability(scene); this.configureForPerformance(scene); this.dispatchEvent('load'); return this.ol3d; }
/** * Application code should override this method. * @return {olcs.OLCesium} */ instantiateOLCesium() { console.assert(this.map); const ol3d = new _OLCesium_js__WEBPACK_IMPORTED_MODULE_1__["default"]({map: this.map}); const scene = ol3d.getCesiumScene(); const terrainProvider = Cesium.createWorldTerrain(); scene.terrainProvider = terrainProvider; return ol3d; }
/** * @param {!Cesium.Scene} scene The scene, passed as parameter for convenience. * @protected */ configureForPerformance(scene) { const fog = scene.fog; fog.enabled = true; fog.density = this.fogDensity; fog.screenSpaceErrorFactor = this.fogSSEFactor; }
/** * @param {!Cesium.Scene} scene The scene, passed as parameter for convenience. * @protected */ configureForUsability(scene) { const sscController = scene.screenSpaceCameraController; sscController.minimumZoomDistance = this.minimumZoomDistance; sscController.maximumZoomDistance = this.maximumZoomDistance;
// Do not see through the terrain. Seeing through the terrain does not make
// sense anyway, except for debugging
scene.globe.depthTestAgainstTerrain = true;
// Use white instead of the black default colour for the globe when tiles are missing
scene.globe.baseColor = Cesium.Color.WHITE; scene.backgroundColor = Cesium.Color.WHITE;
if (this.boundingSphere_) { scene.postRender.addEventListener(this.limitCameraToBoundingSphere.bind(this), scene); } // Stop rendering Cesium when there is nothing to do. This drastically reduces CPU/GPU consumption.
this.ol3d.enableAutoRenderLoop(); }
/** * Constrain the camera so that it stays close to the bounding sphere of the map extent. * Near the ground the allowed distance is shorter. * @protected */ limitCameraToBoundingSphere() { if (this.boundingSphere_ && !this.blockLimiter_) { const scene = this.ol3d.getCesiumScene(); const camera = scene.camera; const position = camera.position; const carto = Cesium.Cartographic.fromCartesian(position); const ratio = this.limitCameraToBoundingSphereRatio(carto.height); if (Cesium.Cartesian3.distance(this.boundingSphere_.center, position) > this.boundingSphere_.radius * ratio) { const currentlyFlying = camera.flying; if (currentlyFlying === true) { // There is a flying property and its value is true
return; } else { this.blockLimiter_ = true; const unblockLimiter = () => this.blockLimiter_ = false; camera.flyToBoundingSphere(this.boundingSphere_, { complete: unblockLimiter, cancel: unblockLimiter }); } } } }
/** * Enable or disable ol3d with a default animation. * @export * @return {Promise<undefined>} */ toggle3d() { return this.load().then((/** @const {!olcs.OLCesium} */ ol3d) => { const is3DCurrentlyEnabled = ol3d.getEnabled(); const scene = ol3d.getCesiumScene(); if (is3DCurrentlyEnabled) { // Disable 3D
console.assert(this.map); return _core_js__WEBPACK_IMPORTED_MODULE_2__["default"].resetToNorthZenith(this.map, scene).then(() => { ol3d.setEnabled(false); this.dispatchEvent('toggle'); }); } else { // Enable 3D
ol3d.setEnabled(true); this.dispatchEvent('toggle'); return _core_js__WEBPACK_IMPORTED_MODULE_2__["default"].rotateAroundBottomCenter(scene, this.cesiumInitialTilt_); } }); }
/** * Enable ol3d with a view built from parameters. * * @export * @param {number} lon * @param {number} lat * @param {number} elevation * @param {number} headingDeg Heading value in degrees. * @param {number} pitchDeg Pitch value in degrees. * @returns {Promise<undefined>} */ set3dWithView(lon, lat, elevation, headingDeg, pitchDeg) { return this.load().then((/** @const {!olcs.OLCesium} */ ol3d) => { const is3DCurrentlyEnabled = ol3d.getEnabled(); const scene = ol3d.getCesiumScene(); const camera = scene.camera; const destination = Cesium.Cartesian3.fromDegrees(lon, lat, elevation); const heading = Cesium.Math.toRadians(headingDeg); const pitch = Cesium.Math.toRadians(pitchDeg); const roll = 0; const orientation = {heading, pitch, roll};
if (!is3DCurrentlyEnabled) { ol3d.setEnabled(true); this.dispatchEvent('toggle'); }
camera.setView({ destination, orientation }); }); }
/** * @export * @return {boolean} */ is3dEnabled() { return !!this.ol3d && this.ol3d.getEnabled(); }
/** * @return {number} */ getHeading() { return this.map ? this.map.getView().getRotation() || 0 : 0; }
/** * @return {number|undefined} */ getTiltOnGlobe() { const scene = this.ol3d.getCesiumScene(); const tiltOnGlobe = _core_js__WEBPACK_IMPORTED_MODULE_2__["default"].computeSignedTiltAngleOnGlobe(scene); return -tiltOnGlobe; }
/** * @param {number} angle */ setHeading(angle) { const scene = this.ol3d.getCesiumScene(); const bottom = _core_js__WEBPACK_IMPORTED_MODULE_2__["default"].pickBottomPoint(scene); if (bottom) { _core_js__WEBPACK_IMPORTED_MODULE_2__["default"].setHeadingUsingBottomCenter(scene, angle, bottom); } }
/** * @export * @return {olcs.OLCesium} */ getOl3d() { return this.ol3d; }
/** * @export * @return {!ol.View} */ getOlView() { const view = this.map.getView(); console.assert(view); return view; }
/** * @export * @return {Cesium.Matrix4} */ getCesiumViewMatrix() { return this.ol3d.getCesiumScene().camera.viewMatrix; }
/** * @export * @return {!Cesium.Scene} */ getCesiumScene() { return this.ol3d.getCesiumScene(); }
/** * @export * @param {!Cesium.Rectangle} rectangle * @param {number=} offset in meters * @return {Promise<undefined>} */ flyToRectangle(rectangle, offset = 0) { const camera = this.getCesiumScene().camera; const destination = camera.getRectangleCameraCoordinates(rectangle);
const mag = Cesium.Cartesian3.magnitude(destination) + offset; Cesium.Cartesian3.normalize(destination, destination); Cesium.Cartesian3.multiplyByScalar(destination, mag, destination);
return new Promise((resolve, reject) => { if (!this.cameraExtentInRadians) { reject(); return; }
camera.flyTo({ destination, complete: () => resolve(), cancel: () => reject(), endTransform: Cesium.Matrix4.IDENTITY }); }); }
/** * @protected * @return {Cesium.Rectangle|undefined} */ getCameraExtentRectangle() { if (this.cameraExtentInRadians) { return new Cesium.Rectangle(...this.cameraExtentInRadians); } }};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Manager);
/***/ }),
/***/ "./src/olcs/core.js":/*!**************************!*\ !*** ./src/olcs/core.js ***! \**************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "attributionsFunctionToCredits": () => (/* binding */ attributionsFunctionToCredits),/* harmony export */ "calcDistanceForResolution": () => (/* binding */ calcDistanceForResolution),/* harmony export */ "calcResolutionForDistance": () => (/* binding */ calcResolutionForDistance),/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var ol_easing_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/easing.js */ "ol/easing.js");/* harmony import */ var ol_easing_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_easing_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var ol_layer_Tile_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ol/layer/Tile.js */ "ol/layer/Tile.js");/* harmony import */ var ol_layer_Tile_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Tile_js__WEBPACK_IMPORTED_MODULE_1__);/* harmony import */ var ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ol/layer/Image.js */ "ol/layer/Image.js");/* harmony import */ var ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_2__);/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ol/proj.js */ "ol/proj.js");/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(ol_proj_js__WEBPACK_IMPORTED_MODULE_3__);/* harmony import */ var ol_source_ImageStatic_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ol/source/ImageStatic.js */ "ol/source/ImageStatic.js");/* harmony import */ var ol_source_ImageStatic_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(ol_source_ImageStatic_js__WEBPACK_IMPORTED_MODULE_4__);/* harmony import */ var ol_source_ImageWMS_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ol/source/ImageWMS.js */ "ol/source/ImageWMS.js");/* harmony import */ var ol_source_ImageWMS_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(ol_source_ImageWMS_js__WEBPACK_IMPORTED_MODULE_5__);/* harmony import */ var ol_source_TileImage_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ol/source/TileImage.js */ "ol/source/TileImage.js");/* harmony import */ var ol_source_TileImage_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(ol_source_TileImage_js__WEBPACK_IMPORTED_MODULE_6__);/* harmony import */ var ol_source_TileWMS_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ol/source/TileWMS.js */ "ol/source/TileWMS.js");/* harmony import */ var ol_source_TileWMS_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(ol_source_TileWMS_js__WEBPACK_IMPORTED_MODULE_7__);/* harmony import */ var ol_source_VectorTile_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ol/source/VectorTile.js */ "ol/source/VectorTile.js");/* harmony import */ var ol_source_VectorTile_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(ol_source_VectorTile_js__WEBPACK_IMPORTED_MODULE_8__);/* harmony import */ var ol_source_Image_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ol/source/Image.js */ "ol/source/Image.js");/* harmony import */ var ol_source_Image_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(ol_source_Image_js__WEBPACK_IMPORTED_MODULE_9__);/* harmony import */ var _core_OLImageryProvider_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./core/OLImageryProvider.js */ "./src/olcs/core/OLImageryProvider.js");/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./util.js */ "./src/olcs/util.js");/* harmony import */ var _MVTImageryProvider_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MVTImageryProvider.js */ "./src/olcs/MVTImageryProvider.js");/* harmony import */ var ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ol/layer/VectorTile.js */ "ol/layer/VectorTile.js");/* harmony import */ var ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_13__);/* harmony import */ var ol_extent__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ol/extent */ "ol/extent");/* harmony import */ var ol_extent__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(ol_extent__WEBPACK_IMPORTED_MODULE_14__);/** * @module olcs.core */
const exports = {};
/** * @typedef {Object} CesiumUrlDefinition * @property {string} url * @property {string} subdomains */
/** * Options for rotate around axis core function. * @typedef {Object} RotateAroundAxisOption * @property {number} [duration] * @property {function(number): number} [easing] * @property {function(): void} [callback] */
/** * @typedef {Object} LayerWithParents * @property {import('ol/layer/Base.js').default} layer * @property {Array<import('ol/layer/Group.js').default>} parents */
/** * Compute the pixel width and height of a point in meters using the * camera frustum. * @param {!Cesium.Scene} scene * @param {!Cesium.Cartesian3} target * @return {!Cesium.Cartesian2} the pixel size * @api */exports.computePixelSizeAtCoordinate = function(scene, target) { const camera = scene.camera; const canvas = scene.canvas; const frustum = camera.frustum; const distance = Cesium.Cartesian3.magnitude(Cesium.Cartesian3.subtract( camera.position, target, new Cesium.Cartesian3())); return frustum.getPixelDimensions(canvas.clientWidth, canvas.clientHeight, distance, scene.pixelRatio, new Cesium.Cartesian2());};
/** * Compute bounding box around a target point. * @param {!Cesium.Scene} scene * @param {!Cesium.Cartesian3} target * @param {number} amount Half the side of the box, in pixels. * @return {Array<Cesium.Cartographic>} bottom left and top right * coordinates of the box */exports.computeBoundingBoxAtTarget = function(scene, target, amount) { const pixelSize = exports.computePixelSizeAtCoordinate(scene, target); const transform = Cesium.Transforms.eastNorthUpToFixedFrame(target);
const bottomLeft = Cesium.Matrix4.multiplyByPoint( transform, new Cesium.Cartesian3(-pixelSize.x * amount, -pixelSize.y * amount, 0), new Cesium.Cartesian3());
const topRight = Cesium.Matrix4.multiplyByPoint( transform, new Cesium.Cartesian3(pixelSize.x * amount, pixelSize.y * amount, 0), new Cesium.Cartesian3());
return Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray( [bottomLeft, topRight]);};
/** * * @param {!ol.geom.Geometry} geometry * @param {number} height * @api */exports.applyHeightOffsetToGeometry = function(geometry, height) { geometry.applyTransform((input, output, stride) => { console.assert(input === output); if (stride !== undefined && stride >= 3) { for (let i = 0; i < output.length; i += stride) { output[i + 2] = output[i + 2] + height; } } return output; });};
/** * @param {ol.Coordinate} coordinates * @param {number=} rotation * @param {!Cesium.Cartesian3=} translation * @param {!Cesium.Cartesian3=} scale * @return {!Cesium.Matrix4} * @api */exports.createMatrixAtCoordinates = function(coordinates, rotation = 0, translation = Cesium.Cartesian3.ZERO, scale = new Cesium.Cartesian3(1, 1, 1)) { const position = exports.ol4326CoordinateToCesiumCartesian(coordinates); const rawMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position); const quaternion = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, -rotation); const rotationMatrix = Cesium.Matrix4.fromTranslationQuaternionRotationScale(translation, quaternion, scale); return Cesium.Matrix4.multiply(rawMatrix, rotationMatrix, new Cesium.Matrix4());};
/** * @param {!Cesium.Camera} camera * @param {number} angle * @param {!Cesium.Cartesian3} axis * @param {!Cesium.Matrix4} transform * @param {RotateAroundAxisOption=} opt_options * @api */exports.rotateAroundAxis = function(camera, angle, axis, transform, opt_options) { const clamp = Cesium.Math.clamp; const defaultValue = Cesium.defaultValue;
const options = opt_options || {}; const duration = defaultValue(options.duration, 500); // ms
const easing = defaultValue(options.easing, ol_easing_js__WEBPACK_IMPORTED_MODULE_0__.linear); const callback = options.callback;
let lastProgress = 0; const oldTransform = new Cesium.Matrix4();
const start = Date.now(); const step = function() { const timestamp = Date.now(); const timeDifference = timestamp - start; const progress = easing(clamp(timeDifference / duration, 0, 1)); console.assert(progress >= lastProgress);
camera.transform.clone(oldTransform); const stepAngle = (progress - lastProgress) * angle; lastProgress = progress; camera.lookAtTransform(transform); camera.rotate(axis, stepAngle); camera.lookAtTransform(oldTransform);
if (progress < 1) { window.requestAnimationFrame(step); } else { if (callback) { callback(); } } }; window.requestAnimationFrame(step);};
/** * @param {!Cesium.Scene} scene * @param {number} heading * @param {!Cesium.Cartesian3} bottomCenter * @param {RotateAroundAxisOption=} opt_options * @api */exports.setHeadingUsingBottomCenter = function(scene, heading, bottomCenter, opt_options) { const camera = scene.camera; // Compute the camera position to zenith quaternion
const angleToZenith = exports.computeAngleToZenith(scene, bottomCenter); const axis = camera.right; const quaternion = Cesium.Quaternion.fromAxisAngle(axis, angleToZenith); const rotation = Cesium.Matrix3.fromQuaternion(quaternion);
// Get the zenith point from the rotation of the position vector
const vector = new Cesium.Cartesian3(); Cesium.Cartesian3.subtract(camera.position, bottomCenter, vector); const zenith = new Cesium.Cartesian3(); Cesium.Matrix3.multiplyByVector(rotation, vector, zenith); Cesium.Cartesian3.add(zenith, bottomCenter, zenith);
// Actually rotate around the zenith normal
const transform = Cesium.Matrix4.fromTranslation(zenith); const rotateAroundAxis = exports.rotateAroundAxis; rotateAroundAxis(camera, heading, zenith, transform, opt_options);};
/** * Get the 3D position of the given pixel of the canvas. * @param {!Cesium.Scene} scene * @param {!Cesium.Cartesian2} pixel * @return {!Cesium.Cartesian3|undefined} * @api */exports.pickOnTerrainOrEllipsoid = function(scene, pixel) { const ray = scene.camera.getPickRay(pixel); const target = scene.globe.pick(ray, scene); return target || scene.camera.pickEllipsoid(pixel);};
/** * Get the 3D position of the point at the bottom-center of the screen. * @param {!Cesium.Scene} scene * @return {!Cesium.Cartesian3|undefined} * @api */exports.pickBottomPoint = function(scene) { const canvas = scene.canvas; const bottom = new Cesium.Cartesian2( canvas.clientWidth / 2, canvas.clientHeight); return exports.pickOnTerrainOrEllipsoid(scene, bottom);};
/** * Get the 3D position of the point at the center of the screen. * @param {!Cesium.Scene} scene * @return {!Cesium.Cartesian3|undefined} * @api */exports.pickCenterPoint = function(scene) { const canvas = scene.canvas; const center = new Cesium.Cartesian2( canvas.clientWidth / 2, canvas.clientHeight / 2); return exports.pickOnTerrainOrEllipsoid(scene, center);};
/** * Compute the signed tilt angle on globe, between the opposite of the * camera direction and the target normal. Return undefined if there is no * intersection of the camera direction with the globe. * @param {!Cesium.Scene} scene * @return {number|undefined} * @api */exports.computeSignedTiltAngleOnGlobe = function(scene) { const camera = scene.camera; const ray = new Cesium.Ray(camera.position, camera.direction); let target = scene.globe.pick(ray, scene);
if (!target) { // no tiles in the area were loaded?
const ellipsoid = Cesium.Ellipsoid.WGS84; const obj = Cesium.IntersectionTests.rayEllipsoid(ray, ellipsoid); if (obj) { target = Cesium.Ray.getPoint(ray, obj.start); } }
if (!target) { return undefined; }
const normal = new Cesium.Cartesian3(); Cesium.Ellipsoid.WGS84.geocentricSurfaceNormal(target, normal);
const angleBetween = exports.signedAngleBetween; const angle = angleBetween(camera.direction, normal, camera.right) - Math.PI; return Cesium.Math.convertLongitudeRange(angle);};
/** * Compute the ray from the camera to the bottom-center of the screen. * @param {!Cesium.Scene} scene * @return {!Cesium.Ray} */exports.bottomFovRay = function(scene) { const camera = scene.camera; const fovy2 = camera.frustum.fovy / 2; const direction = camera.direction; const rotation = Cesium.Quaternion.fromAxisAngle(camera.right, fovy2); const matrix = Cesium.Matrix3.fromQuaternion(rotation); const vector = new Cesium.Cartesian3(); Cesium.Matrix3.multiplyByVector(matrix, direction, vector); return new Cesium.Ray(camera.position, vector);};
/** * Compute the angle between two Cartesian3. * @param {!Cesium.Cartesian3} first * @param {!Cesium.Cartesian3} second * @param {!Cesium.Cartesian3} normal Normal to test orientation against. * @return {number} */exports.signedAngleBetween = function(first, second, normal) { // We are using the dot for the angle.
// Then the cross and the dot for the sign.
const a = new Cesium.Cartesian3(); const b = new Cesium.Cartesian3(); const c = new Cesium.Cartesian3(); Cesium.Cartesian3.normalize(first, a); Cesium.Cartesian3.normalize(second, b); Cesium.Cartesian3.cross(a, b, c);
const cosine = Cesium.Cartesian3.dot(a, b); const sine = Cesium.Cartesian3.magnitude(c);
// Sign of the vector product and the orientation normal
const sign = Cesium.Cartesian3.dot(normal, c); const angle = Math.atan2(sine, cosine); return sign >= 0 ? angle : -angle;};
/** * Compute the rotation angle around a given point, needed to reach the * zenith position. * At a zenith position, the camera direction is going througth the earth * center and the frustrum bottom ray is going through the chosen pivot * point. * The bottom-center of the screen is a good candidate for the pivot point. * @param {!Cesium.Scene} scene * @param {!Cesium.Cartesian3} pivot Point around which the camera rotates. * @return {number} * @api */exports.computeAngleToZenith = function(scene, pivot) { // This angle is the sum of the angles 'fy' and 'a', which are defined
// using the pivot point and its surface normal.
// Zenith | camera
// \ | /
// \fy| /
// \ |a/
// \|/pivot
const camera = scene.camera; const fy = camera.frustum.fovy / 2; const ray = exports.bottomFovRay(scene); const direction = Cesium.Cartesian3.clone(ray.direction); Cesium.Cartesian3.negate(direction, direction);
const normal = new Cesium.Cartesian3(); Cesium.Ellipsoid.WGS84.geocentricSurfaceNormal(pivot, normal);
const left = new Cesium.Cartesian3(); Cesium.Cartesian3.negate(camera.right, left);
const a = exports.signedAngleBetween(normal, direction, left); return a + fy;};
/** * Convert an OpenLayers extent to a Cesium rectangle. * @param {ol.Extent} extent Extent. * @param {ol.ProjectionLike} projection Extent projection. * @return {Cesium.Rectangle} The corresponding Cesium rectangle. * @api */exports.extentToRectangle = function(extent, projection) { if (extent && projection) { const ext = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_3__.transformExtent)(extent, projection, 'EPSG:4326'); return Cesium.Rectangle.fromDegrees(ext[0], ext[1], ext[2], ext[3]); } else { return null; }};
/** * @param {!ol.Map} olMap * @param {!ol.source.Source} source * @param {!ol.View} viewProj * @param {!ol.layer.Base} olLayer * @return {!Cesium.ImageryProvider} */exports.sourceToImageryProvider = function(olMap, source, viewProj, olLayer) { const skip = source.get('olcs_skip'); if (skip) { return null; } let provider = null; // Convert ImageWMS to TileWMS
if (source instanceof (ol_source_ImageWMS_js__WEBPACK_IMPORTED_MODULE_5___default()) && source.getUrl() && source.getImageLoadFunction() === ol_source_Image_js__WEBPACK_IMPORTED_MODULE_9__.defaultImageLoadFunction) { const sourceProps = { 'olcs.proxy': source.get('olcs.proxy'), 'olcs.extent': source.get('olcs.extent'), 'olcs.projection': source.get('olcs.projection'), 'olcs.imagesource': source }; source = new (ol_source_TileWMS_js__WEBPACK_IMPORTED_MODULE_7___default())({ url: source.getUrl(), attributions: source.getAttributions(), projection: source.getProjection(), params: source.getParams() }); source.setProperties(sourceProps); }
if (source instanceof (ol_source_TileImage_js__WEBPACK_IMPORTED_MODULE_6___default())) { let projection = _util_js__WEBPACK_IMPORTED_MODULE_11__["default"].getSourceProjection(source);
if (!projection) { // if not explicit, assume the same projection as view
projection = viewProj; }
if (exports.isCesiumProjection(projection)) { provider = new _core_OLImageryProvider_js__WEBPACK_IMPORTED_MODULE_10__["default"](olMap, source, viewProj); } // Projection not supported by Cesium
else { return null; } } else if (source instanceof (ol_source_ImageStatic_js__WEBPACK_IMPORTED_MODULE_4___default())) { let projection = _util_js__WEBPACK_IMPORTED_MODULE_11__["default"].getSourceProjection(source); if (!projection) { projection = viewProj; } if (exports.isCesiumProjection(projection)) { provider = new Cesium.SingleTileImageryProvider({ url: source.getUrl(), rectangle: new Cesium.Rectangle.fromDegrees( source.getImageExtent()[0], source.getImageExtent()[1], source.getImageExtent()[2], source.getImageExtent()[3] ) }); } // Projection not supported by Cesium
else { return null; } } else if (source instanceof (ol_source_VectorTile_js__WEBPACK_IMPORTED_MODULE_8___default())) { let projection = _util_js__WEBPACK_IMPORTED_MODULE_11__["default"].getSourceProjection(source);
if (!projection) { projection = viewProj; } if (skip === false) { // MVT is experimental, it should be whitelisted to be synchronized
const fromCode = projection.getCode().split(':')[1]; const urls = source.urls.map(u => u.replace(fromCode, '3857')); const extent = olLayer.getExtent(); const rectangle = exports.extentToRectangle(extent, projection); const minimumLevel = source.get('olcs_minimumLevel'); const attributionsFunction = source.getAttributions(); const styleFunction = olLayer.getStyleFunction(); let credit; if (extent && attributionsFunction) { const center = (0,ol_extent__WEBPACK_IMPORTED_MODULE_14__.getCenter)(extent); credit = attributionsFunctionToCredits(attributionsFunction, 0, center, extent)[0]; }
provider = new _MVTImageryProvider_js__WEBPACK_IMPORTED_MODULE_12__["default"]({ credit, rectangle, minimumLevel, styleFunction, urls }); return provider; } return null; // FIXME: it is disabled by default right now
} else { // sources other than TileImage|ImageStatic are currently not supported
return null; } return provider;};
/** * Creates Cesium.ImageryLayer best corresponding to the given ol.layer.Layer. * Only supports raster layers and static images * @param {!ol.Map} olMap * @param {!ol.layer.Base} olLayer * @param {!ol.proj.Projection} viewProj Projection of the view. * @return {?Cesium.ImageryLayer} null if not possible (or supported) * @api */exports.tileLayerToImageryLayer = function(olMap, olLayer, viewProj) {
if (!(olLayer instanceof (ol_layer_Tile_js__WEBPACK_IMPORTED_MODULE_1___default())) && !(olLayer instanceof (ol_layer_Image_js__WEBPACK_IMPORTED_MODULE_2___default())) && !(olLayer instanceof (ol_layer_VectorTile_js__WEBPACK_IMPORTED_MODULE_13___default()))) { return null; }
const source = olLayer.getSource(); if (!source) { return null; } let provider = source.get('olcs_provider'); if (!provider) { provider = this.sourceToImageryProvider(olMap, source, viewProj, olLayer); } if (!provider) { return null; }
const layerOptions = {};
const forcedExtent = /** @type {ol.Extent} */ (olLayer.get('olcs.extent')); const ext = forcedExtent || olLayer.getExtent(); if (ext) { layerOptions.rectangle = exports.extentToRectangle(ext, viewProj); }
const cesiumLayer = new Cesium.ImageryLayer(provider, layerOptions); return cesiumLayer;};
/** * Synchronizes the layer rendering properties (opacity, visible) * to the given Cesium ImageryLayer. * @param {olcsx.LayerWithParents} olLayerWithParents * @param {!Cesium.ImageryLayer} csLayer * @api */exports.updateCesiumLayerProperties = function(olLayerWithParents, csLayer) { let opacity = 1; let visible = true; [olLayerWithParents.layer].concat(olLayerWithParents.parents).forEach((olLayer) => { const layerOpacity = olLayer.getOpacity(); if (layerOpacity !== undefined) { opacity *= layerOpacity; } const layerVisible = olLayer.getVisible(); if (layerVisible !== undefined) { visible &= layerVisible; } }); csLayer.alpha = opacity; csLayer.show = visible;};
/** * Convert a 2D or 3D OpenLayers coordinate to Cesium. * @param {ol.Coordinate} coordinate Ol3 coordinate. * @return {!Cesium.Cartesian3} Cesium cartesian coordinate * @api */exports.ol4326CoordinateToCesiumCartesian = function(coordinate) { const coo = coordinate; return coo.length > 2 ? Cesium.Cartesian3.fromDegrees(coo[0], coo[1], coo[2]) : Cesium.Cartesian3.fromDegrees(coo[0], coo[1]);};
/** * Convert an array of 2D or 3D OpenLayers coordinates to Cesium. * @param {Array.<!ol.Coordinate>} coordinates Ol3 coordinates. * @return {!Array.<Cesium.Cartesian3>} Cesium cartesian coordinates * @api */exports.ol4326CoordinateArrayToCsCartesians = function(coordinates) { console.assert(coordinates !== null); const toCartesian = exports.ol4326CoordinateToCesiumCartesian; const cartesians = []; for (let i = 0; i < coordinates.length; ++i) { cartesians.push(toCartesian(coordinates[i])); } return cartesians;};
/** * Reproject an OpenLayers geometry to EPSG:4326 if needed. * The geometry will be cloned only when original projection is not EPSG:4326 * and the properties will be shallow copied. * @param {!T} geometry * @param {!ol.ProjectionLike} projection * @return {!T} * @template T * @api */exports.olGeometryCloneTo4326 = function(geometry, projection) { console.assert(projection);
const proj4326 = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_3__.get)('EPSG:4326'); const proj = (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_3__.get)(projection); if (proj !== proj4326) { const properties = geometry.getProperties(); geometry = geometry.clone(); geometry.transform(proj, proj4326); geometry.setProperties(properties); } return geometry;};
/** * Convert an OpenLayers color to Cesium. * @param {ol.Color|CanvasGradient|CanvasPattern|string} olColor * @return {!Cesium.Color} * @api */exports.convertColorToCesium = function(olColor) { olColor = olColor || 'black'; if (Array.isArray(olColor)) { return new Cesium.Color( Cesium.Color.byteToFloat(olColor[0]), Cesium.Color.byteToFloat(olColor[1]), Cesium.Color.byteToFloat(olColor[2]), olColor[3] ); } else if (typeof olColor == 'string') { return Cesium.Color.fromCssColorString(olColor); } else if (olColor instanceof CanvasPattern || olColor instanceof CanvasGradient) { // Render the CanvasPattern/CanvasGradient into a canvas that will be sent to Cesium as material
const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = canvas.height = 256; ctx.fillStyle = olColor; ctx.fillRect(0, 0, canvas.width, canvas.height); return new Cesium.ImageMaterialProperty({ image: canvas }); } console.assert(false, 'impossible');};
/** * Convert an OpenLayers url to Cesium. * @param {string} url * @return {!CesiumUrlDefinition} * @api */exports.convertUrlToCesium = function(url) { let subdomains = ''; const re = /\{(\d|[a-z])-(\d|[a-z])\}/; const match = re.exec(url); if (match) { url = url.replace(re, '{s}'); const startCharCode = match[1].charCodeAt(0); const stopCharCode = match[2].charCodeAt(0); let charCode; for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) { subdomains += String.fromCharCode(charCode); } } return { url, subdomains };};
/** * Animate the return to a top-down view from the zenith. * The camera is rotated to orient to the North. * @param {!ol.Map} map * @param {!Cesium.Scene} scene * @return {Promise<undefined>} * @api */exports.resetToNorthZenith = function(map, scene) { return new Promise((resolve, reject) => { const camera = scene.camera; const pivot = exports.pickBottomPoint(scene); if (!pivot) { reject('Could not get bottom pivot'); return; }
const currentHeading = map.getView().getRotation(); if (currentHeading === undefined) { reject('The view is not initialized'); return; } const angle = exports.computeAngleToZenith(scene, pivot);
// Point to North
exports.setHeadingUsingBottomCenter(scene, currentHeading, pivot);
// Go to zenith
const transform = Cesium.Matrix4.fromTranslation(pivot); const axis = camera.right; const options = { callback: () => { const view = map.getView(); exports.normalizeView(view); resolve(); } }; exports.rotateAroundAxis(camera, -angle, axis, transform, options); });};
/** * @param {!Cesium.Scene} scene * @param {number} angle in radian * @return {Promise<undefined>} * @api */exports.rotateAroundBottomCenter = function(scene, angle) { return new Promise((resolve, reject) => { const camera = scene.camera; const pivot = exports.pickBottomPoint(scene); if (!pivot) { reject('could not get bottom pivot'); return; }
const options = {callback: resolve}; const transform = Cesium.Matrix4.fromTranslation(pivot); const axis = camera.right; const rotateAroundAxis = exports.rotateAroundAxis; rotateAroundAxis(camera, -angle, axis, transform, options); });};
/** * Set the OpenLayers view to a specific rotation and * the nearest resolution. * @param {ol.View} view * @param {number=} angle * @api */exports.normalizeView = function(view, angle = 0) { const resolution = view.getResolution(); view.setRotation(angle); if (view.constrainResolution) { view.setResolution(view.constrainResolution(resolution)); } else { view.setResolution(view.getConstrainedResolution(resolution)); }};
/** * Check if the given projection is managed by Cesium (WGS84 or Mercator Spheric) * * @param {ol.proj.Projection} projection Projection to check. * @returns {boolean} Whether it's managed by Cesium. */exports.isCesiumProjection = function(projection) { const is3857 = projection === (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_3__.get)('EPSG:3857'); const is4326 = projection === (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_3__.get)('EPSG:4326'); return is3857 || is4326;};
function attributionsFunctionToCredits(attributionsFunction, zoom, center, extent) { const frameState = { viewState: {zoom, center}, extent, };
if (!attributionsFunction) { return []; } let attributions = attributionsFunction(frameState); if (!Array.isArray(attributions)) { attributions = [attributions]; }
return attributions.map(html => new Cesium.Credit(html, true));}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (exports);
/** * 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. * @param {import('cesium').Scene} scene. * @param {import('ol/proj/Projection').default} projection View projection. * @return {number} The calculated distance. * @api */function calcDistanceForResolution(resolution, latitude, scene, projection) { const canvas = scene.canvas; const camera = scene.camera; const fovy = camera.frustum.fovy; // vertical field of view
console.assert(!isNaN(fovy)); const metersPerUnit = projection.getMetersPerUnit();
// number of "map units" visible in 2D (vertically)
const 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.
const relativeCircumference = Math.cos(Math.abs(latitude));
// how many meters should be visible in 3D
const visibleMeters = visibleMapUnits * metersPerUnit * relativeCircumference;
// distance required to view the calculated length in meters
//
// fovy/2
// |\
// x | \
// |--\
// visibleMeters/2
const 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 * @param {import('cesium').Scene} scene. * @param {import('ol/proj/Projection').default} projection View projection. * @return {number} The calculated resolution. * @api */function calcResolutionForDistance(distance, latitude, scene, projection) { // See the reverse calculation (calcDistanceForResolution) for details
const canvas = scene.canvas; const camera = scene.camera; const fovy = camera.frustum.fovy; // vertical field of view
console.assert(!isNaN(fovy)); const metersPerUnit = projection.getMetersPerUnit();
const visibleMeters = 2 * distance * Math.tan(fovy / 2); const relativeCircumference = Math.cos(Math.abs(latitude)); const visibleMapUnits = visibleMeters / metersPerUnit / relativeCircumference; const resolution = visibleMapUnits / canvas.clientHeight;
return resolution;}
/***/ }),
/***/ "./src/olcs/core/OLImageryProvider.js":/*!********************************************!*\ !*** ./src/olcs/core/OLImageryProvider.js ***! \********************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ol/proj.js */ "ol/proj.js");/* harmony import */ var ol_proj_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ol_proj_js__WEBPACK_IMPORTED_MODULE_0__);/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util.js */ "./src/olcs/util.js");/* harmony import */ var ol_source_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ol/source.js */ "ol/source.js");/* harmony import */ var ol_source_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ol_source_js__WEBPACK_IMPORTED_MODULE_2__);/* harmony import */ var _core_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../core.js */ "./src/olcs/core.js");/** * @module olcs.core.OLImageryProvider */
const olUseNewCoordinates = (function() { const tileSource = new ol_source_js__WEBPACK_IMPORTED_MODULE_2__.Tile({ projection: 'EPSG:3857', wrapX: true }); const tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]); return tileCoord && tileCoord[1] === 33 && tileCoord[2] === 22; // See b/test/spec/ol/source/tile.test.js
// of e9a30c5cb7e3721d9370025fbe5472c322847b35 in OpenLayers repository
})();
class OLImageryProvider /* should not extend Cesium.ImageryProvider */ { /** * Special class derived from Cesium.ImageryProvider * that is connected to the given ol.source.TileImage. * @param {!ol.Map} olMap * @param {!ol.source.TileImage} source * @param {ol.proj.Projection=} opt_fallbackProj Projection to assume if the * projection of the source is not defined. * @constructor * @extends {Cesium.ImageryProvider} */ constructor(olMap, source, opt_fallbackProj) { // Do not extend or call super constructor from
// Cesium.ImageryProvider since this particular function is a
// 'non instanciable interface' which throws on instanciation.
/** * @type {!ol.source.TileImage} * @private */ this.source_ = source;
/** * @type {?ol.proj.Projection} * @private */ this.projection_ = null;
/** * @type {?ol.proj.Projection} * @private */ this.fallbackProj_ = opt_fallbackProj || null;
/** * @type {boolean} * @private */ this.ready_ = false;
/** * @type {?Cesium.TilingScheme} * @private */ this.tilingScheme_ = null;
/** * @type {?Cesium.Rectangle} * @private */ this.rectangle_ = null;
/** * @type {!ol.Map} * @private */ this.map_ = olMap;
/** * @type {boolean} * @private */ this.shouldRequestNextLevel = false;
const proxy = this.source_.get('olcs.proxy'); if (proxy) { if (typeof proxy === 'function') { this.proxy_ = { 'getURL': proxy }; } else if (typeof proxy === 'string') { this.proxy_ = new Cesium.DefaultProxy(proxy); } }
this.errorEvent_ = new Cesium.Event();
this.emptyCanvas_ = document.createElement('canvas'); this.emptyCanvas_.width = 1; this.emptyCanvas_.height = 1;
this.source_.on('change', (e) => { this.handleSourceChanged_(); }); this.handleSourceChanged_(); }
/** * Checks if the underlying source is ready and cached required data. * @private */ handleSourceChanged_(frameState) { if (!this.ready_ && this.source_.getState() == 'ready') { this.projection_ = _util_js__WEBPACK_IMPORTED_MODULE_1__["default"].getSourceProjection(this.source_) || this.fallbackProj_; const options = {numberOfLevelZeroTilesX: 1, numberOfLevelZeroTilesY: 1};
if (this.source_.tileGrid !== null) { // Get the number of tiles at level 0 if it is defined
this.source_.tileGrid.forEachTileCoord(this.projection_.getExtent(), 0, ([zoom, xIndex, yIndex]) => { options.numberOfLevelZeroTilesX = xIndex + 1; options.numberOfLevelZeroTilesY = yIndex + 1; }); }
if (this.projection_ == (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_0__.get)('EPSG:4326')) { // Cesium zoom level 0 is OpenLayers zoom level 1 for layer in EPSG:4326 with a single tile on level 0
this.shouldRequestNextLevel = options.numberOfLevelZeroTilesX === 1 && options.numberOfLevelZeroTilesY === 1; this.tilingScheme_ = new Cesium.GeographicTilingScheme(options); } else if (this.projection_ == (0,ol_proj_js__WEBPACK_IMPORTED_MODULE_0__.get)('EPSG:3857')) { this.shouldRequestNextLevel = false; this.tilingScheme_ = new Cesium.WebMercatorTilingScheme(options); } else { return; } this.rectangle_ = this.tilingScheme_.rectangle;
this.ready_ = true; } }
/** * Generates the proper attributions for a given position and zoom * level. * @export * @override */ getTileCredits(x, y, level) { const attributionsFunction = this.source_.getAttributions(); if (!attributionsFunction) { return []; } const extent = this.map_.getView().calculateExtent(this.map_.getSize()); const center = this.map_.getView().getCenter(); const zoom = this.shouldRequestNextLevel ? level + 1 : level; return (0,_core_js__WEBPACK_IMPORTED_MODULE_3__.attributionsFunctionToCredits)(attributionsFunction, zoom, center, extent); }
/** * @export * @override */ requestImage(x, y, level) { const tileUrlFunction = this.source_.getTileUrlFunction(); if (tileUrlFunction && this.projection_) {
const z_ = this.shouldRequestNextLevel ? level + 1 : level;
let y_ = y; if (!olUseNewCoordinates) { // OpenLayers version 3 to 5 tile coordinates increase from bottom to top
y_ = -y - 1; } let url = tileUrlFunction.call(this.source_, [z_, x, y_], 1, this.projection_); if (this.proxy_) { url = this.proxy_.getURL(url); } return url ? Cesium.ImageryProvider.loadImage(this, url) : this.emptyCanvas_; } else { // return empty canvas to stop Cesium from retrying later
return this.emptyCanvas_; } }}
// definitions of getters that are required to be present
// in the Cesium.ImageryProvider instance:
Object.defineProperties(OLImageryProvider.prototype, { 'ready': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() {return this.ready_;} },
'rectangle': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() {return this.rectangle_;} },
'tileWidth': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() { const tg = this.source_.getTileGrid(); return tg ? (Array.isArray(tg.getTileSize(0)) ? tg.getTileSize(0)[0] : tg.getTileSize(0)) : 256; } },
'tileHeight': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() { const tg = this.source_.getTileGrid(); return tg ? (Array.isArray(tg.getTileSize(0)) ? tg.getTileSize(0)[1] : tg.getTileSize(0)) : 256; } },
'maximumLevel': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() { const tg = this.source_.getTileGrid(); return tg ? tg.getMaxZoom() : 18; } },
'minimumLevel': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() { // WARNING: Do not use the minimum level (at least until the extent is
// properly set). Cesium assumes the minimumLevel to contain only
// a few tiles and tries to load them all at once -- this can
// freeze and/or crash the browser !
return 0; //var tg = this.source_.getTileGrid();
//return tg ? tg.getMinZoom() : 0;
} },
'tilingScheme': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() {return this.tilingScheme_;} },
'tileDiscardPolicy': { 'get': function() {return undefined;} },
'errorEvent': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() {return this.errorEvent_;} },
'proxy': { 'get': /** @this {olcs.core.OLImageryProvider} */ function() {return this.proxy_;} },
'hasAlphaChannel': { 'get': function() {return true;} },
'pickFeatures': { 'get': function() {return undefined;} }});
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (OLImageryProvider);
/***/ }),
/***/ "./src/olcs/core/VectorLayerCounterpart.js":/*!*************************************************!*\ !*** ./src/olcs/core/VectorLayerCounterpart.js ***! \*************************************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* 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__);/** * @module olcs.core.VectorLayerCounterpart */
/** * Context for feature conversion. * @typedef {Object} OlFeatureToCesiumContext * @property {!(import('ol/Projection.js').default|string)} projection * @property {!Cesium.PrimitiveCollection} primitives * @property {Object<number, Array<!Cesium.Primitive|!Cesium.Billboard>>} featureToCesiumMap * @property {!Cesium.BillboardCollection} billboards */
class VectorLayerCounterpart { /** * Result of the conversion of an OpenLayers layer to Cesium. * @param {!(ol.proj.Projection|string)} layerProjection * @param {!Cesium.Scene} scene */ constructor(layerProjection, scene) { const billboards = new Cesium.BillboardCollection({scene}); const primitives = new Cesium.PrimitiveCollection();
/** * @type {!Array.<ol.EventsKey>} */ this.olListenKeys = [];
this.rootCollection_ = new Cesium.PrimitiveCollection(); /** * @type {!OlFeatureToCesiumContext} */ this.context = { projection: layerProjection, billboards, featureToCesiumMap: {}, primitives };
this.rootCollection_.add(billboards); this.rootCollection_.add(primitives); }
/** * Unlisten. */ destroy() { this.olListenKeys.forEach(ol_Observable_js__WEBPACK_IMPORTED_MODULE_0__.unByKey); this.olListenKeys.length = 0; }
/** * @return {!Cesium.Primitive} */ getRootPrimitive() { return this.rootCollection_; }}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (VectorLayerCounterpart);
/***/ }),
/***/ "./src/olcs/math.js":/*!**************************!*\ !*** ./src/olcs/math.js ***! \**************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "toDegrees": () => (/* binding */ toDegrees),/* harmony export */ "toRadians": () => (/* binding */ toRadians)/* harmony export */ });/** * Converts radians to to degrees. * * @param {number} angleInRadians Angle in radians. * @return {number} Angle in degrees. */function toDegrees(angleInRadians) { return angleInRadians * 180 / Math.PI;}
/** * Converts degrees to radians. * * @param {number} angleInDegrees Angle in degrees. * @return {number} Angle in radians. */function toRadians(angleInDegrees) { return angleInDegrees * Math.PI / 180;}
/***/ }),
/***/ "./src/olcs/util.js":/*!**************************!*\ !*** ./src/olcs/util.js ***! \**************************//***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),/* harmony export */ "getUid": () => (/* binding */ getUid),/* harmony export */ "isGroundPolylinePrimitiveSupported": () => (/* binding */ isGroundPolylinePrimitiveSupported),/* harmony export */ "olcsListen": () => (/* binding */ olcsListen),/* harmony export */ "removeChildren": () => (/* binding */ removeChildren),/* harmony export */ "removeNode": () => (/* binding */ removeNode),/* harmony export */ "stableSort": () => (/* binding */ stableSort)/* harmony export */ });/** * @module olcs.util */const exports = {};
/** * Cast to object. * @param {Object} param * @return {Object} */exports.obj = function(param) { return param;};
/** * @type {boolean|undefined} * @private */exports.supportsImageRenderingPixelatedResult_ = undefined;
/** * @type {string|undefined} * @private */exports.imageRenderingValueResult_ = undefined;
/** * @return {boolean} */exports.supportsImageRenderingPixelated = function() { if (exports.supportsImageRenderingPixelatedResult_ === undefined) { const canvas = document.createElement('canvas'); canvas.setAttribute('style', 'image-rendering: -moz-crisp-edges; image-rendering: pixelated;'); // canvas.style.imageRendering will be undefined, null or an
// empty string on unsupported browsers.
const tmp = canvas.style['imageRendering']; // non standard
exports.supportsImageRenderingPixelatedResult_ = !!tmp; if (exports.supportsImageRenderingPixelatedResult_) { exports.imageRenderingValueResult_ = tmp; } } return exports.supportsImageRenderingPixelatedResult_;};
/** * @return {string} */exports.imageRenderingValue = function() { exports.supportsImageRenderingPixelated(); return exports.imageRenderingValueResult_ || '';};
/** * Return the projection of the source that Cesium should use. * * @param {ol.source.Source} source Source. * @returns {ol.proj.Projection} The projection of the source. */exports.getSourceProjection = function(source) { return /** @type {ol.proj.Projection} */ (source.get('olcs.projection')) || source.getProjection();};
/** * @param {ol.Observable} observable * @param {string} type * @param {Function} listener * @return {!ol.events.EventsKey} */function olcsListen(observable, type, listener) { // See https://github.com/openlayers/openlayers/pull/8481
// ol.events.listen is internal so we use `on` instead.
// And since `on` as a convoluted API (can return an EventsKey or an array of them)
// we use a cast here.
return /** @type {!ol.events.EventsKey} */ (observable.on(type, listener));}
/** * Counter for getUid. * @type {number} */let uidCounter_ = 0;
/** * Gets a unique ID for an object. This mutates the object so that further calls * with the same object as a parameter returns the same value. Unique IDs are generated * as a strictly increasing sequence. Adapted from goog.getUid. * * @param {Object} obj The object to get the unique ID for. * @return {number} The unique ID for the object. */function getUid(obj) { return obj.olcs_uid || (obj.olcs_uid = ++uidCounter_);}
/** * Sort the passed array such that the relative order of equal elements is preverved. * See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.
* @param {Array<*>} arr The array to sort (modifies original). * @param {!function(*, *): number} compareFnc Comparison function. */function stableSort(arr, compareFnc) { const length = arr.length; const tmp = Array(arr.length); for (let i = 0; i < length; i++) { tmp[i] = {index: i, value: arr[i]}; } tmp.sort((a, b) => compareFnc(a.value, b.value) || a.index - b.index); for (let i = 0; i < arr.length; i++) { arr[i] = tmp[i].value; }}
/** * @param {Node} node The node to remove. * @returns {Node} The node that was removed or null. */function removeNode(node) { return node && node.parentNode ? node.parentNode.removeChild(node) : null;}
/** * @param {Node} node The node to remove the children from. */function removeChildren(node) { while (node.lastChild) { node.removeChild(node.lastChild); }}
/** * @param {Cesium.Scene} scene The scene. */function isGroundPolylinePrimitiveSupported(scene) { const obj = Cesium.GroundPolylinePrimitive; return obj && obj.isSupported(scene);}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (exports);
/***/ }),
/***/ "ol/Observable.js":/*!********************************!*\ !*** external "ol.Observable" ***! \********************************//***/ ((module) => {
module.exports = ol.Observable;
/***/ }),
/***/ "ol/Overlay.js":/*!*****************************!*\ !*** external "ol.Overlay" ***! \*****************************//***/ ((module) => {
module.exports = ol.Overlay;
/***/ }),
/***/ "ol/easing.js":/*!****************************!*\ !*** external "ol.easing" ***! \****************************//***/ ((module) => {
module.exports = ol.easing;
/***/ }),
/***/ "ol/extent":/*!****************************!*\ !*** external "ol.extent" ***! \****************************//***/ ((module) => {
module.exports = ol.extent;
/***/ }),
/***/ "ol/format/MVT.js":/*!********************************!*\ !*** external "ol.format.MVT" ***! \********************************//***/ ((module) => {
module.exports = ol.format.MVT;
/***/ }),
/***/ "ol/geom/Geometry.js":/*!***********************************!*\ !*** external "ol.geom.Geometry" ***! \***********************************//***/ ((module) => {
module.exports = ol.geom.Geometry;
/***/ }),
/***/ "ol/geom/Point.js":/*!********************************!*\ !*** external "ol.geom.Point" ***! \********************************//***/ ((module) => {
module.exports = ol.geom.Point;
/***/ }),
/***/ "ol/geom/Polygon.js":/*!**********************************!*\ !*** external "ol.geom.Polygon" ***! \**********************************//***/ ((module) => {
module.exports = ol.geom.Polygon;
/***/ }),
/***/ "ol/geom/SimpleGeometry.js":/*!*****************************************!*\ !*** external "ol.geom.SimpleGeometry" ***! \*****************************************//***/ ((module) => {
module.exports = ol.geom.SimpleGeometry;
/***/ }),
/***/ "ol/layer/Group.js":/*!*********************************!*\ !*** external "ol.layer.Group" ***! \*********************************//***/ ((module) => {
module.exports = ol.layer.Group;
/***/ }),
/***/ "ol/layer/Image.js":/*!*********************************!*\ !*** external "ol.layer.Image" ***! \*********************************//***/ ((module) => {
module.exports = ol.layer.Image;
/***/ }),
/***/ "ol/layer/Layer.js":/*!*********************************!*\ !*** external "ol.layer.Layer" ***! \*********************************//***/ ((module) => {
module.exports = ol.layer.Layer;
/***/ }),
/***/ "ol/layer/Tile.js":/*!********************************!*\ !*** external "ol.layer.Tile" ***! \********************************//***/ ((module) => {
module.exports = ol.layer.Tile;
/***/ }),
/***/ "ol/layer/Vector.js":/*!**********************************!*\ !*** external "ol.layer.Vector" ***! \**********************************//***/ ((module) => {
module.exports = ol.layer.Vector;
/***/ }),
/***/ "ol/layer/VectorTile.js":/*!**************************************!*\ !*** external "ol.layer.VectorTile" ***! \**************************************//***/ ((module) => {
module.exports = ol.layer.VectorTile;
/***/ }),
/***/ "ol/proj.js":/*!**************************!*\ !*** external "ol.proj" ***! \**************************//***/ ((module) => {
module.exports = ol.proj;
/***/ }),
/***/ "ol/render.js":/*!****************************!*\ !*** external "ol.render" ***! \****************************//***/ ((module) => {
module.exports = ol.render;
/***/ }),
/***/ "ol/source.js":/*!****************************!*\ !*** external "ol.source" ***! \****************************//***/ ((module) => {
module.exports = ol.source;
/***/ }),
/***/ "ol/source/Cluster.js":/*!************************************!*\ !*** external "ol.source.Cluster" ***! \************************************//***/ ((module) => {
module.exports = ol.source.Cluster;
/***/ }),
/***/ "ol/source/Image.js":/*!**********************************!*\ !*** external "ol.source.Image" ***! \**********************************//***/ ((module) => {
module.exports = ol.source.Image;
/***/ }),
/***/ "ol/source/ImageStatic.js":/*!****************************************!*\ !*** external "ol.source.ImageStatic" ***! \****************************************//***/ ((module) => {
module.exports = ol.source.ImageStatic;
/***/ }),
/***/ "ol/source/ImageWMS.js":/*!*************************************!*\ !*** external "ol.source.ImageWMS" ***! \*************************************//***/ ((module) => {
module.exports = ol.source.ImageWMS;
/***/ }),
/***/ "ol/source/TileImage.js":/*!**************************************!*\ !*** external "ol.source.TileImage" ***! \**************************************//***/ ((module) => {
module.exports = ol.source.TileImage;
/***/ }),
/***/ "ol/source/TileWMS.js":/*!************************************!*\ !*** external "ol.source.TileWMS" ***! \************************************//***/ ((module) => {
module.exports = ol.source.TileWMS;
/***/ }),
/***/ "ol/source/Vector.js":/*!***********************************!*\ !*** external "ol.source.Vector" ***! \***********************************//***/ ((module) => {
module.exports = ol.source.Vector;
/***/ }),
/***/ "ol/source/VectorTile.js":/*!***************************************!*\ !*** external "ol.source.VectorTile" ***! \***************************************//***/ ((module) => {
module.exports = ol.source.VectorTile;
/***/ }),
/***/ "ol/structs/LRUCache.js":/*!**************************************!*\ !*** external "ol.structs.LRUCache" ***! \**************************************//***/ ((module) => {
module.exports = ol.structs.LRUCache;
/***/ }),
/***/ "ol/style/Icon.js":/*!********************************!*\ !*** external "ol.style.Icon" ***! \********************************//***/ ((module) => {
module.exports = ol.style.Icon;
/***/ }),
/***/ "ol/style/Stroke.js":/*!**********************************!*\ !*** external "ol.style.Stroke" ***! \**********************************//***/ ((module) => {
module.exports = ol.style.Stroke;
/***/ }),
/***/ "ol/style/Style.js":/*!*********************************!*\ !*** external "ol.style.Style" ***! \*********************************//***/ ((module) => {
module.exports = ol.style.Style;
/***/ }),
/***/ "ol/tilegrid.js":/*!******************************!*\ !*** external "ol.tilegrid" ***! \******************************//***/ ((module) => {
module.exports = ol.tilegrid;
/***/ }),
/***/ "ol/tileurlfunction.js":/*!*************************************!*\ !*** external "ol.tileurlfunction" ***! \*************************************//***/ ((module) => {
module.exports = ol.tileurlfunction;
/***/ }),
/***/ "ol/util.js":/*!**************************!*\ !*** external "ol.util" ***! \**************************//***/ ((module) => {
module.exports = ol.util;
/***/ })
/******/ });/************************************************************************//******/ // The module cache
/******/ var __webpack_module_cache__ = {};/******//******/ // The require function
/******/ function __webpack_require__(moduleId) {/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];/******/ if (cachedModule !== undefined) {/******/ return cachedModule.exports;/******/ }/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}/******/ };/******//******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);/******//******/ // Return the exports of the module
/******/ return module.exports;/******/ }/******//************************************************************************//******/ /* webpack/runtime/compat get default export *//******/ (() => {/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {/******/ var getter = module && module.__esModule ?/******/ () => (module['default']) :/******/ () => (module);/******/ __webpack_require__.d(getter, { a: getter });/******/ return getter;/******/ };/******/ })();/******//******/ /* webpack/runtime/define property getters *//******/ (() => {/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {/******/ for(var key in definition) {/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });/******/ }/******/ }/******/ };/******/ })();/******//******/ /* webpack/runtime/hasOwnProperty shorthand *//******/ (() => {/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))/******/ })();/******//******/ /* webpack/runtime/make namespace object *//******/ (() => {/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });/******/ }/******/ Object.defineProperty(exports, '__esModule', { value: true });/******/ };/******/ })();/******//************************************************************************/var __webpack_exports__ = {};// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {/*!******************************!*\ !*** ./src/index.library.js ***! \******************************/__webpack_require__.r(__webpack_exports__);/* harmony export */ __webpack_require__.d(__webpack_exports__, {/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)/* harmony export */ });/* 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 */ const __WEBPACK_DEFAULT_EXPORT__ = (_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"];
})();
olcs_unused_var = __webpack_exports__;/******/ })();//# sourceMappingURL=olcesium-debug.js.map
|