Use a hash to store features uids

This commit is contained in:
Antoine Abt
2014-03-20 13:03:31 +01:00
parent d0f2dd354b
commit 78039aceb8
5 changed files with 61 additions and 33 deletions

View File

@@ -92,8 +92,8 @@ oli.FrameState.prototype.postRenderFunctions;
oli.FrameState.prototype.size; oli.FrameState.prototype.size;
/** @type {Array.<number>} */ /** @type {Object} */
oli.FrameState.prototype.skippedFeaturesIds_; oli.FrameState.prototype.skippedFeaturesHash_;
/** @type {ol.TileQueue} */ /** @type {ol.TileQueue} */

View File

@@ -366,10 +366,17 @@ ol.Map = function(options) {
*/ */
this.skippedFeatures_ = new ol.Collection(); this.skippedFeatures_ = new ol.Collection();
goog.events.listen(this.skippedFeatures_, goog.events.listen(this.skippedFeatures_,
[ol.CollectionEventType.ADD, ol.CollectionEventType.remove], [ol.CollectionEventType.ADD, ol.CollectionEventType.REMOVE],
this.render, false, this); this.handleSkippedFeaturesChange_, false, this);
this.registerDisposable(this.skippedFeatures_); this.registerDisposable(this.skippedFeatures_);
/**
* Hash of features uid to skip drawing.
* @type {Object}
* @private
*/
this.skippedFeaturesHash_ = {};
goog.events.listen( goog.events.listen(
this, ol.Object.getChangeEventType(ol.MapProperty.LAYERGROUP), this, ol.Object.getChangeEventType(ol.MapProperty.LAYERGROUP),
this.handleLayerGroupChanged_, false, this); this.handleLayerGroupChanged_, false, this);
@@ -818,6 +825,16 @@ ol.Map.prototype.getSkippedFeatures = function() {
}; };
/**
* Get the hash of features uids to be skipped.
* @return {Object} Features uids hash
* @todo stability experimental
*/
ol.Map.prototype.getSkippedFeaturesHash = function() {
return this.skippedFeaturesHash_;
};
/** /**
* @param {goog.events.BrowserEvent} browserEvent Browser event. * @param {goog.events.BrowserEvent} browserEvent Browser event.
* @param {string=} opt_type Type. * @param {string=} opt_type Type.
@@ -917,6 +934,18 @@ ol.Map.prototype.handleSizeChanged_ = function() {
}; };
/**
* @private
*/
ol.Map.prototype.handleSkippedFeaturesChange_ = function() {
this.skippedFeaturesHash_ = {};
this.skippedFeatures_.forEach(function(feature) {
this.skippedFeaturesHash_[goog.getUid(feature).toString()] = true;
}, this);
this.render();
};
/** /**
* @private * @private
*/ */
@@ -1202,8 +1231,7 @@ ol.Map.prototype.renderFrame_ = function(time) {
pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_, pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_,
postRenderFunctions: [], postRenderFunctions: [],
size: size, size: size,
skippedFeaturesIds: goog.array.map( skippedFeaturesHash_: this.skippedFeaturesHash_,
this.skippedFeatures_.getArray(), goog.getUid),
tileQueue: this.tileQueue_, tileQueue: this.tileQueue_,
time: time, time: time,
usedTiles: {}, usedTiles: {},

View File

@@ -209,7 +209,7 @@ ol.render.canvas.Replay.prototype.beginGeometry = function(geometry, uid) {
this.beginGeometryInstruction1_ = this.beginGeometryInstruction1_ =
[ol.render.canvas.Instruction.BEGIN_GEOMETRY, geometry, 0]; [ol.render.canvas.Instruction.BEGIN_GEOMETRY, geometry, 0];
this.instructions.push(this.beginGeometryInstruction1_); this.instructions.push(this.beginGeometryInstruction1_);
this.instructionIndices_[this.instructions.length - 1] = uid; this.instructionIndices_[this.instructions.length - 1] = uid.toString();
this.beginGeometryInstruction2_ = this.beginGeometryInstruction2_ =
[ol.render.canvas.Instruction.BEGIN_GEOMETRY, geometry, 0]; [ol.render.canvas.Instruction.BEGIN_GEOMETRY, geometry, 0];
this.hitDetectionInstructions.push(this.beginGeometryInstruction2_); this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);
@@ -222,7 +222,7 @@ ol.render.canvas.Replay.prototype.beginGeometry = function(geometry, uid) {
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {goog.vec.Mat4.Number} transform Transform. * @param {goog.vec.Mat4.Number} transform Transform.
* @param {number} viewRotation View rotation. * @param {number} viewRotation View rotation.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip. * @param {Object} skippedFeaturesHash Ids of features to skip.
* @param {Array.<*>} instructions Instructions array. * @param {Array.<*>} instructions Instructions array.
* @param {function(ol.geom.Geometry, Object): T|undefined} geometryCallback * @param {function(ol.geom.Geometry, Object): T|undefined} geometryCallback
* Geometry callback. * Geometry callback.
@@ -230,7 +230,7 @@ ol.render.canvas.Replay.prototype.beginGeometry = function(geometry, uid) {
* @template T * @template T
*/ */
ol.render.canvas.Replay.prototype.replay_ = function( ol.render.canvas.Replay.prototype.replay_ = function(
context, pixelRatio, transform, viewRotation, skippedFeaturesIds, context, pixelRatio, transform, viewRotation, skippedFeaturesHash,
instructions, geometryCallback) { instructions, geometryCallback) {
/** @type {Array.<number>} */ /** @type {Array.<number>} */
var pixelCoordinates; var pixelCoordinates;
@@ -254,8 +254,8 @@ ol.render.canvas.Replay.prototype.replay_ = function(
switch (type) { switch (type) {
case ol.render.canvas.Instruction.BEGIN_GEOMETRY: case ol.render.canvas.Instruction.BEGIN_GEOMETRY:
geometry = /** @type {ol.geom.Geometry} */ (instruction[1]); geometry = /** @type {ol.geom.Geometry} */ (instruction[1]);
if (!goog.array.contains(skippedFeaturesIds, if (!goog.isDef(goog.object.get(skippedFeaturesHash,
this.instructionIndices_[i])) { this.instructionIndices_[i]))) {
++i; ++i;
} else { } else {
i = /** @type {number} */ (instruction[2]); i = /** @type {number} */ (instruction[2]);
@@ -461,15 +461,15 @@ ol.render.canvas.Replay.prototype.replay_ = function(
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {goog.vec.Mat4.Number} transform Transform. * @param {goog.vec.Mat4.Number} transform Transform.
* @param {number} viewRotation View rotation. * @param {number} viewRotation View rotation.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip * @param {Object} skippedFeaturesHash Ids of features to skip
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.canvas.Replay.prototype.replay = function( ol.render.canvas.Replay.prototype.replay = function(
context, pixelRatio, transform, viewRotation, skippedFeaturesIds) { context, pixelRatio, transform, viewRotation, skippedFeaturesHash) {
var instructions = this.instructions; var instructions = this.instructions;
return this.replay_(context, pixelRatio, transform, viewRotation, return this.replay_(context, pixelRatio, transform, viewRotation,
skippedFeaturesIds, instructions, undefined); skippedFeaturesHash, instructions, undefined);
}; };
@@ -477,18 +477,18 @@ ol.render.canvas.Replay.prototype.replay = function(
* @param {CanvasRenderingContext2D} context Context. * @param {CanvasRenderingContext2D} context Context.
* @param {goog.vec.Mat4.Number} transform Transform. * @param {goog.vec.Mat4.Number} transform Transform.
* @param {number} viewRotation View rotation. * @param {number} viewRotation View rotation.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip * @param {Object} skippedFeaturesHash Ids of features to skip
* @param {function(ol.geom.Geometry, Object): T=} opt_geometryCallback * @param {function(ol.geom.Geometry, Object): T=} opt_geometryCallback
* Geometry callback. * Geometry callback.
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.canvas.Replay.prototype.replayHitDetection = function( ol.render.canvas.Replay.prototype.replayHitDetection = function(
context, transform, viewRotation, skippedFeaturesIds, context, transform, viewRotation, skippedFeaturesHash,
opt_geometryCallback) { opt_geometryCallback) {
var instructions = this.hitDetectionInstructions; var instructions = this.hitDetectionInstructions;
return this.replay_(context, 1, transform, viewRotation, return this.replay_(context, 1, transform, viewRotation,
skippedFeaturesIds, instructions, opt_geometryCallback); skippedFeaturesHash, instructions, opt_geometryCallback);
}; };
@@ -1850,17 +1850,17 @@ ol.render.canvas.ReplayGroup = function(tolerance, maxExtent, resolution) {
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {goog.vec.Mat4.Number} transform Transform. * @param {goog.vec.Mat4.Number} transform Transform.
* @param {number} viewRotation View rotation. * @param {number} viewRotation View rotation.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip * @param {Object} skippedFeaturesHash Ids of features to skip
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.canvas.ReplayGroup.prototype.replay = function(context, extent, ol.render.canvas.ReplayGroup.prototype.replay = function(context, extent,
pixelRatio, transform, viewRotation, skippedFeaturesIds) { pixelRatio, transform, viewRotation, skippedFeaturesHash) {
/** @type {Array.<number>} */ /** @type {Array.<number>} */
var zs = goog.array.map(goog.object.getKeys(this.replaysByZIndex_), Number); var zs = goog.array.map(goog.object.getKeys(this.replaysByZIndex_), Number);
goog.array.sort(zs); goog.array.sort(zs);
return this.replay_(zs, context, extent, pixelRatio, transform, return this.replay_(zs, context, extent, pixelRatio, transform,
viewRotation, skippedFeaturesIds); viewRotation, skippedFeaturesHash);
}; };
@@ -1871,14 +1871,14 @@ ol.render.canvas.ReplayGroup.prototype.replay = function(context, extent,
* @param {ol.Extent} extent Extent. * @param {ol.Extent} extent Extent.
* @param {goog.vec.Mat4.Number} transform Transform. * @param {goog.vec.Mat4.Number} transform Transform.
* @param {number} viewRotation View rotation. * @param {number} viewRotation View rotation.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip * @param {Object} skippedFeaturesHash Ids of features to skip
* @param {function(ol.geom.Geometry, Object): T} geometryCallback Geometry * @param {function(ol.geom.Geometry, Object): T} geometryCallback Geometry
* callback. * callback.
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function( ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function(
zs, context, extent, transform, viewRotation, skippedFeaturesIds, zs, context, extent, transform, viewRotation, skippedFeaturesHash,
geometryCallback) { geometryCallback) {
var i, ii, replays, replayType, replay, result; var i, ii, replays, replayType, replay, result;
for (i = 0, ii = zs.length; i < ii; ++i) { for (i = 0, ii = zs.length; i < ii; ++i) {
@@ -1887,7 +1887,7 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function(
replay = replays[replayType]; replay = replays[replayType];
if (ol.extent.intersects(extent, replay.getExtent())) { if (ol.extent.intersects(extent, replay.getExtent())) {
result = replay.replayHitDetection(context, transform, viewRotation, result = replay.replayHitDetection(context, transform, viewRotation,
skippedFeaturesIds, geometryCallback); skippedFeaturesHash, geometryCallback);
if (result) { if (result) {
return result; return result;
} }
@@ -1906,13 +1906,13 @@ ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function(
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {goog.vec.Mat4.Number} transform Transform. * @param {goog.vec.Mat4.Number} transform Transform.
* @param {number} viewRotation View rotation. * @param {number} viewRotation View rotation.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip * @param {Object} skippedFeaturesHash Ids of features to skip
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.canvas.ReplayGroup.prototype.replay_ = function( ol.render.canvas.ReplayGroup.prototype.replay_ = function(
zs, context, extent, pixelRatio, transform, viewRotation, zs, context, extent, pixelRatio, transform, viewRotation,
skippedFeaturesIds) { skippedFeaturesHash) {
var maxExtent = this.maxExtent_; var maxExtent = this.maxExtent_;
var minX = maxExtent[0]; var minX = maxExtent[0];
@@ -1938,7 +1938,7 @@ ol.render.canvas.ReplayGroup.prototype.replay_ = function(
if (goog.isDef(replay) && if (goog.isDef(replay) &&
ol.extent.intersects(extent, replay.getExtent())) { ol.extent.intersects(extent, replay.getExtent())) {
result = replay.replay(context, pixelRatio, transform, viewRotation, result = replay.replay(context, pixelRatio, transform, viewRotation,
skippedFeaturesIds); skippedFeaturesHash);
if (result) { if (result) {
return result; return result;
} }
@@ -1956,14 +1956,14 @@ ol.render.canvas.ReplayGroup.prototype.replay_ = function(
* @param {number} resolution Resolution. * @param {number} resolution Resolution.
* @param {number} rotation Rotation. * @param {number} rotation Rotation.
* @param {ol.Coordinate} coordinate Coordinate. * @param {ol.Coordinate} coordinate Coordinate.
* @param {Array.<number>} skippedFeaturesIds Ids of features to skip * @param {Object} skippedFeaturesHash Ids of features to skip
* @param {function(ol.geom.Geometry, Object): T} callback Geometry callback. * @param {function(ol.geom.Geometry, Object): T} callback Geometry callback.
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.canvas.ReplayGroup.prototype.forEachGeometryAtPixel = function( ol.render.canvas.ReplayGroup.prototype.forEachGeometryAtPixel = function(
extent, resolution, rotation, coordinate, extent, resolution, rotation, coordinate,
skippedFeaturesIds, callback) { skippedFeaturesHash, callback) {
var transform = this.hitDetectionTransform_; var transform = this.hitDetectionTransform_;
ol.vec.Mat4.makeTransform2D(transform, 0.5, 0.5, ol.vec.Mat4.makeTransform2D(transform, 0.5, 0.5,
@@ -1978,7 +1978,7 @@ ol.render.canvas.ReplayGroup.prototype.forEachGeometryAtPixel = function(
context.clearRect(0, 0, 1, 1); context.clearRect(0, 0, 1, 1);
return this.replayHitDetection_(zs, context, extent, transform, return this.replayHitDetection_(zs, context, extent, transform,
rotation, skippedFeaturesIds, rotation, skippedFeaturesHash,
/** /**
* @param {ol.geom.Geometry} geometry Geometry. * @param {ol.geom.Geometry} geometry Geometry.
* @param {Object} data Opaque data object. * @param {Object} data Opaque data object.

View File

@@ -98,7 +98,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
replayContext.globalAlpha = layerState.opacity; replayContext.globalAlpha = layerState.opacity;
replayGroup.replay( replayGroup.replay(
replayContext, frameState.extent, frameState.pixelRatio, transform, replayContext, frameState.extent, frameState.pixelRatio, transform,
frameState.view2DState.rotation, frameState.skippedFeaturesIds_); frameState.view2DState.rotation, frameState.skippedFeaturesHash_);
if (replayContext != context) { if (replayContext != context) {
this.dispatchRenderEvent(replayContext, frameState, transform); this.dispatchRenderEvent(replayContext, frameState, transform);
@@ -124,7 +124,7 @@ ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtPixel =
var rotation = frameState.view2DState.rotation; var rotation = frameState.view2DState.rotation;
var layer = this.getLayer(); var layer = this.getLayer();
return this.replayGroup_.forEachGeometryAtPixel(extent, resolution, return this.replayGroup_.forEachGeometryAtPixel(extent, resolution,
rotation, coordinate, frameState.skippedFeaturesIds_, rotation, coordinate, frameState.skippedFeaturesHash_,
/** /**
* @param {ol.geom.Geometry} geometry Geometry. * @param {ol.geom.Geometry} geometry Geometry.
* @param {Object} data Data. * @param {Object} data Data.

View File

@@ -141,7 +141,7 @@ ol.source.ImageVector.prototype.canvasFunctionInternal_ =
var transform = this.getTransform_(ol.extent.getCenter(extent), var transform = this.getTransform_(ol.extent.getCenter(extent),
resolution, pixelRatio, size); resolution, pixelRatio, size);
replayGroup.replay(this.canvasContext_, extent, pixelRatio, transform, 0, replayGroup.replay(this.canvasContext_, extent, pixelRatio, transform, 0,
[]); {});
this.replayGroup_ = replayGroup; this.replayGroup_ = replayGroup;
@@ -158,7 +158,7 @@ ol.source.ImageVector.prototype.forEachFeatureAtPixel =
return undefined; return undefined;
} else { } else {
return this.replayGroup_.forEachGeometryAtPixel( return this.replayGroup_.forEachGeometryAtPixel(
extent, resolution, 0, coordinate, [], extent, resolution, 0, coordinate, {},
/** /**
* @param {ol.geom.Geometry} geometry Geometry. * @param {ol.geom.Geometry} geometry Geometry.
* @param {Object} data Data. * @param {Object} data Data.