goog.provide('ol.renderer.Layer'); goog.require('goog.events'); goog.require('goog.events.EventType'); goog.require('ol.Attribution'); goog.require('ol.FrameState'); goog.require('ol.Image'); goog.require('ol.ImageState'); goog.require('ol.Object'); goog.require('ol.Tile'); goog.require('ol.TileCoord'); goog.require('ol.TileRange'); goog.require('ol.TileState'); goog.require('ol.layer.Layer'); goog.require('ol.layer.LayerProperty'); goog.require('ol.layer.LayerState'); goog.require('ol.source.TileSource'); /** * @constructor * @extends {ol.Object} * @param {ol.renderer.Map} mapRenderer Map renderer. * @param {ol.layer.Layer} layer Layer. */ ol.renderer.Layer = function(mapRenderer, layer) { goog.base(this); /** * @private * @type {ol.renderer.Map} */ this.mapRenderer_ = mapRenderer; /** * @private * @type {ol.layer.Layer} */ this.layer_ = layer; /** * @protected * @type {Object.} */ this.observedTileKeys = {}; goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.layer.LayerProperty.BRIGHTNESS), this.handleLayerBrightnessChange, false, this); goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.layer.LayerProperty.CONTRAST), this.handleLayerContrastChange, false, this); goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.layer.LayerProperty.HUE), this.handleLayerHueChange, false, this); goog.events.listen(this.layer_, goog.events.EventType.LOAD, this.handleLayerLoad, false, this); goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.layer.LayerProperty.OPACITY), this.handleLayerOpacityChange, false, this); goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.layer.LayerProperty.SATURATION), this.handleLayerSaturationChange, false, this); goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.layer.LayerProperty.VISIBLE), this.handleLayerVisibleChange, false, this); }; goog.inherits(ol.renderer.Layer, ol.Object); /** * @protected */ ol.renderer.Layer.prototype.dispatchChangeEvent = function() { this.dispatchEvent(goog.events.EventType.CHANGE); }; /** * @return {ol.layer.Layer} Layer. */ ol.renderer.Layer.prototype.getLayer = function() { return this.layer_; }; /** * @return {ol.Map} Map. */ ol.renderer.Layer.prototype.getMap = function() { return this.mapRenderer_.getMap(); }; /** * @return {ol.renderer.Map} Map renderer. */ ol.renderer.Layer.prototype.getMapRenderer = function() { return this.mapRenderer_; }; /** * @protected */ ol.renderer.Layer.prototype.handleLayerBrightnessChange = goog.nullFunction; /** * @protected */ ol.renderer.Layer.prototype.handleLayerContrastChange = goog.nullFunction; /** * @protected */ ol.renderer.Layer.prototype.handleLayerHueChange = goog.nullFunction; /** * Handle changes in image state. * @param {goog.events.Event} event Image change event. * @protected */ ol.renderer.Layer.prototype.handleImageChange = function(event) { var image = /** @type {ol.Image} */ (event.target); if (image.getState() === ol.ImageState.LOADED) { this.getMap().requestRenderFrame(); } }; /** * @protected */ ol.renderer.Layer.prototype.handleLayerLoad = function() { this.dispatchChangeEvent(); }; /** * @protected */ ol.renderer.Layer.prototype.handleLayerOpacityChange = function() { this.dispatchChangeEvent(); }; /** * @protected */ ol.renderer.Layer.prototype.handleLayerSaturationChange = goog.nullFunction; /** * @protected */ ol.renderer.Layer.prototype.handleLayerVisibleChange = function() { this.dispatchChangeEvent(); }; /** * Handle changes in tile state. * @param {goog.events.Event} event Tile change event. * @private */ ol.renderer.Layer.prototype.handleTileChange_ = function(event) { var tile = /** @type {ol.Tile} */ (event.target); if (tile.getState() === ol.TileState.LOADED) { this.getMap().requestRenderFrame(); } delete this.observedTileKeys[tile.getKey()]; }; /** * Listen once to titileKey, le change event. * @param {ol.Tile} tile Tile. * @protected */ ol.renderer.Layer.prototype.listenToTileChange = function(tile) { var tileKey = tile.getKey(); if (!(tileKey in this.observedTileKeys)) { this.observedTileKeys[tileKey] = true; goog.events.listenOnce(tile, goog.events.EventType.CHANGE, this.handleTileChange_, false, this); } }; /** * @param {ol.FrameState} frameState Frame state. * @param {ol.layer.LayerState} layerState Layer state. */ ol.renderer.Layer.prototype.renderFrame = goog.abstractMethod; /** * @protected * @param {ol.FrameState} frameState Frame state. * @param {ol.source.TileSource} tileSource Tile source. */ ol.renderer.Layer.prototype.scheduleExpireCache = function(frameState, tileSource) { if (tileSource.canExpireCache()) { frameState.postRenderFunctions.push( goog.partial(function(tileSource, map, frameState) { var tileSourceKey = goog.getUid(tileSource).toString(); tileSource.expireCache(frameState.usedTiles[tileSourceKey]); }, tileSource)); } }; /** * @protected * @param {Object.} attributionsSet Attributions * set (target). * @param {Array.} attributions Attributions (source). */ ol.renderer.Layer.prototype.updateAttributions = function(attributionsSet, attributions) { var i; var attribution; for (i = 0; i < attributions.length; ++i) { attribution = attributions[i]; attributionsSet[goog.getUid(attribution).toString()] = attribution; } }; /** * @protected * @param {Object.>} usedTiles Used tiles. * @param {ol.source.TileSource} tileSource Tile source. * @param {number} z Z. * @param {ol.TileRange} tileRange Tile range. */ ol.renderer.Layer.prototype.updateUsedTiles = function(usedTiles, tileSource, z, tileRange) { // FIXME should we use tilesToDrawByZ instead? var tileSourceKey = goog.getUid(tileSource).toString(); var zKey = z.toString(); if (tileSourceKey in usedTiles) { if (zKey in usedTiles[tileSourceKey]) { usedTiles[tileSourceKey][zKey].extend(tileRange); } else { usedTiles[tileSourceKey][zKey] = tileRange; } } else { usedTiles[tileSourceKey] = {}; usedTiles[tileSourceKey][zKey] = tileRange; } }; /** * @protected * @param {Object.>} wantedTiles Wanted tiles. * @param {ol.source.TileSource} tileSource Tile source. * @param {ol.TileCoord} tileCoord Tile coordinate. */ ol.renderer.Layer.prototype.updateWantedTiles = function(wantedTiles, tileSource, tileCoord) { var tileSourceKey = goog.getUid(tileSource).toString(); var coordKey = tileCoord.toString(); if (!(tileSourceKey in wantedTiles)) { wantedTiles[tileSourceKey] = {}; } wantedTiles[tileSourceKey][coordKey] = true; }; /** * @param {function(ol.Tile): boolean} isLoadedFunction Function to * determine if the tile is loaded. * @param {ol.source.TileSource} tileSource Tile source. * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. * @param {ol.Projection} projection Projection. * @return {function(ol.TileCoord): ol.Tile} Returns a tile if it is loaded. */ ol.renderer.Layer.prototype.createGetTileIfLoadedFunction = function(isLoadedFunction, tileSource, tileGrid, projection) { return function(tileCoord) { var tile = tileSource.getTile(tileCoord, tileGrid, projection); return isLoadedFunction(tile) ? tile : null; }; };