c8y-openlayer
Version:
This module is designed to help integrate Openlayer with Cumulocity IoT
297 lines (262 loc) • 9.15 kB
JavaScript
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_;