Get rid of ol.FeatureOverlay

This also introduces a wrapX option to the Draw, Modify and Select
interaction.
This commit is contained in:
Andreas Hocevar
2015-06-09 13:25:51 +02:00
parent 54da473991
commit 53d5d8c1d9
28 changed files with 177 additions and 676 deletions

View File

@@ -1,326 +0,0 @@
goog.provide('ol.FeatureOverlay');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.object');
goog.require('ol.Collection');
goog.require('ol.CollectionEventType');
goog.require('ol.Feature');
goog.require('ol.render.EventType');
goog.require('ol.renderer.vector');
goog.require('ol.style.Style');
/**
* @classdesc
* A mechanism for changing the style of a small number of features on a
* temporary basis, for example highlighting. This is necessary with the Canvas
* renderer, where, unlike in SVG, features cannot be individually referenced.
* See examples/vector-layers for an example: create a FeatureOverlay with a
* different style, copy the feature(s) you want rendered in this different
* style into it, and then remove them again when you're finished.
*
* @constructor
* @param {olx.FeatureOverlayOptions=} opt_options Options.
* @api
*/
ol.FeatureOverlay = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
/**
* @private
* @type {ol.Collection.<ol.Feature>}
*/
this.features_ = null;
/**
* @private
* @type {Array.<goog.events.Key>}
*/
this.featuresListenerKeys_ = null;
/**
* @private
* @type {Object.<string, goog.events.Key>}
*/
this.featureChangeListenerKeys_ = null;
/**
* @private
* @type {ol.Map}
*/
this.map_ = null;
/**
* @private
* @type {goog.events.Key}
*/
this.postComposeListenerKey_ = null;
/**
* @private
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
*/
this.style_ = null;
/**
* @private
* @type {ol.style.StyleFunction|undefined}
*/
this.styleFunction_ = undefined;
this.setStyle(goog.isDef(options.style) ?
options.style : ol.style.defaultStyleFunction);
if (goog.isDef(options.features)) {
if (goog.isArray(options.features)) {
this.setFeatures(new ol.Collection(options.features.slice()));
} else {
goog.asserts.assertInstanceof(options.features, ol.Collection,
'options.features should be an ol.Collection');
this.setFeatures(options.features);
}
} else {
this.setFeatures(new ol.Collection());
}
if (goog.isDef(options.map)) {
this.setMap(options.map);
}
};
/**
* Add a feature to the overlay.
* @param {ol.Feature} feature Feature.
* @api
*/
ol.FeatureOverlay.prototype.addFeature = function(feature) {
this.features_.push(feature);
};
/**
* Get the features on the overlay.
* @return {ol.Collection.<ol.Feature>} Features collection.
* @api
*/
ol.FeatureOverlay.prototype.getFeatures = function() {
return this.features_;
};
/**
* Get the map associated with the overlay.
* @return {?ol.Map} The map with which this feature overlay is associated.
* @api
*/
ol.FeatureOverlay.prototype.getMap = function() {
return this.map_;
};
/**
* @private
*/
ol.FeatureOverlay.prototype.handleFeatureChange_ = function() {
this.render_();
};
/**
* @private
* @param {ol.CollectionEvent} collectionEvent Collection event.
*/
ol.FeatureOverlay.prototype.handleFeaturesAdd_ = function(collectionEvent) {
goog.asserts.assert(!goog.isNull(this.featureChangeListenerKeys_),
'this.featureChangeListenerKeys_ should not be null');
var feature = /** @type {ol.Feature} */ (collectionEvent.element);
this.featureChangeListenerKeys_[goog.getUid(feature).toString()] =
goog.events.listen(feature, goog.events.EventType.CHANGE,
this.handleFeatureChange_, false, this);
this.render_();
};
/**
* @private
* @param {ol.CollectionEvent} collectionEvent Collection event.
*/
ol.FeatureOverlay.prototype.handleFeaturesRemove_ = function(collectionEvent) {
goog.asserts.assert(!goog.isNull(this.featureChangeListenerKeys_),
'this.featureChangeListenerKeys_ should not be null');
var feature = /** @type {ol.Feature} */ (collectionEvent.element);
var key = goog.getUid(feature).toString();
goog.events.unlistenByKey(this.featureChangeListenerKeys_[key]);
delete this.featureChangeListenerKeys_[key];
this.render_();
};
/**
* Handle changes in image style state.
* @param {goog.events.Event} event Image style change event.
* @private
*/
ol.FeatureOverlay.prototype.handleImageChange_ = function(event) {
this.render_();
};
/**
* @param {ol.render.Event} event Event.
* @private
*/
ol.FeatureOverlay.prototype.handleMapPostCompose_ = function(event) {
if (goog.isNull(this.features_)) {
return;
}
var styleFunction = this.styleFunction_;
if (!goog.isDef(styleFunction)) {
styleFunction = ol.style.defaultStyleFunction;
}
var replayGroup = /** @type {ol.render.IReplayGroup} */
(event.replayGroup);
goog.asserts.assert(goog.isDef(replayGroup),
'replayGroup should be defined');
var frameState = event.frameState;
var pixelRatio = frameState.pixelRatio;
var resolution = frameState.viewState.resolution;
var squaredTolerance = ol.renderer.vector.getSquaredTolerance(resolution,
pixelRatio);
var i, ii, styles, featureStyleFunction;
this.features_.forEach(function(feature) {
featureStyleFunction = feature.getStyleFunction();
styles = goog.isDef(featureStyleFunction) ?
featureStyleFunction.call(feature, resolution) :
styleFunction(feature, resolution);
if (!goog.isDefAndNotNull(styles)) {
return;
}
ii = styles.length;
for (i = 0; i < ii; ++i) {
ol.renderer.vector.renderFeature(replayGroup, feature, styles[i],
squaredTolerance, this.handleImageChange_, this);
}
}, this);
};
/**
* Remove a feature from the overlay.
* @param {ol.Feature} feature The feature to be removed.
* @api
*/
ol.FeatureOverlay.prototype.removeFeature = function(feature) {
this.features_.remove(feature);
};
/**
* @private
*/
ol.FeatureOverlay.prototype.render_ = function() {
if (!goog.isNull(this.map_)) {
this.map_.render();
}
};
/**
* Set the features for the overlay.
* @param {ol.Collection.<ol.Feature>} features Features collection.
* @api
*/
ol.FeatureOverlay.prototype.setFeatures = function(features) {
if (!goog.isNull(this.featuresListenerKeys_)) {
goog.array.forEach(this.featuresListenerKeys_, goog.events.unlistenByKey);
this.featuresListenerKeys_ = null;
}
if (!goog.isNull(this.featureChangeListenerKeys_)) {
goog.array.forEach(
goog.object.getValues(this.featureChangeListenerKeys_),
goog.events.unlistenByKey);
this.featureChangeListenerKeys_ = null;
}
this.features_ = features;
if (!goog.isNull(features)) {
this.featuresListenerKeys_ = [
goog.events.listen(features, ol.CollectionEventType.ADD,
this.handleFeaturesAdd_, false, this),
goog.events.listen(features, ol.CollectionEventType.REMOVE,
this.handleFeaturesRemove_, false, this)
];
this.featureChangeListenerKeys_ = {};
features.forEach(function(feature) {
this.featureChangeListenerKeys_[goog.getUid(feature).toString()] =
goog.events.listen(feature, goog.events.EventType.CHANGE,
this.handleFeatureChange_, false, this);
}, this);
}
this.render_();
};
/**
* Set the map for the overlay.
* @param {ol.Map} map Map.
* @api
*/
ol.FeatureOverlay.prototype.setMap = function(map) {
if (!goog.isNull(this.postComposeListenerKey_)) {
goog.events.unlistenByKey(this.postComposeListenerKey_);
this.postComposeListenerKey_ = null;
}
this.render_();
this.map_ = map;
if (!goog.isNull(map)) {
this.postComposeListenerKey_ = goog.events.listen(
map, ol.render.EventType.POSTCOMPOSE, this.handleMapPostCompose_, false,
this);
map.render();
}
};
/**
* Set the style for features. This can be a single style object, an array
* of styles, or a function that takes a feature and resolution and returns
* an array of styles.
* @param {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction} style
* Overlay style.
* @api
*/
ol.FeatureOverlay.prototype.setStyle = function(style) {
this.style_ = style;
this.styleFunction_ = ol.style.createStyleFunction(style);
this.render_();
};
/**
* Get the style for features. This returns whatever was passed to the `style`
* option at construction or to the `setStyle` method.
* @return {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
* Overlay style.
* @api
*/
ol.FeatureOverlay.prototype.getStyle = function() {
return this.style_;
};
/**
* Get the style function.
* @return {ol.style.StyleFunction|undefined} Style function.
* @api
*/
ol.FeatureOverlay.prototype.getStyleFunction = function() {
return this.styleFunction_;
};

