Merge pull request #2254 from elemoine/replaygroup
Use replay groups for feature overlays
This commit is contained in:
+15
-37
@@ -10,7 +10,7 @@ goog.require('ol.CollectionEventType');
|
|||||||
goog.require('ol.Feature');
|
goog.require('ol.Feature');
|
||||||
goog.require('ol.feature');
|
goog.require('ol.feature');
|
||||||
goog.require('ol.render.EventType');
|
goog.require('ol.render.EventType');
|
||||||
goog.require('ol.style.ImageState');
|
goog.require('ol.renderer.vector');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -71,8 +71,11 @@ ol.FeatureOverlay = function(opt_options) {
|
|||||||
* @private
|
* @private
|
||||||
* @type {ol.feature.StyleFunction|undefined}
|
* @type {ol.feature.StyleFunction|undefined}
|
||||||
*/
|
*/
|
||||||
this.styleFunction_ = goog.isDef(options.style) ?
|
this.styleFunction_ = undefined;
|
||||||
ol.feature.createStyleFunction(options.style) : undefined;
|
|
||||||
|
if (goog.isDef(options.style)) {
|
||||||
|
this.setStyle(options.style);
|
||||||
|
}
|
||||||
|
|
||||||
if (goog.isDef(options.features)) {
|
if (goog.isDef(options.features)) {
|
||||||
if (goog.isArray(options.features)) {
|
if (goog.isArray(options.features)) {
|
||||||
@@ -101,37 +104,6 @@ ol.FeatureOverlay.prototype.addFeature = function(feature) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.render.IVectorContext|undefined} vectorContext Vector context.
|
|
||||||
* @param {ol.Feature} feature Feature.
|
|
||||||
* @param {ol.style.Style} style Style.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.FeatureOverlay.prototype.drawFeature_ = function(vectorContext, feature,
|
|
||||||
style) {
|
|
||||||
var imageStyle = style.getImage();
|
|
||||||
if (!goog.isNull(imageStyle)) {
|
|
||||||
var imageState = imageStyle.getImageState();
|
|
||||||
if (imageState == ol.style.ImageState.LOADED ||
|
|
||||||
imageState == ol.style.ImageState.ERROR) {
|
|
||||||
imageStyle.unlistenImageChange(this.handleImageChange_, this);
|
|
||||||
if (imageState == ol.style.ImageState.LOADED) {
|
|
||||||
vectorContext.drawFeature(feature, style);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (imageState == ol.style.ImageState.IDLE) {
|
|
||||||
imageStyle.load();
|
|
||||||
}
|
|
||||||
imageState = imageStyle.getImageState();
|
|
||||||
goog.asserts.assert(imageState == ol.style.ImageState.LOADING);
|
|
||||||
imageStyle.listenImageChange(this.handleImageChange_, this);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vectorContext.drawFeature(feature, style);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {ol.Collection} Features collection.
|
* @return {ol.Collection} Features collection.
|
||||||
* @todo api
|
* @todo api
|
||||||
@@ -199,8 +171,12 @@ ol.FeatureOverlay.prototype.handleMapPostCompose_ = function(event) {
|
|||||||
if (!goog.isDef(styleFunction)) {
|
if (!goog.isDef(styleFunction)) {
|
||||||
styleFunction = ol.feature.defaultStyleFunction;
|
styleFunction = ol.feature.defaultStyleFunction;
|
||||||
}
|
}
|
||||||
var resolution = event.frameState.view2DState.resolution;
|
var replayGroup = /** @type {ol.render.IReplayGroup} */
|
||||||
var vectorContext = event.vectorContext;
|
(event.replayGroup);
|
||||||
|
goog.asserts.assert(goog.isDef(replayGroup));
|
||||||
|
var frameState = event.frameState;
|
||||||
|
var pixelRatio = frameState.pixelRatio;
|
||||||
|
var resolution = frameState.view2DState.resolution;
|
||||||
var i, ii, styles;
|
var i, ii, styles;
|
||||||
this.features_.forEach(function(feature) {
|
this.features_.forEach(function(feature) {
|
||||||
styles = styleFunction(feature, resolution);
|
styles = styleFunction(feature, resolution);
|
||||||
@@ -209,7 +185,9 @@ ol.FeatureOverlay.prototype.handleMapPostCompose_ = function(event) {
|
|||||||
}
|
}
|
||||||
ii = styles.length;
|
ii = styles.length;
|
||||||
for (i = 0; i < ii; ++i) {
|
for (i = 0; i < ii; ++i) {
|
||||||
this.drawFeature_(vectorContext, feature, styles[i]);
|
ol.renderer.vector.renderFeature(replayGroup, feature, styles[i],
|
||||||
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||||
|
feature, this.handleImageChange_, this);
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ ol.geom.flat.simplify.radialDistance = function(flatCoordinates, offset, end,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} value Value.
|
* @param {number} value Value.
|
||||||
* @param {number} tolerance Squared tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @return {number} Rounded value.
|
* @return {number} Rounded value.
|
||||||
*/
|
*/
|
||||||
ol.geom.flat.simplify.snap = function(value, tolerance) {
|
ol.geom.flat.simplify.snap = function(value, tolerance) {
|
||||||
@@ -259,7 +259,7 @@ ol.geom.flat.simplify.snap = function(value, tolerance) {
|
|||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
* @param {number} end End.
|
* @param {number} end End.
|
||||||
* @param {number} stride Stride.
|
* @param {number} stride Stride.
|
||||||
* @param {number} tolerance Squared tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
|
* @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
|
||||||
* coordinates.
|
* coordinates.
|
||||||
* @param {number} simplifiedOffset Simplified offset.
|
* @param {number} simplifiedOffset Simplified offset.
|
||||||
@@ -344,7 +344,7 @@ ol.geom.flat.simplify.quantize = function(flatCoordinates, offset, end, stride,
|
|||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
* @param {Array.<number>} ends Ends.
|
* @param {Array.<number>} ends Ends.
|
||||||
* @param {number} stride Stride.
|
* @param {number} stride Stride.
|
||||||
* @param {number} tolerance Squared tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
|
* @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
|
||||||
* coordinates.
|
* coordinates.
|
||||||
* @param {number} simplifiedOffset Simplified offset.
|
* @param {number} simplifiedOffset Simplified offset.
|
||||||
@@ -374,7 +374,7 @@ ol.geom.flat.simplify.quantizes = function(
|
|||||||
* @param {number} offset Offset.
|
* @param {number} offset Offset.
|
||||||
* @param {Array.<Array.<number>>} endss Endss.
|
* @param {Array.<Array.<number>>} endss Endss.
|
||||||
* @param {number} stride Stride.
|
* @param {number} stride Stride.
|
||||||
* @param {number} tolerance Squared tolerance.
|
* @param {number} tolerance Tolerance.
|
||||||
* @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
|
* @param {Array.<number>} simplifiedFlatCoordinates Simplified flat
|
||||||
* coordinates.
|
* coordinates.
|
||||||
* @param {number} simplifiedOffset Simplified offset.
|
* @param {number} simplifiedOffset Simplified offset.
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ ol.interaction.Select.prototype.handleMapBrowserEvent =
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Modify the currently selected feature(s).
|
// Modify the currently selected feature(s).
|
||||||
|
var /** @type {Array.<number>} */ deselected = [];
|
||||||
|
var /** @type {Array.<ol.Feature>} */ selected = [];
|
||||||
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
|
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
|
||||||
/**
|
/**
|
||||||
* @param {ol.Feature} feature Feature.
|
* @param {ol.Feature} feature Feature.
|
||||||
@@ -159,14 +161,19 @@ ol.interaction.Select.prototype.handleMapBrowserEvent =
|
|||||||
var index = goog.array.indexOf(features.getArray(), feature);
|
var index = goog.array.indexOf(features.getArray(), feature);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
if (add || toggle) {
|
if (add || toggle) {
|
||||||
features.push(feature);
|
selected.push(feature);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (remove || toggle) {
|
if (remove || toggle) {
|
||||||
features.removeAt(index);
|
deselected.push(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, undefined, this.layerFilter_);
|
}, undefined, this.layerFilter_);
|
||||||
|
var i;
|
||||||
|
for (i = deselected.length - 1; i >= 0; --i) {
|
||||||
|
features.removeAt(deselected[i]);
|
||||||
|
}
|
||||||
|
features.extend(selected);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|||||||
+12
-4
@@ -535,16 +535,24 @@ ol.Map.prototype.disposeInternal = function() {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Detect features that intersect a pixel on the viewport, and execute a
|
||||||
|
* callback with each intersecting feature. Layers included in the detection can
|
||||||
|
* be configured through `opt_layerFilter`. Feature overlays will always be
|
||||||
|
* included in the detection.
|
||||||
* @param {ol.Pixel} pixel Pixel.
|
* @param {ol.Pixel} pixel Pixel.
|
||||||
* @param {function(this: S, ol.Feature, ol.layer.Layer): T} callback Feature
|
* @param {function(this: S, ol.Feature, ol.layer.Layer): T} callback Feature
|
||||||
* callback.
|
* callback. If the detected feature is not on a layer, but on a
|
||||||
|
* {@link ol.FeatureOverlay}, then the 2nd argument to this function will
|
||||||
|
* be `null`. To stop detection, callback functions can return a truthy
|
||||||
|
* value.
|
||||||
* @param {S=} opt_this Value to use as `this` when executing `callback`.
|
* @param {S=} opt_this Value to use as `this` when executing `callback`.
|
||||||
* @param {function(this: U, ol.layer.Layer): boolean=} opt_layerFilter Layer
|
* @param {function(this: U, ol.layer.Layer): boolean=} opt_layerFilter Layer
|
||||||
* filter function, only layers which are visible and for which this
|
* filter function, only layers which are visible and for which this
|
||||||
* function returns `true` will be tested for features. By default, all
|
* function returns `true` will be tested for features. By default, all
|
||||||
* visible layers will be tested.
|
* visible layers will be tested. Feature overlays will always be tested.
|
||||||
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
|
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
|
||||||
* @return {T|undefined} Callback result.
|
* @return {T|undefined} Callback result, i.e. the return value of last
|
||||||
|
* callback execution, or the first truthy callback return value.
|
||||||
* @template S,T,U
|
* @template S,T,U
|
||||||
* @todo api stable
|
* @todo api stable
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -173,6 +173,12 @@ ol.MOUSEWHEELZOOM_TIMEOUT_DURATION = 80;
|
|||||||
ol.ROTATE_ANIMATION_DURATION = 250;
|
ol.ROTATE_ANIMATION_DURATION = 250;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @define {number} Tolerance for geometry simplification in device pixels.
|
||||||
|
*/
|
||||||
|
ol.SIMPLIFY_TOLERANCE = 0.5;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @define {number} Texture cache high water mark.
|
* @define {number} Texture cache high water mark.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -35,13 +35,14 @@ ol.render.EventType = {
|
|||||||
* @param {ol.render.EventType} type Type.
|
* @param {ol.render.EventType} type Type.
|
||||||
* @param {Object=} opt_target Target.
|
* @param {Object=} opt_target Target.
|
||||||
* @param {ol.render.IVectorContext=} opt_vectorContext Vector context.
|
* @param {ol.render.IVectorContext=} opt_vectorContext Vector context.
|
||||||
|
* @param {ol.render.IReplayGroup=} opt_replayGroup Replay group.
|
||||||
* @param {olx.FrameState=} opt_frameState Frame state.
|
* @param {olx.FrameState=} opt_frameState Frame state.
|
||||||
* @param {?CanvasRenderingContext2D=} opt_context Context.
|
* @param {?CanvasRenderingContext2D=} opt_context Context.
|
||||||
* @param {?ol.webgl.Context=} opt_glContext WebGL Context.
|
* @param {?ol.webgl.Context=} opt_glContext WebGL Context.
|
||||||
*/
|
*/
|
||||||
ol.render.Event = function(
|
ol.render.Event = function(
|
||||||
type, opt_target, opt_vectorContext, opt_frameState, opt_context,
|
type, opt_target, opt_vectorContext, opt_replayGroup, opt_frameState,
|
||||||
opt_glContext) {
|
opt_context, opt_glContext) {
|
||||||
|
|
||||||
goog.base(this, type, opt_target);
|
goog.base(this, type, opt_target);
|
||||||
|
|
||||||
@@ -52,6 +53,11 @@ ol.render.Event = function(
|
|||||||
*/
|
*/
|
||||||
this.vectorContext = opt_vectorContext;
|
this.vectorContext = opt_vectorContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.render.IReplayGroup|undefined}
|
||||||
|
*/
|
||||||
|
this.replayGroup = opt_replayGroup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {olx.FrameState|undefined}
|
* @type {olx.FrameState|undefined}
|
||||||
* @todo api
|
* @todo api
|
||||||
|
|||||||
@@ -24,6 +24,27 @@ ol.renderer.vector.defaultOrder = function(feature1, feature2) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
|
* @return {number} Squared pixel tolerance.
|
||||||
|
*/
|
||||||
|
ol.renderer.vector.getSquaredTolerance = function(resolution, pixelRatio) {
|
||||||
|
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
|
||||||
|
return tolerance * tolerance;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
|
* @return {number} Pixel tolerance.
|
||||||
|
*/
|
||||||
|
ol.renderer.vector.getTolerance = function(resolution, pixelRatio) {
|
||||||
|
return ol.SIMPLIFY_TOLERANCE * resolution / pixelRatio;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.render.IReplayGroup} replayGroup Replay group.
|
* @param {ol.render.IReplayGroup} replayGroup Replay group.
|
||||||
* @param {ol.geom.Geometry} geometry Geometry.
|
* @param {ol.geom.Geometry} geometry Geometry.
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ =
|
|||||||
var render = new ol.render.canvas.Immediate(
|
var render = new ol.render.canvas.Immediate(
|
||||||
context, frameState.pixelRatio, frameState.extent, transform,
|
context, frameState.pixelRatio, frameState.extent, transform,
|
||||||
frameState.view2DState.rotation);
|
frameState.view2DState.rotation);
|
||||||
var composeEvent = new ol.render.Event(type, layer, render, frameState,
|
var composeEvent = new ol.render.Event(type, layer, render, null,
|
||||||
context, null);
|
frameState, context, null);
|
||||||
layer.dispatchEvent(composeEvent);
|
layer.dispatchEvent(composeEvent);
|
||||||
render.flush();
|
render.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,13 @@ goog.require('ol.layer.Vector');
|
|||||||
goog.require('ol.render.Event');
|
goog.require('ol.render.Event');
|
||||||
goog.require('ol.render.EventType');
|
goog.require('ol.render.EventType');
|
||||||
goog.require('ol.render.canvas.Immediate');
|
goog.require('ol.render.canvas.Immediate');
|
||||||
|
goog.require('ol.render.canvas.ReplayGroup');
|
||||||
goog.require('ol.renderer.Map');
|
goog.require('ol.renderer.Map');
|
||||||
goog.require('ol.renderer.canvas.ImageLayer');
|
goog.require('ol.renderer.canvas.ImageLayer');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.Layer');
|
||||||
goog.require('ol.renderer.canvas.TileLayer');
|
goog.require('ol.renderer.canvas.TileLayer');
|
||||||
goog.require('ol.renderer.canvas.VectorLayer');
|
goog.require('ol.renderer.canvas.VectorLayer');
|
||||||
|
goog.require('ol.renderer.vector');
|
||||||
goog.require('ol.source.State');
|
goog.require('ol.source.State');
|
||||||
goog.require('ol.vec.Mat4');
|
goog.require('ol.vec.Mat4');
|
||||||
|
|
||||||
@@ -97,8 +99,11 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
|
|||||||
var map = this.getMap();
|
var map = this.getMap();
|
||||||
var context = this.context_;
|
var context = this.context_;
|
||||||
if (map.hasListener(type)) {
|
if (map.hasListener(type)) {
|
||||||
var view2DState = frameState.view2DState;
|
var extent = frameState.extent;
|
||||||
var pixelRatio = frameState.pixelRatio;
|
var pixelRatio = frameState.pixelRatio;
|
||||||
|
var view2DState = frameState.view2DState;
|
||||||
|
var resolution = view2DState.resolution;
|
||||||
|
var rotation = view2DState.rotation;
|
||||||
ol.vec.Mat4.makeTransform2D(this.transform_,
|
ol.vec.Mat4.makeTransform2D(this.transform_,
|
||||||
this.canvas_.width / 2,
|
this.canvas_.width / 2,
|
||||||
this.canvas_.height / 2,
|
this.canvas_.height / 2,
|
||||||
@@ -106,12 +111,21 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
|
|||||||
-pixelRatio / view2DState.resolution,
|
-pixelRatio / view2DState.resolution,
|
||||||
-view2DState.rotation,
|
-view2DState.rotation,
|
||||||
-view2DState.center[0], -view2DState.center[1]);
|
-view2DState.center[0], -view2DState.center[1]);
|
||||||
var render = new ol.render.canvas.Immediate(context, pixelRatio,
|
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
|
||||||
frameState.extent, this.transform_, view2DState.rotation);
|
extent, this.transform_, rotation);
|
||||||
var composeEvent = new ol.render.Event(type, map, render, frameState,
|
var replayGroup = new ol.render.canvas.ReplayGroup(
|
||||||
context, null);
|
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
||||||
|
resolution);
|
||||||
|
var composeEvent = new ol.render.Event(type, map, vectorContext,
|
||||||
|
replayGroup, frameState, context, null);
|
||||||
map.dispatchEvent(composeEvent);
|
map.dispatchEvent(composeEvent);
|
||||||
render.flush();
|
replayGroup.finish();
|
||||||
|
if (!replayGroup.isEmpty()) {
|
||||||
|
replayGroup.replay(context, extent, pixelRatio, this.transform_,
|
||||||
|
rotation, {});
|
||||||
|
}
|
||||||
|
vectorContext.flush();
|
||||||
|
this.replayGroup = replayGroup;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -206,9 +206,10 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
|
|||||||
if (!goog.isDef(styleFunction)) {
|
if (!goog.isDef(styleFunction)) {
|
||||||
styleFunction = ol.feature.defaultStyleFunction;
|
styleFunction = ol.feature.defaultStyleFunction;
|
||||||
}
|
}
|
||||||
var tolerance = resolution / (2 * pixelRatio);
|
|
||||||
var replayGroup =
|
var replayGroup =
|
||||||
new ol.render.canvas.ReplayGroup(tolerance, extent, resolution);
|
new ol.render.canvas.ReplayGroup(
|
||||||
|
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
||||||
|
resolution);
|
||||||
vectorSource.loadFeatures(extent, resolution, projection);
|
vectorSource.loadFeatures(extent, resolution, projection);
|
||||||
var renderFeature =
|
var renderFeature =
|
||||||
/**
|
/**
|
||||||
@@ -261,14 +262,12 @@ ol.renderer.canvas.VectorLayer.prototype.renderFeature =
|
|||||||
if (!goog.isDefAndNotNull(styles)) {
|
if (!goog.isDefAndNotNull(styles)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// simplify to a tolerance of half a device pixel
|
|
||||||
var squaredTolerance =
|
|
||||||
resolution * resolution / (4 * pixelRatio * pixelRatio);
|
|
||||||
var i, ii, loading = false;
|
var i, ii, loading = false;
|
||||||
for (i = 0, ii = styles.length; i < ii; ++i) {
|
for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||||
loading = ol.renderer.vector.renderFeature(
|
loading = ol.renderer.vector.renderFeature(
|
||||||
replayGroup, feature, styles[i], squaredTolerance, feature,
|
replayGroup, feature, styles[i],
|
||||||
this.handleImageChange_, this) || loading;
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||||
|
feature, this.handleImageChange_, this) || loading;
|
||||||
}
|
}
|
||||||
return loading;
|
return loading;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ ol.renderer.Map = function(container, map) {
|
|||||||
*/
|
*/
|
||||||
this.map_ = map;
|
this.map_ = map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {ol.render.IReplayGroup}
|
||||||
|
*/
|
||||||
|
this.replayGroup = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Object.<string, ol.renderer.Layer>}
|
* @type {Object.<string, ol.renderer.Layer>}
|
||||||
@@ -110,9 +116,36 @@ ol.renderer.Map.prototype.disposeInternal = function() {
|
|||||||
ol.renderer.Map.prototype.forEachFeatureAtPixel =
|
ol.renderer.Map.prototype.forEachFeatureAtPixel =
|
||||||
function(coordinate, frameState, callback, thisArg,
|
function(coordinate, frameState, callback, thisArg,
|
||||||
layerFilter, thisArg2) {
|
layerFilter, thisArg2) {
|
||||||
|
var result;
|
||||||
|
var extent = frameState.extent;
|
||||||
|
var view2DState = frameState.view2DState;
|
||||||
|
var viewResolution = view2DState.resolution;
|
||||||
|
var viewRotation = view2DState.rotation;
|
||||||
|
if (!goog.isNull(this.replayGroup)) {
|
||||||
|
/** @type {Object.<string, boolean>} */
|
||||||
|
var features = {};
|
||||||
|
result = this.replayGroup.forEachGeometryAtPixel(extent, viewResolution,
|
||||||
|
viewRotation, coordinate, {},
|
||||||
|
/**
|
||||||
|
* @param {ol.geom.Geometry} geometry Geometry.
|
||||||
|
* @param {Object} data Data.
|
||||||
|
* @return {?} Callback result.
|
||||||
|
*/
|
||||||
|
function(geometry, data) {
|
||||||
|
var feature = /** @type {ol.Feature} */ (data);
|
||||||
|
goog.asserts.assert(goog.isDef(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 = this.map_.getLayerGroup().getLayerStatesArray();
|
var layerStates = this.map_.getLayerGroup().getLayerStatesArray();
|
||||||
var numLayers = layerStates.length;
|
var numLayers = layerStates.length;
|
||||||
var viewResolution = frameState.view2DState.resolution;
|
|
||||||
var i;
|
var i;
|
||||||
for (i = numLayers - 1; i >= 0; --i) {
|
for (i = numLayers - 1; i >= 0; --i) {
|
||||||
var layerState = layerStates[i];
|
var layerState = layerStates[i];
|
||||||
@@ -120,7 +153,7 @@ ol.renderer.Map.prototype.forEachFeatureAtPixel =
|
|||||||
if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
|
if (ol.layer.Layer.visibleAtResolution(layerState, viewResolution) &&
|
||||||
layerFilter.call(thisArg2, layer)) {
|
layerFilter.call(thisArg2, layer)) {
|
||||||
var layerRenderer = this.getLayerRenderer(layer);
|
var layerRenderer = this.getLayerRenderer(layer);
|
||||||
var result = layerRenderer.forEachFeatureAtPixel(
|
result = layerRenderer.forEachFeatureAtPixel(
|
||||||
coordinate, frameState, callback, thisArg);
|
coordinate, frameState, callback, thisArg);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ =
|
|||||||
if (layer.hasListener(type)) {
|
if (layer.hasListener(type)) {
|
||||||
var render = new ol.render.webgl.Immediate(context, frameState.pixelRatio);
|
var render = new ol.render.webgl.Immediate(context, frameState.pixelRatio);
|
||||||
var composeEvent = new ol.render.Event(
|
var composeEvent = new ol.render.Event(
|
||||||
type, layer, render, frameState, null, context);
|
type, layer, render, null, frameState, null, context);
|
||||||
layer.dispatchEvent(composeEvent);
|
layer.dispatchEvent(composeEvent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ =
|
|||||||
var context = this.getContext();
|
var context = this.getContext();
|
||||||
var render = new ol.render.webgl.Immediate(context, frameState.pixelRatio);
|
var render = new ol.render.webgl.Immediate(context, frameState.pixelRatio);
|
||||||
var composeEvent = new ol.render.Event(
|
var composeEvent = new ol.render.Event(
|
||||||
type, map, render, frameState, null, context);
|
type, map, render, null, frameState, null, context);
|
||||||
map.dispatchEvent(composeEvent);
|
map.dispatchEvent(composeEvent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ goog.inherits(ol.source.ImageVector, ol.source.ImageCanvas);
|
|||||||
ol.source.ImageVector.prototype.canvasFunctionInternal_ =
|
ol.source.ImageVector.prototype.canvasFunctionInternal_ =
|
||||||
function(extent, resolution, pixelRatio, size, projection) {
|
function(extent, resolution, pixelRatio, size, projection) {
|
||||||
|
|
||||||
var tolerance = resolution / (2 * pixelRatio);
|
var replayGroup = new ol.render.canvas.ReplayGroup(
|
||||||
var replayGroup = new ol.render.canvas.ReplayGroup(tolerance, extent,
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio), extent,
|
||||||
resolution);
|
resolution);
|
||||||
|
|
||||||
var loading = false;
|
var loading = false;
|
||||||
@@ -226,14 +226,12 @@ ol.source.ImageVector.prototype.renderFeature_ =
|
|||||||
if (!goog.isDefAndNotNull(styles)) {
|
if (!goog.isDefAndNotNull(styles)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// simplify to a tolerance of half a device pixel
|
|
||||||
var squaredTolerance =
|
|
||||||
resolution * resolution / (4 * pixelRatio * pixelRatio);
|
|
||||||
var i, ii, loading = false;
|
var i, ii, loading = false;
|
||||||
for (i = 0, ii = styles.length; i < ii; ++i) {
|
for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||||
loading = ol.renderer.vector.renderFeature(
|
loading = ol.renderer.vector.renderFeature(
|
||||||
replayGroup, feature, styles[i], squaredTolerance, feature,
|
replayGroup, feature, styles[i],
|
||||||
this.handleImageChange_, this) || loading;
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||||
|
feature, this.handleImageChange_, this) || loading;
|
||||||
}
|
}
|
||||||
return loading;
|
return loading;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,70 +1,34 @@
|
|||||||
goog.provide('ol.test.FeatureOverlay');
|
goog.provide('ol.test.FeatureOverlay');
|
||||||
|
|
||||||
describe('ol.Feature', function() {
|
describe('ol.FeatureOverlay', function() {
|
||||||
var featureOverlay;
|
|
||||||
|
|
||||||
beforeEach(function() {
|
describe('constructor', function() {
|
||||||
featureOverlay = new ol.FeatureOverlay();
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
it('creates an new feature overlay', function() {
|
||||||
ol.style.IconImageCache.getInstance().clear();
|
var featureOverlay = new ol.FeatureOverlay();
|
||||||
});
|
expect(featureOverlay).to.be.a(ol.FeatureOverlay);
|
||||||
|
|
||||||
describe('#drawFeature_ style with no image', function() {
|
|
||||||
it('calls vectorContext.drawFeature', function() {
|
|
||||||
var vectorContext = new ol.render.canvas.Immediate(
|
|
||||||
null, // context
|
|
||||||
1, // pixelRatio
|
|
||||||
[], // extent
|
|
||||||
goog.vec.Mat4.createNumberIdentity(), // transform
|
|
||||||
0 // viewRotation
|
|
||||||
);
|
|
||||||
var feature = new ol.Feature();
|
|
||||||
var style = new ol.style.Style({
|
|
||||||
fill: new ol.style.Fill({
|
|
||||||
color: '#ffffff'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
var spy = sinon.spy(vectorContext, 'drawFeature');
|
|
||||||
featureOverlay.drawFeature_(vectorContext, feature, style);
|
|
||||||
expect(spy.calledOnce).to.be.ok();
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('#drawFeature_ style with unloaded image', function() {
|
it('takes features', function() {
|
||||||
it('calls image.load', function() {
|
var featureOverlay = new ol.FeatureOverlay({
|
||||||
var vectorContext = new ol.render.canvas.Immediate(
|
features: [new ol.Feature(new ol.geom.Point([0, 0]))]
|
||||||
null, // context
|
|
||||||
1, // pixelRatio
|
|
||||||
[], // extent
|
|
||||||
goog.vec.Mat4.createNumberIdentity(), // transform
|
|
||||||
0 // viewRotation
|
|
||||||
);
|
|
||||||
var feature = new ol.Feature();
|
|
||||||
var style = new ol.style.Style({
|
|
||||||
image: new ol.style.Icon({
|
|
||||||
src: 'http://example.com/icon.png'
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
expect(featureOverlay.getFeatures().getLength()).to.be(1);
|
||||||
var stub = sinon.stub(style.getImage(), 'load', function() {
|
|
||||||
style.getImage().iconImage_.imageState_ =
|
|
||||||
ol.style.ImageState.LOADING;
|
|
||||||
});
|
|
||||||
featureOverlay.drawFeature_(vectorContext, feature, style);
|
|
||||||
expect(stub.calledOnce).to.be.ok();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('takes a style', function() {
|
||||||
|
var style = [new ol.style.Style()];
|
||||||
|
var featureOverlay = new ol.FeatureOverlay({
|
||||||
|
style: [new ol.style.Style()]
|
||||||
|
});
|
||||||
|
expect(featureOverlay.getStyle()).to.eql(style);
|
||||||
|
expect(featureOverlay.getStyleFunction()()).to.eql(style);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
goog.require('goog.vec.Mat4');
|
|
||||||
goog.require('ol.Feature');
|
goog.require('ol.Feature');
|
||||||
goog.require('ol.FeatureOverlay');
|
goog.require('ol.FeatureOverlay');
|
||||||
goog.require('ol.style.ImageState');
|
goog.require('ol.geom.Point');
|
||||||
goog.require('ol.render.canvas.Immediate');
|
|
||||||
goog.require('ol.style.Fill');
|
|
||||||
goog.require('ol.style.Icon');
|
|
||||||
goog.require('ol.style.IconImageCache');
|
|
||||||
goog.require('ol.style.Style');
|
goog.require('ol.style.Style');
|
||||||
|
|||||||
Reference in New Issue
Block a user