UNPKG

c8y-openlayer

Version:

This module is designed to help integrate Openlayer with Cumulocity IoT

297 lines (262 loc) 9.15 kB
import _ol_ from './index.js'; import _ol_Tile_ from './tile.js'; import _ol_TileState_ from './tilestate.js'; import _ol_dom_ from './dom.js'; import _ol_events_ from './events.js'; import _ol_extent_ from './extent.js'; import _ol_events_EventType_ from './events/eventtype.js'; import _ol_featureloader_ from './featureloader.js'; /** * @constructor * @extends {ol.Tile} * @param {ol.TileCoord} tileCoord Tile coordinate. * @param {ol.TileState} state State. * @param {number} sourceRevision Source revision. * @param {ol.format.Feature} format Feature format. * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function. * @param {ol.TileCoord} urlTileCoord Wrapped tile coordinate for source urls. * @param {ol.TileUrlFunctionType} tileUrlFunction Tile url function. * @param {ol.tilegrid.TileGrid} sourceTileGrid Tile grid of the source. * @param {ol.tilegrid.TileGrid} tileGrid Tile grid of the renderer. * @param {Object.<string,ol.VectorTile>} sourceTiles Source tiles. * @param {number} pixelRatio Pixel ratio. * @param {ol.proj.Projection} projection Projection. * @param {function(new: ol.VectorTile, ol.TileCoord, ol.TileState, string, * ol.format.Feature, ol.TileLoadFunctionType)} tileClass Class to * instantiate for source tiles. * @param {function(this: ol.source.VectorTile, ol.events.Event)} handleTileChange * Function to call when a source tile's state changes. * @param {olx.TileOptions=} opt_options Tile options. */ var _ol_VectorImageTile_ = function(tileCoord, state, sourceRevision, format, tileLoadFunction, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, sourceTiles, pixelRatio, projection, tileClass, handleTileChange, opt_options) { _ol_Tile_.call(this, tileCoord, state, opt_options); /** * @private * @type {Object.<string, CanvasRenderingContext2D>} */ this.context_ = {}; /** * @private * @type {ol.FeatureLoader} */ this.loader_; /** * @private * @type {Object.<string, ol.TileReplayState>} */ this.replayState_ = {}; /** * @private * @type {Object.<string,ol.VectorTile>} */ this.sourceTiles_ = sourceTiles; /** * Keys of source tiles used by this tile. Use with {@link #getTile}. * @type {Array.<string>} */ this.tileKeys = []; /** * @type {number} */ this.sourceRevision_ = sourceRevision; /** * @type {ol.TileCoord} */ this.wrappedTileCoord = urlTileCoord; /** * @type {Array.<ol.EventsKey>} */ this.loadListenerKeys_ = []; /** * @type {Array.<ol.EventsKey>} */ this.sourceTileListenerKeys_ = []; if (urlTileCoord) { var extent = tileGrid.getTileCoordExtent(urlTileCoord); var resolution = tileGrid.getResolution(tileCoord[0]); var sourceZ = sourceTileGrid.getZForResolution(resolution); sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) { var sharedExtent = _ol_extent_.getIntersection(extent, sourceTileGrid.getTileCoordExtent(sourceTileCoord)); var sourceExtent = sourceTileGrid.getExtent(); if (sourceExtent) { sharedExtent = _ol_extent_.getIntersection(sharedExtent, sourceExtent); } if (_ol_extent_.getWidth(sharedExtent) / resolution >= 0.5 && _ol_extent_.getHeight(sharedExtent) / resolution >= 0.5) { // only include source tile if overlap is at least 1 pixel var sourceTileKey = sourceTileCoord.toString(); var sourceTile = sourceTiles[sourceTileKey]; if (!sourceTile) { var tileUrl = tileUrlFunction(sourceTileCoord, pixelRatio, projection); sourceTile = sourceTiles[sourceTileKey] = new tileClass(sourceTileCoord, tileUrl == undefined ? _ol_TileState_.EMPTY : _ol_TileState_.IDLE, tileUrl == undefined ? '' : tileUrl, format, tileLoadFunction); this.sourceTileListenerKeys_.push( _ol_events_.listen(sourceTile, _ol_events_EventType_.CHANGE, handleTileChange)); } sourceTile.consumers++; this.tileKeys.push(sourceTileKey); } }.bind(this)); } }; _ol_.inherits(_ol_VectorImageTile_, _ol_Tile_); /** * @inheritDoc */ _ol_VectorImageTile_.prototype.disposeInternal = function() { for (var i = 0, ii = this.tileKeys.length; i < ii; ++i) { var sourceTileKey = this.tileKeys[i]; var sourceTile = this.getTile(sourceTileKey); sourceTile.consumers--; if (sourceTile.consumers == 0) { delete this.sourceTiles_[sourceTileKey]; sourceTile.dispose(); } } this.tileKeys.length = 0; this.sourceTiles_ = null; this.loadListenerKeys_.forEach(_ol_events_.unlistenByKey); this.loadListenerKeys_.length = 0; if (this.interimTile) { this.interimTile.dispose(); } this.state = _ol_TileState_.ABORT; this.changed(); this.sourceTileListenerKeys_.forEach(_ol_events_.unlistenByKey); this.sourceTileListenerKeys_.length = 0; _ol_Tile_.prototype.disposeInternal.call(this); }; /** * @param {ol.layer.Layer} layer Layer. * @return {CanvasRenderingContext2D} The rendering context. */ _ol_VectorImageTile_.prototype.getContext = function(layer) { var key = _ol_.getUid(layer).toString(); if (!(key in this.context_)) { this.context_[key] = _ol_dom_.createCanvasContext2D(); } return this.context_[key]; }; /** * Get the Canvas for this tile. * @param {ol.layer.Layer} layer Layer. * @return {HTMLCanvasElement} Canvas. */ _ol_VectorImageTile_.prototype.getImage = function(layer) { return this.getReplayState(layer).renderedTileRevision == -1 ? null : this.getContext(layer).canvas; }; /** * @param {ol.layer.Layer} layer Layer. * @return {ol.TileReplayState} The replay state. */ _ol_VectorImageTile_.prototype.getReplayState = function(layer) { var key = _ol_.getUid(layer).toString(); if (!(key in this.replayState_)) { this.replayState_[key] = { dirty: false, renderedRenderOrder: null, renderedRevision: -1, renderedTileRevision: -1 }; } return this.replayState_[key]; }; /** * @inheritDoc */ _ol_VectorImageTile_.prototype.getKey = function() { return this.tileKeys.join('/') + '-' + this.sourceRevision_; }; /** * @param {string} tileKey Key (tileCoord) of the source tile. * @return {ol.VectorTile} Source tile. */ _ol_VectorImageTile_.prototype.getTile = function(tileKey) { return this.sourceTiles_[tileKey]; }; /** * @inheritDoc */ _ol_VectorImageTile_.prototype.load = function() { // Source tiles with LOADED state - we just count them because once they are // loaded, we're no longer listening to state changes. var leftToLoad = 0; // Source tiles with ERROR state - we track them because they can still have // an ERROR state after another load attempt. var errorSourceTiles = {}; if (this.state == _ol_TileState_.IDLE) { this.setState(_ol_TileState_.LOADING); } if (this.state == _ol_TileState_.LOADING) { this.tileKeys.forEach(function(sourceTileKey) { var sourceTile = this.getTile(sourceTileKey); if (sourceTile.state == _ol_TileState_.IDLE) { sourceTile.setLoader(this.loader_); sourceTile.load(); } if (sourceTile.state == _ol_TileState_.LOADING) { var key = _ol_events_.listen(sourceTile, _ol_events_EventType_.CHANGE, function(e) { var state = sourceTile.getState(); if (state == _ol_TileState_.LOADED || state == _ol_TileState_.ERROR) { var uid = _ol_.getUid(sourceTile); if (state == _ol_TileState_.ERROR) { errorSourceTiles[uid] = true; } else { --leftToLoad; delete errorSourceTiles[uid]; } if (leftToLoad - Object.keys(errorSourceTiles).length == 0) { this.finishLoading_(); } } }.bind(this)); this.loadListenerKeys_.push(key); ++leftToLoad; } }.bind(this)); } if (leftToLoad - Object.keys(errorSourceTiles).length == 0) { setTimeout(this.finishLoading_.bind(this), 0); } }; /** * @private */ _ol_VectorImageTile_.prototype.finishLoading_ = function() { var loaded = this.tileKeys.length; var empty = 0; for (var i = loaded - 1; i >= 0; --i) { var state = this.getTile(this.tileKeys[i]).getState(); if (state != _ol_TileState_.LOADED) { --loaded; } if (state == _ol_TileState_.EMPTY) { ++empty; } } if (loaded == this.tileKeys.length) { this.loadListenerKeys_.forEach(_ol_events_.unlistenByKey); this.loadListenerKeys_.length = 0; this.setState(_ol_TileState_.LOADED); } else { this.setState(empty == this.tileKeys.length ? _ol_TileState_.EMPTY : _ol_TileState_.ERROR); } }; /** * Sets the loader for a tile. * @param {ol.VectorTile} tile Vector tile. * @param {string} url URL. */ _ol_VectorImageTile_.defaultLoadFunction = function(tile, url) { var loader = _ol_featureloader_.loadFeaturesXhr( url, tile.getFormat(), tile.onLoad.bind(tile), tile.onError.bind(tile)); tile.setLoader(loader); }; export default _ol_VectorImageTile_;