View File

@@ -10,7 +10,6 @@ goog.require('goog.events.Event');
goog.require('ol.Collection');
goog.require('ol.Coordinate');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.Object');
@@ -27,6 +26,7 @@ goog.require('ol.geom.Polygon');
goog.require('ol.geom.SimpleGeometry');
goog.require('ol.interaction.InteractionProperty');
goog.require('ol.interaction.Pointer');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
@@ -269,10 +269,14 @@ ol.interaction.Draw = function(options) {
/**
* Draw overlay where our sketch features are drawn.
* @type {ol.FeatureOverlay}
* @type {ol.layer.Vector}
* @private
*/
this.overlay_ = new ol.FeatureOverlay({
this.overlay_ = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
wrapX: goog.isDef(options.wrapX) ? options.wrapX : false
}),
style: goog.isDef(options.style) ?
options.style : ol.interaction.Draw.getDefaultStyleFunction()
});
@@ -674,7 +678,7 @@ ol.interaction.Draw.prototype.abortDrawing_ = function() {
this.sketchFeature_ = null;
this.sketchPoint_ = null;
this.sketchLine_ = null;
this.overlay_.getFeatures().clear();
this.overlay_.getSource().clear();
}
return sketchFeature;
};
@@ -701,7 +705,9 @@ ol.interaction.Draw.prototype.updateSketchFeatures_ = function() {
if (!goog.isNull(this.sketchPoint_)) {
sketchFeatures.push(this.sketchPoint_);
}
this.overlay_.setFeatures(new ol.Collection(sketchFeatures));
var overlaySource = this.overlay_.getSource();
overlaySource.clear();
overlaySource.addFeatures(sketchFeatures);
};

