Fix hit detection for decluttered layers

This commit is contained in:
Andreas Hocevar
2017-10-22 12:55:23 +02:00
parent f4506d87eb
commit 53a2cf55f1
2 changed files with 30 additions and 28 deletions

View File

@@ -201,11 +201,11 @@ ol.render.canvas.ReplayGroup.replayDeclutter = function(declutterReplays, contex
ol.render.canvas.ReplayGroup.replayDeclutterHitDetection = function(
declutterReplays, context, rotation, featureCallback, hitExtent) {
var zs = Object.keys(declutterReplays).map(Number).sort(ol.array.numberSafeCompareFunction);
for (var z = zs.length - 1; z >= 0; --z) {
for (var z = 0, zz = zs.length; z < zz; ++z) {
var replayData = declutterReplays[zs[z].toString()];
for (var i = 0, ii = replayData.length; i < ii;) {
var replay = replayData[i++];
var transform = replayData[i++];
for (var i = replayData.length - 1; i >= 0;) {
var transform = replayData[i--];
var replay = replayData[i--];
var result = replay.replayHitDetection(context, transform, rotation, {},
featureCallback, hitExtent);
if (result) {
@@ -327,33 +327,34 @@ ol.render.canvas.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
var mask = ol.render.canvas.ReplayGroup.getCircleArray_(hitTolerance);
var result = this.replayHitDetection_(context, transform, rotation,
skippedFeaturesHash,
/**
* @param {ol.Feature|ol.render.Feature} feature Feature.
* @return {?} Callback result.
*/
function(feature) {
var imageData = context.getImageData(0, 0, contextSize, contextSize).data;
for (var i = 0; i < contextSize; i++) {
for (var j = 0; j < contextSize; j++) {
if (mask[i][j]) {
if (imageData[(j * contextSize + i) * 4 + 3] > 0) {
var result = callback(feature);
if (result) {
return result;
} else {
context.clearRect(0, 0, contextSize, contextSize);
return undefined;
}
}
/**
* @param {ol.Feature|ol.render.Feature} feature Feature.
* @return {?} Callback result.
*/
function hitDetectionCallback(feature) {
var imageData = context.getImageData(0, 0, contextSize, contextSize).data;
for (var i = 0; i < contextSize; i++) {
for (var j = 0; j < contextSize; j++) {
if (mask[i][j]) {
if (imageData[(j * contextSize + i) * 4 + 3] > 0) {
var result = callback(feature);
if (result) {
return result;
} else {
context.clearRect(0, 0, contextSize, contextSize);
return undefined;
}
}
}
}, hitExtent);
}
}
}
var result = this.replayHitDetection_(context, transform, rotation,
skippedFeaturesHash, hitDetectionCallback, hitExtent, declutterReplays);
if (!result && declutterReplays) {
result = ol.render.canvas.ReplayGroup.replayDeclutterHitDetection(
declutterReplays, context, rotation, callback, hitExtent);
declutterReplays, context, rotation, hitDetectionCallback, hitExtent);
}
return result;
};

View File

@@ -234,9 +234,10 @@ ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = function(c
} else {
var resolution = frameState.viewState.resolution;
var rotation = frameState.viewState.rotation;
var layer = this.getLayer();
var layer = /** @type {ol.layer.Vector} */ (this.getLayer());
/** @type {Object.<string, boolean>} */
var features = {};
var declutterReplays = layer.getDeclutter() ? {} : null;
var result = this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution,
rotation, hitTolerance, {},
/**
@@ -249,7 +250,7 @@ ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate = function(c
features[key] = true;
return callback.call(thisArg, feature, layer);
}
}, null);
}, declutterReplays);
if (this.declutterTree_) {
this.declutterTree_.clear();
}