Allow layers that are not managed by the map

When a layer is configured with a map, it will be added on top of other
layers, and not be managed in the map's features collection. The layerState
will have an 'unmanaged' flag for such layers. For vector layers, this flag
is used to not skip any features.
This commit is contained in:
Andreas Hocevar
2015-06-03 12:10:39 +02:00
parent f186ed3deb
commit 54da473991
6 changed files with 107 additions and 3 deletions

View File

@@ -3282,6 +3282,7 @@ olx.layer.HeatmapOptions.prototype.visible;
* hue: (number|undefined),
* opacity: (number|undefined),
* saturation: (number|undefined),
* map: (ol.Map|undefined),
* source: (ol.source.Image|undefined),
* visible: (boolean|undefined),
* extent: (ol.Extent|undefined),
@@ -3340,6 +3341,17 @@ olx.layer.ImageOptions.prototype.saturation;
olx.layer.ImageOptions.prototype.source;
/**
* Sets the layer as overlay on a map. The map will not manage this layer in its
* layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it
* managed by the map is to use {@link ol.Map#addLayer}.
* @type {ol.Map|undefined}
* @api
*/
olx.layer.ImageOptions.prototype.map;
/**
* Visibility. Default is `true` (visible).
* @type {boolean|undefined}
@@ -3381,6 +3393,7 @@ olx.layer.ImageOptions.prototype.maxResolution;
* preload: (number|undefined),
* saturation: (number|undefined),
* source: (ol.source.Tile|undefined),
* map: (ol.Map|undefined),
* visible: (boolean|undefined),
* extent: (ol.Extent|undefined),
* minResolution: (number|undefined),
@@ -3448,6 +3461,17 @@ olx.layer.TileOptions.prototype.saturation;
olx.layer.TileOptions.prototype.source;
/**
* Sets the layer as overlay on a map. The map will not manage this layer in its
* layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it
* managed by the map is to use {@link ol.Map#addLayer}.
* @type {ol.Map|undefined}
* @api
*/
olx.layer.TileOptions.prototype.map;
/**
* Visibility. Default is `true` (visible).
* @type {boolean|undefined}
@@ -3500,6 +3524,7 @@ olx.layer.TileOptions.prototype.useInterimTilesOnError;
* renderBuffer: (number|undefined),
* saturation: (number|undefined),
* source: (ol.source.Vector|undefined),
* map: (ol.Map|undefined),
* style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined),
* updateWhileAnimating: (boolean|undefined),
* updateWhileInteracting: (boolean|undefined),
@@ -3543,6 +3568,17 @@ olx.layer.VectorOptions.prototype.renderOrder;
olx.layer.VectorOptions.prototype.hue;
/**
* Sets the layer as overlay on a map. The map will not manage this layer in its
* layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it
* managed by the map is to use {@link ol.Map#addLayer}.
* @type {ol.Map|undefined}
* @api
*/
olx.layer.VectorOptions.prototype.map;
/**
* The bounding extent for layer rendering. The layer will not be rendered
* outside of this extent.

View File

@@ -6,6 +6,7 @@ goog.require('goog.object');
goog.require('ol.Object');
goog.require('ol.layer.Base');
goog.require('ol.layer.LayerProperty');
goog.require('ol.render.EventType');
goog.require('ol.source.State');
@@ -32,12 +33,28 @@ ol.layer.Layer = function(options) {
goog.base(this, /** @type {olx.layer.LayerOptions} */ (baseOptions));
/**
* @private
* @type {goog.events.Key}
*/
this.mapPrecomposeKey_ = null;
/**
* @private
* @type {goog.events.Key}
*/
this.mapRenderKey_ = null;
/**
* @private
* @type {goog.events.Key}
*/
this.sourceChangeKey_ = null;
if (goog.isDef(options.map)) {
this.setMap(options.map);
}
goog.events.listen(this,
ol.Object.getChangeEventType(ol.layer.LayerProperty.SOURCE),
this.handleSourcePropertyChange_, false, this);
@@ -129,6 +146,32 @@ ol.layer.Layer.prototype.handleSourcePropertyChange_ = function() {
};
/**
* Sets the layer to be rendered on a map. The map will not manage this layer in
* its layers collection, and the layer will be rendered on top. This is useful
* for temporary layers. To add the layer to a map and have it managed by the
* map, use {@link ol.Map#addLayer} instead.
* @param {ol.Map} map Map.
* @api
*/
ol.layer.Layer.prototype.setMap = function(map) {
goog.events.unlistenByKey(this.mapPrecomposeKey_);
this.changed();
goog.events.unlistenByKey(this.mapRenderKey_);
if (!goog.isNull(map)) {
this.mapPrecomposeKey_ = goog.events.listen(
map, ol.render.EventType.PRECOMPOSE, function(evt) {
var layerState = this.getLayerState();
layerState.unmanaged = true;
evt.frameState.layerStatesArray.push(layerState);
evt.frameState.layerStates[goog.getUid(this)] = layerState;
}, false, this);
this.mapRenderKey_ = goog.events.listen(
this, goog.events.EventType.CHANGE, map.render, false, map);
}
};
/**
* Set the layer source.
* @param {ol.source.Source} source The layer source.

View File

@@ -79,7 +79,8 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
var extent = frameState.extent;
var focus = frameState.focus;
var pixelRatio = frameState.pixelRatio;
var skippedFeatureUids = frameState.skippedFeatureUids;
var skippedFeatureUids = layerState.unmanaged ?
{} : frameState.skippedFeatureUids;
var viewState = frameState.viewState;
var projection = viewState.projection;
var rotation = viewState.rotation;

View File

@@ -142,7 +142,7 @@ ol.renderer.dom.VectorLayer.prototype.composeFrame =
context.globalAlpha = layerState.opacity;
replayGroup.replay(context, pixelRatio, transform, viewRotation,
frameState.skippedFeatureUids);
layerState.unmanaged ? {} : frameState.skippedFeatureUids);
this.dispatchEvent_(ol.render.EventType.RENDER, frameState, transform);
}

View File

@@ -83,7 +83,8 @@ ol.renderer.webgl.VectorLayer.prototype.composeFrame =
viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio, layerState.opacity,
layerState.brightness, layerState.contrast, layerState.hue,
layerState.saturation, frameState.skippedFeatureUids);
layerState.saturation,
layerState.unmanaged ? {} : frameState.skippedFeatureUids);
}
};

View File

@@ -573,11 +573,34 @@ describe('ol.layer.Layer', function() {
});
describe('As overlay', function() {
it('overlays the layer on the map', function() {
var map = new ol.Map({});
var layer = new ol.layer.Layer({
map: map
});
var frameState = {
layerStatesArray: [],
layerStates: {}
};
map.dispatchEvent(new ol.render.Event('precompose', map, null,
frameState, null, null));
var layerState = frameState.layerStatesArray[0];
expect(frameState.layerStatesArray.length).to.be(1);
expect(layerState.layer).to.equal(layer);
expect(frameState.layerStates[goog.getUid(layer)]).to.equal(layerState);
});
});
});
goog.require('goog.dispose');
goog.require('ol.Map');
goog.require('ol.ObjectEventType');
goog.require('ol.layer.Layer');
goog.require('ol.proj');
goog.require('ol.render.Event');
goog.require('ol.source.Source');
goog.require('ol.source.State');