View File

@@ -7,7 +7,6 @@ goog.require('goog.functions');
goog.require('ol.Collection');
goog.require('ol.CollectionEventType');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.ViewHint');
goog.require('ol.coordinate');
@@ -21,6 +20,8 @@ goog.require('ol.geom.MultiPolygon');
goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon');
goog.require('ol.interaction.Pointer');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.structs.RBush');
goog.require('ol.style.Style');
@@ -112,10 +113,14 @@ ol.interaction.Modify = function(options) {
/**
* Draw overlay where are sketch features are drawn.
* @type {ol.FeatureOverlay}
* @type {ol.layer.Vector}
* @private
*/
this.overlay_ = new ol.FeatureOverlay({
this.overlay_ = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
wrapX: goog.isDef(options.wrapX) ? options.wrapX : false
}),
style: goog.isDef(options.style) ? options.style :
ol.interaction.Modify.getDefaultStyleFunction()
});
@@ -208,7 +213,7 @@ ol.interaction.Modify.prototype.handleFeatureRemove_ = function(evt) {
// There remains only vertexFeature…
if (!goog.isNull(this.vertexFeature_) &&
this.features_.getLength() === 0) {
this.overlay_.removeFeature(this.vertexFeature_);
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
};
@@ -383,7 +388,7 @@ ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ =
if (goog.isNull(vertexFeature)) {
vertexFeature = new ol.Feature(new ol.geom.Point(coordinates));
this.vertexFeature_ = vertexFeature;
this.overlay_.addFeature(vertexFeature);
this.overlay_.getSource().addFeature(vertexFeature);
} else {
var geometry = /** @type {ol.geom.Point} */ (vertexFeature.getGeometry());
geometry.setCoordinates(coordinates);
@@ -630,7 +635,7 @@ ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) {
}
}
if (!goog.isNull(this.vertexFeature_)) {
this.overlay_.removeFeature(this.vertexFeature_);
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
};
@@ -800,7 +805,7 @@ ol.interaction.Modify.prototype.removeVertex_ = function() {
newSegmentData);
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
this.overlay_.removeFeature(this.vertexFeature_);
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
}

