goog.provide('ol.layer.Group');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.math');
goog.require('goog.object');
goog.require('ol.Collection');
goog.require('ol.CollectionEvent');
goog.require('ol.CollectionEventType');
goog.require('ol.Object');
goog.require('ol.ObjectEventType');
goog.require('ol.extent');
goog.require('ol.layer.Base');
goog.require('ol.source.State');
/**
* @enum {string}
*/
ol.layer.GroupProperty = {
LAYERS: 'layers'
};
/**
* @classdesc
* A {@link ol.Collection} of layers that are handled together.
*
* @constructor
* @extends {ol.layer.Base}
* @fires change Triggered when the group/Collection changes.
* @param {olx.layer.GroupOptions=} opt_options Layer options.
* @api stable
*/
ol.layer.Group = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
var baseOptions = /** @type {olx.layer.GroupOptions} */
(goog.object.clone(options));
delete baseOptions.layers;
var layers = options.layers;
goog.base(this, baseOptions);
/**
* @private
* @type {Object.<string, goog.events.Key>}
*/
this.listenerKeys_ = null;
goog.events.listen(this,
ol.Object.getChangeEventType(ol.layer.GroupProperty.LAYERS),
this.handleLayersChanged_, false, this);
if (goog.isDef(layers)) {
if (goog.isArray(layers)) {
layers = new ol.Collection(goog.array.clone(layers));
} else {
goog.asserts.assertInstanceof(layers, ol.Collection);
layers = layers;
}
} else {
layers = new ol.Collection();
}
this.setLayers(layers);
};
goog.inherits(ol.layer.Group, ol.layer.Base);
/**
* @private
*/
ol.layer.Group.prototype.handleLayerChange_ = function() {
if (this.getVisible()) {
this.dispatchChangeEvent();
}
};
/**
* @param {goog.events.Event} event Event.
* @private
*/
ol.layer.Group.prototype.handleLayersChanged_ = function(event) {
if (!goog.isNull(this.listenerKeys_)) {
goog.array.forEach(
goog.object.getValues(this.listenerKeys_), goog.events.unlistenByKey);
this.listenerKeys_ = null;
}
var layers = this.getLayers();
if (goog.isDefAndNotNull(layers)) {
this.listenerKeys_ = {
'add': goog.events.listen(layers, ol.CollectionEventType.ADD,
this.handleLayersAdd_, false, this),
'remove': goog.events.listen(layers, ol.CollectionEventType.REMOVE,
this.handleLayersRemove_, false, this)
};
var layersArray = layers.getArray();
var i, ii, layer;
for (i = 0, ii = layersArray.length; i < ii; i++) {
layer = layersArray[i];
this.listenerKeys_[goog.getUid(layer).toString()] =
goog.events.listen(layer,
[ol.ObjectEventType.PROPERTYCHANGE, goog.events.EventType.CHANGE],
this.handleLayerChange_, false, this);
}
}
this.dispatchChangeEvent();
};
/**
* @param {ol.CollectionEvent} collectionEvent Collection event.
* @private
*/
ol.layer.Group.prototype.handleLayersAdd_ = function(collectionEvent) {
var layer = /** @type {ol.layer.Base} */ (collectionEvent.element);
this.listenerKeys_[goog.getUid(layer).toString()] = goog.events.listen(
layer, [ol.ObjectEventType.PROPERTYCHANGE, goog.events.EventType.CHANGE],
this.handleLayerChange_, false, this);
this.dispatchChangeEvent();
};
/**
* @param {ol.CollectionEvent} collectionEvent Collection event.
* @private
*/
ol.layer.Group.prototype.handleLayersRemove_ = function(collectionEvent) {
var layer = /** @type {ol.layer.Base} */ (collectionEvent.element);
var key = goog.getUid(layer).toString();
goog.events.unlistenByKey(this.listenerKeys_[key]);
delete this.listenerKeys_[key];
this.dispatchChangeEvent();
};
/**
* @return {ol.Collection.<ol.layer.Base>|undefined} Collection of
* {@link ol.layer.Layer layers} that are part of this group.
* @observable
* @api stable
*/
ol.layer.Group.prototype.getLayers = function() {
return /** @type {ol.Collection.<ol.layer.Base>|undefined} */ (this.get(
ol.layer.GroupProperty.LAYERS));
};
goog.exportProperty(
ol.layer.Group.prototype,
'getLayers',
ol.layer.Group.prototype.getLayers);
/**
* @param {ol.Collection.<ol.layer.Base>|undefined} layers Collection of
* {@link ol.layer.Layer layers} that are part of this group.
* @observable
* @api stable
*/
ol.layer.Group.prototype.setLayers = function(layers) {
this.set(ol.layer.GroupProperty.LAYERS, layers);
};
goog.exportProperty(
ol.layer.Group.prototype,
'setLayers',
ol.layer.Group.prototype.setLayers);
/**
* @inheritDoc
*/
ol.layer.Group.prototype.getLayersArray = function(opt_array) {
var array = (goog.isDef(opt_array)) ? opt_array : [];
this.getLayers().forEach(function(layer) {
layer.getLayersArray(array);
});
return array;
};
/**
* @inheritDoc
*/
ol.layer.Group.prototype.getLayerStatesArray = function(opt_states) {
var states = (goog.isDef(opt_states)) ? opt_states : [];
var pos = states.length;
this.getLayers().forEach(function(layer) {
layer.getLayerStatesArray(states);
});
var ownLayerState = this.getLayerState();
var i, ii, layerState;
for (i = pos, ii = states.length; i < ii; i++) {
layerState = states[i];
layerState.brightness = goog.math.clamp(
layerState.brightness + ownLayerState.brightness, -1, 1);
layerState.contrast *= ownLayerState.contrast;
layerState.hue += ownLayerState.hue;
layerState.opacity *= ownLayerState.opacity;
layerState.saturation *= ownLayerState.saturation;
layerState.visible = layerState.visible && ownLayerState.visible;
layerState.maxResolution = Math.min(
layerState.maxResolution, ownLayerState.maxResolution);
layerState.minResolution = Math.max(
layerState.minResolution, ownLayerState.minResolution);
if (goog.isDef(ownLayerState.extent) && goog.isDef(layerState.extent)) {
layerState.extent = ol.extent.getIntersection(
layerState.extent, ownLayerState.extent);
}
}
return states;
};
/**
* @inheritDoc
*/
ol.layer.Group.prototype.getSourceState = function() {
return ol.source.State.READY;
};