View File

@@ -8,10 +8,11 @@ goog.require('goog.events.Event');
goog.require('goog.functions');
goog.require('ol.CollectionEventType');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.events.condition');
goog.require('ol.geom.GeometryType');
goog.require('ol.interaction.Interaction');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
@@ -73,7 +74,7 @@ goog.inherits(ol.SelectEvent, goog.events.Event);
/**
* @classdesc
* Handles selection of vector data. A {@link ol.FeatureOverlay} is maintained
* Handles selection of vector data. An {@link ol.source.Vector} is maintained
* internally to store the selected feature(s). Which features are selected is
* determined by the `condition` option, and optionally the `toggle` or
* `add`/`remove` options.
@@ -160,14 +161,18 @@ ol.interaction.Select = function(opt_options) {
/**
* @private
* @type {ol.FeatureOverlay}
* @type {ol.layer.Vector}
*/
this.featureOverlay_ = new ol.FeatureOverlay({
this.featureOverlay_ = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
wrapX: options.wrapX
}),
style: goog.isDef(options.style) ? options.style :
ol.interaction.Select.getDefaultStyleFunction()
});
var features = this.featureOverlay_.getFeatures();
var features = this.featureOverlay_.getSource().getFeaturesCollection();
goog.events.listen(features, ol.CollectionEventType.ADD,
this.addFeature_, false, this);
goog.events.listen(features, ol.CollectionEventType.REMOVE,
@@ -183,7 +188,7 @@ goog.inherits(ol.interaction.Select, ol.interaction.Interaction);
* @api stable
*/
ol.interaction.Select.prototype.getFeatures = function() {
return this.featureOverlay_.getFeatures();
return this.featureOverlay_.getSource().getFeaturesCollection();
};
@@ -204,7 +209,7 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
var toggle = this.toggleCondition_(mapBrowserEvent);
var set = !add && !remove && !toggle;
var map = mapBrowserEvent.map;
var features = this.featureOverlay_.getFeatures();
var features = this.featureOverlay_.getSource().getFeaturesCollection();
var /** @type {Array.<ol.Feature>} */ deselected = [];
var /** @type {Array.<ol.Feature>} */ selected = [];
var change = false;
@@ -280,7 +285,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
*/
ol.interaction.Select.prototype.setMap = function(map) {
var currentMap = this.getMap();
var selectedFeatures = this.featureOverlay_.getFeatures();
var selectedFeatures =
this.featureOverlay_.getSource().getFeaturesCollection();
if (!goog.isNull(currentMap)) {
selectedFeatures.forEach(currentMap.unskipFeature, currentMap);
}

View File

@@ -577,10 +577,8 @@ ol.Map.prototype.disposeInternal = function() {
* @param {function(this: S, ol.Feature, ol.layer.Layer): T} callback Feature
* callback. The callback will be called with two arguments. The first
* argument is one {@link ol.Feature feature} at the pixel, the second is
* the {@link ol.layer.Layer layer} of the feature. If the detected feature
* is not on a layer, but on a {@link ol.FeatureOverlay}, then the second
* argument to this function will be `null`. To stop detection, callback
* functions can return a truthy value.
* the {@link ol.layer.Layer layer} of the feature. To stop detection,
* callback functions can return a truthy value.
* @param {S=} opt_this Value to use as `this` when executing `callback`.
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
* filter function. The filter function will receive one argument, the
@@ -618,10 +616,8 @@ ol.Map.prototype.forEachFeatureAtPixel =
* @param {ol.Pixel} pixel Pixel.
* @param {function(this: S, ol.layer.Layer): T} callback Layer
* callback. Will receive one argument, the {@link ol.layer.Layer layer}
* that contains the color pixel. If the detected color value is not from a
* layer, but from a {@link ol.FeatureOverlay}, then the argument to this
* function will be `null`. To stop detection, callback functions can return
* a truthy value.
* that contains the color pixel. To stop detection, callback functions can
* return a truthy value.
* @param {S=} opt_this Value to use as `this` when executing `callback`.
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
* filter function. The filter function will receive one argument, the

View File

@@ -471,8 +471,8 @@ ol.render.canvas.Immediate.prototype.drawCircleGeometry =
* Render a feature into the canvas. In order to respect the zIndex of the
* style this method draws asynchronously and thus *after* calls to
* drawXxxxGeometry have been finished, effectively drawing the feature
* *on top* of everything else. You probably should be using
* {@link ol.FeatureOverlay} instead of calling this method directly.
* *on top* of everything else. You probably should be using an
* {@link ol.layer.Vector} instead of calling this method directly.
*
* @param {ol.Feature} feature Feature.
* @param {ol.style.Style} style Style.

View File

@@ -35,14 +35,13 @@ ol.render.EventType = {
* @param {ol.render.EventType} type Type.
* @param {Object=} opt_target Target.
* @param {ol.render.VectorContext=} opt_vectorContext Vector context.
* @param {ol.render.IReplayGroup=} opt_replayGroup Replay group.
* @param {olx.FrameState=} opt_frameState Frame state.
* @param {?CanvasRenderingContext2D=} opt_context Context.
* @param {?ol.webgl.Context=} opt_glContext WebGL Context.
*/
ol.render.Event = function(
type, opt_target, opt_vectorContext, opt_replayGroup, opt_frameState,
opt_context, opt_glContext) {
type, opt_target, opt_vectorContext, opt_frameState, opt_context,
opt_glContext) {
goog.base(this, type, opt_target);
@@ -53,11 +52,6 @@ ol.render.Event = function(
*/
this.vectorContext = opt_vectorContext;
/**
* @type {ol.render.IReplayGroup|undefined}
*/
this.replayGroup = opt_replayGroup;
/**
* @type {olx.FrameState|undefined}
* @api

View File

@@ -131,8 +131,8 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ =
var render = new ol.render.canvas.Immediate(
context, frameState.pixelRatio, frameState.extent, transform,
frameState.viewState.rotation);
var composeEvent = new ol.render.Event(type, layer, render, null,
frameState, context, null);
var composeEvent = new ol.render.Event(type, layer, render, frameState,
context, null);
layer.dispatchEvent(composeEvent);
render.flush();
}

View File

@@ -10,7 +10,6 @@ goog.require('ol');
goog.require('ol.RendererType');
goog.require('ol.css');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Image');
goog.require('ol.layer.Layer');
goog.require('ol.layer.Tile');
@@ -18,13 +17,11 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.canvas.Immediate');
goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.ImageLayer');
goog.require('ol.renderer.canvas.Layer');
goog.require('ol.renderer.canvas.TileLayer');
goog.require('ol.renderer.canvas.VectorLayer');
goog.require('ol.renderer.vector');
goog.require('ol.source.State');
goog.require('ol.vec.Mat4');
@@ -103,55 +100,27 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
var extent = frameState.extent;
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var projection = viewState.projection;
var resolution = viewState.resolution;
var rotation = viewState.rotation;
var offsetX = 0;
if (projection.canWrapX()) {
var projectionExtent = projection.getExtent();
var worldWidth = ol.extent.getWidth(projectionExtent);
var x = frameState.focus[0];
if (x < projectionExtent[0] || x > projectionExtent[2]) {
var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth);
offsetX = worldWidth * worldsAway;
extent = [
extent[0] + offsetX, extent[1],
extent[2] + offsetX, extent[3]
];
}
}
var transform = this.getTransform(frameState, offsetX);
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
var replayGroup = new ol.render.canvas.ReplayGroup(
tolerance, extent, resolution);
var transform = this.getTransform(frameState);
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
extent, transform, rotation);
var composeEvent = new ol.render.Event(type, map, vectorContext,
replayGroup, frameState, context, null);
frameState, context, null);
map.dispatchEvent(composeEvent);
replayGroup.finish();
if (!replayGroup.isEmpty()) {
replayGroup.replay(context, pixelRatio, transform, rotation, {});
}
vectorContext.flush();
this.replayGroup = replayGroup;
}
};
/**
* @param {olx.FrameState} frameState Frame state.
* @param {number} offsetX Offset on the x-axis in view coordinates.
* @protected
* @return {!goog.vec.Mat4.Number} Transform.
*/
ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) {
ol.renderer.canvas.Map.prototype.getTransform = function(frameState) {
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var resolution = viewState.resolution;
@@ -159,8 +128,7 @@ ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) {
this.canvas_.width / 2, this.canvas_.height / 2,
pixelRatio / resolution, -pixelRatio / resolution,
-viewState.rotation,
-viewState.center[0] - offsetX,
-viewState.center[1]);
-viewState.center[0], -viewState.center[1]);
};

View File

@@ -77,7 +77,6 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
function(frameState, layerState, context) {
var extent = frameState.extent;
var focus = frameState.focus;
var pixelRatio = frameState.pixelRatio;
var skippedFeatureUids = layerState.unmanaged ?
{} : frameState.skippedFeatureUids;
@@ -109,20 +108,11 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
// see http://jsperf.com/context-save-restore-versus-variable
var alpha = replayContext.globalAlpha;
replayContext.globalAlpha = layerState.opacity;
var noSkip = {};
var focusX = focus[0];
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
skippedFeatureUids);
if (vectorSource.getWrapX() && projection.canWrapX() &&
!ol.extent.containsExtent(projectionExtent, extent)) {
var projLeft = projectionExtent[0];
var projRight = projectionExtent[2];
// A feature from skippedFeatureUids will only be skipped in the world
// that has the frameState's focus, because this is where a feature
// overlay for highlighting or selection would render the skipped
// feature.
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
projLeft <= focusX && focusX <= projRight ?
skippedFeatureUids : noSkip);
var startX = extent[0];
var worldWidth = ol.extent.getWidth(projectionExtent);
var world = 0;
@@ -132,8 +122,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
offsetX = worldWidth * world;
transform = this.getTransform(frameState, offsetX);
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
projLeft + offsetX <= focusX && focusX <= projRight + offsetX ?
skippedFeatureUids : noSkip);
skippedFeatureUids);
startX += worldWidth;
}
world = 0;
@@ -143,13 +132,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
offsetX = worldWidth * world;
transform = this.getTransform(frameState, offsetX);
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
projLeft + offsetX <= focusX && focusX <= projRight + offsetX ?
skippedFeatureUids : noSkip);
skippedFeatureUids);
startX -= worldWidth;
}
} else {
replayGroup.replay(
replayContext, pixelRatio, transform, rotation, skippedFeatureUids);
}
if (replayContext != context) {

View File

@@ -20,13 +20,11 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.canvas.Immediate');
goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.dom.ImageLayer');
goog.require('ol.renderer.dom.Layer');
goog.require('ol.renderer.dom.TileLayer');
goog.require('ol.renderer.dom.VectorLayer');
goog.require('ol.renderer.vector');
goog.require('ol.source.State');
goog.require('ol.vec.Mat4');
@@ -139,7 +137,6 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ =
var extent = frameState.extent;
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var resolution = viewState.resolution;
var rotation = viewState.rotation;
var context = this.context_;
var canvas = context.canvas;
@@ -153,18 +150,10 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ =
-viewState.center[0], -viewState.center[1]);
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
extent, this.transform_, rotation);
var replayGroup = new ol.render.canvas.ReplayGroup(
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
resolution);
var composeEvent = new ol.render.Event(type, map, vectorContext,
replayGroup, frameState, context, null);
frameState, context, null);
map.dispatchEvent(composeEvent);
replayGroup.finish();
if (!replayGroup.isEmpty()) {
replayGroup.replay(context, pixelRatio, this.transform_, rotation, {});
}
vectorContext.flush();
this.replayGroup = replayGroup;
}
};

View File

@@ -165,8 +165,8 @@ ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ =
var render = new ol.render.canvas.Immediate(
context, frameState.pixelRatio, frameState.extent, transform,
frameState.viewState.rotation);
var event = new ol.render.Event(type, layer, render, null,
frameState, context, null);
var event = new ol.render.Event(type, layer, render, frameState,
context, null);
layer.dispatchEvent(event);
render.flush();
}

View File

@@ -48,12 +48,6 @@ ol.renderer.Map = function(container, map) {
*/
this.map_ = map;
/**
* @protected
* @type {ol.render.IReplayGroup}
*/
this.replayGroup = null;
/**
* @private
* @type {Object.<string, ol.renderer.Layer>}
@@ -137,7 +131,6 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate =
var result;
var viewState = frameState.viewState;
var viewResolution = viewState.resolution;
var viewRotation = viewState.rotation;
/** @type {Object.<string, boolean>} */
var features = {};
@@ -168,13 +161,6 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate =
}
}
if (!goog.isNull(this.replayGroup)) {
result = this.replayGroup.forEachFeatureAtCoordinate(translatedCoordinate,
viewResolution, viewRotation, {}, forEachFeatureAtCoordinate);
if (result) {
return result;
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;
@@ -216,20 +202,7 @@ ol.renderer.Map.prototype.forEachLayerAtPixel =
var result;
var viewState = frameState.viewState;
var viewResolution = viewState.resolution;
var viewRotation = viewState.rotation;
if (!goog.isNull(this.replayGroup)) {
var coordinate = this.getMap().getCoordinateFromPixel(pixel);
var hasFeature = this.replayGroup.forEachFeatureAtCoordinate(coordinate,
viewResolution, viewRotation, {}, goog.functions.TRUE);
if (hasFeature) {
result = callback.call(thisArg, null);
if (result) {
return result;
}
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;

View File

@@ -247,7 +247,7 @@ ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ =
var render = new ol.render.webgl.Immediate(
context, center, resolution, rotation, size, extent, pixelRatio);
var composeEvent = new ol.render.Event(
type, layer, render, null, frameState, null, context);
type, layer, render, frameState, null, context);
layer.dispatchEvent(composeEvent);
}
};

View File

@@ -24,9 +24,7 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.webgl.Immediate');
goog.require('ol.render.webgl.ReplayGroup');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.vector');
goog.require('ol.renderer.webgl.ImageLayer');
goog.require('ol.renderer.webgl.Layer');
goog.require('ol.renderer.webgl.TileLayer');
@@ -287,27 +285,14 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ =
var resolution = viewState.resolution;
var center = viewState.center;
var rotation = viewState.rotation;
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
var vectorContext = new ol.render.webgl.Immediate(context,
center, resolution, rotation, size, extent, pixelRatio);
var replayGroup = new ol.render.webgl.ReplayGroup(tolerance, extent);
var composeEvent = new ol.render.Event(type, map, vectorContext,
replayGroup, frameState, null, context);
frameState, null, context);
map.dispatchEvent(composeEvent);
replayGroup.finish(context);
if (!replayGroup.isEmpty()) {
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
replayGroup.replay(context, center, resolution, rotation, size,
pixelRatio, d.opacity, d.brightness, d.contrast,
d.hue, d.saturation, {});
}
replayGroup.getDeleteResourcesFunction(context)();
vectorContext.flush();
this.replayGroup = replayGroup;
}
};
@@ -561,37 +546,8 @@ ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate =
return false;
}
var context = this.getContext();
var viewState = frameState.viewState;
// do the hit-detection for the overlays first
if (!goog.isNull(this.replayGroup)) {
/** @type {Object.<string, boolean>} */
var features = {};
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
result = this.replayGroup.forEachFeatureAtCoordinate(coordinate,
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {},
/**
* @param {ol.Feature} feature Feature.
* @return {?} Callback result.
*/
function(feature) {
goog.asserts.assert(goog.isDef(feature), 'received a feature');
var key = goog.getUid(feature).toString();
if (!(key in features)) {
features[key] = true;
return callback.call(thisArg, feature, null);
}
});
if (result) {
return result;
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;
@@ -623,22 +579,8 @@ ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate =
return false;
}
var context = this.getContext();
var viewState = frameState.viewState;
// do the hit-detection for the overlays first
if (!goog.isNull(this.replayGroup)) {
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
hasFeature = this.replayGroup.hasFeatureAtCoordinate(coordinate,
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {});
if (hasFeature) {
return true;
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;
@@ -669,27 +611,9 @@ ol.renderer.webgl.Map.prototype.forEachLayerAtPixel =
return false;
}
var context = this.getContext();
var viewState = frameState.viewState;
var result;
// do the hit-detection for the overlays first
if (!goog.isNull(this.replayGroup)) {
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
var coordinate = this.getMap().getCoordinateFromPixel(pixel);
var hasFeature = this.replayGroup.hasFeatureAtCoordinate(coordinate,
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {});
if (hasFeature) {
result = callback.call(thisArg, null);
if (result) {
return result;
}
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;