Compare commits
4 Commits
v6.0.0-bet
...
v4.6.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2eea8df75a | ||
|
|
c3870aed81 | ||
|
|
98d0fc05c8 | ||
|
|
2912a5d7a7 |
7
changelog/v4.6.5.md
Normal file
7
changelog/v4.6.5.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# 4.6.5
|
||||||
|
|
||||||
|
The v4.6.5 release fixes a hit detection issue when `declutter: true` is set on an `ol.layer.VectorTile`.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
* [#7669](https://github.com/openlayers/openlayers/pull/7559) - Use declutter tree only for text and image replays ([@ahocevar](https://github.com/ahocevar))
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openlayers",
|
"name": "openlayers",
|
||||||
"version": "4.6.4",
|
"version": "4.6.5",
|
||||||
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"map",
|
"map",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ol",
|
"name": "ol",
|
||||||
"version": "4.6.4",
|
"version": "4.6.5",
|
||||||
"description": "OpenLayers as ES2015 modules",
|
"description": "OpenLayers as ES2015 modules",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"module": "index.js",
|
"module": "index.js",
|
||||||
|
|||||||
@@ -321,18 +321,21 @@ ol.render.canvas.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var replayType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||||
* @return {?} Callback result.
|
* @return {?} Callback result.
|
||||||
*/
|
*/
|
||||||
function hitDetectionCallback(feature) {
|
function featureCallback(feature) {
|
||||||
var imageData = context.getImageData(0, 0, contextSize, contextSize).data;
|
var imageData = context.getImageData(0, 0, contextSize, contextSize).data;
|
||||||
for (var i = 0; i < contextSize; i++) {
|
for (var i = 0; i < contextSize; i++) {
|
||||||
for (var j = 0; j < contextSize; j++) {
|
for (var j = 0; j < contextSize; j++) {
|
||||||
if (mask[i][j]) {
|
if (mask[i][j]) {
|
||||||
if (imageData[(j * contextSize + i) * 4 + 3] > 0) {
|
if (imageData[(j * contextSize + i) * 4 + 3] > 0) {
|
||||||
var result;
|
var result;
|
||||||
if (!declutteredFeatures || declutteredFeatures.indexOf(feature) !== -1) {
|
if (!(declutteredFeatures && (replayType == ol.render.ReplayType.IMAGE || replayType == ol.render.ReplayType.TEXT)) ||
|
||||||
|
declutteredFeatures.indexOf(feature) !== -1) {
|
||||||
result = callback(feature);
|
result = callback(feature);
|
||||||
}
|
}
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -347,8 +350,37 @@ ol.render.canvas.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.replayHitDetection_(context, transform, rotation,
|
/** @type {Array.<number>} */
|
||||||
skippedFeaturesHash, hitDetectionCallback, hitExtent, declutterReplays);
|
var zs = Object.keys(this.replaysByZIndex_).map(Number);
|
||||||
|
zs.sort(ol.array.numberSafeCompareFunction);
|
||||||
|
|
||||||
|
var i, j, replays, replay, result;
|
||||||
|
for (i = zs.length - 1; i >= 0; --i) {
|
||||||
|
var zIndexKey = zs[i].toString();
|
||||||
|
replays = this.replaysByZIndex_[zIndexKey];
|
||||||
|
for (j = ol.render.replay.ORDER.length - 1; j >= 0; --j) {
|
||||||
|
replayType = ol.render.replay.ORDER[j];
|
||||||
|
replay = replays[replayType];
|
||||||
|
if (replay !== undefined) {
|
||||||
|
if (declutterReplays &&
|
||||||
|
(replayType == ol.render.ReplayType.IMAGE || replayType == ol.render.ReplayType.TEXT)) {
|
||||||
|
var declutter = declutterReplays[zIndexKey];
|
||||||
|
if (!declutter) {
|
||||||
|
declutterReplays[zIndexKey] = [replay, transform.slice(0)];
|
||||||
|
} else {
|
||||||
|
declutter.push(replay, transform.slice(0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = replay.replayHitDetection(context, transform, rotation,
|
||||||
|
skippedFeaturesHash, featureCallback, hitExtent);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -457,59 +489,6 @@ ol.render.canvas.ReplayGroup.prototype.replay = function(context,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @param {CanvasRenderingContext2D} context Context.
|
|
||||||
* @param {ol.Transform} transform Transform.
|
|
||||||
* @param {number} viewRotation View rotation.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T} featureCallback
|
|
||||||
* Feature callback.
|
|
||||||
* @param {ol.Extent=} opt_hitExtent Only check features that intersect this
|
|
||||||
* extent.
|
|
||||||
* @param {Object.<string, ol.DeclutterGroup>=} opt_declutterReplays Declutter
|
|
||||||
* replays.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template T
|
|
||||||
*/
|
|
||||||
ol.render.canvas.ReplayGroup.prototype.replayHitDetection_ = function(
|
|
||||||
context, transform, viewRotation, skippedFeaturesHash,
|
|
||||||
featureCallback, opt_hitExtent, opt_declutterReplays) {
|
|
||||||
/** @type {Array.<number>} */
|
|
||||||
var zs = Object.keys(this.replaysByZIndex_).map(Number);
|
|
||||||
zs.sort(ol.array.numberSafeCompareFunction);
|
|
||||||
|
|
||||||
var i, j, replays, replay, result;
|
|
||||||
for (i = zs.length - 1; i >= 0; --i) {
|
|
||||||
var zIndexKey = zs[i].toString();
|
|
||||||
replays = this.replaysByZIndex_[zIndexKey];
|
|
||||||
for (j = ol.render.replay.ORDER.length - 1; j >= 0; --j) {
|
|
||||||
var replayType = ol.render.replay.ORDER[j];
|
|
||||||
replay = replays[replayType];
|
|
||||||
if (replay !== undefined) {
|
|
||||||
if (opt_declutterReplays &&
|
|
||||||
(replayType == ol.render.ReplayType.IMAGE || replayType == ol.render.ReplayType.TEXT)) {
|
|
||||||
var declutter = opt_declutterReplays[zIndexKey];
|
|
||||||
if (!declutter) {
|
|
||||||
opt_declutterReplays[zIndexKey] = [replay, transform.slice(0)];
|
|
||||||
} else {
|
|
||||||
declutter.push(replay, transform.slice(0));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = replay.replayHitDetection(context, transform, viewRotation,
|
|
||||||
skippedFeaturesHash, featureCallback, opt_hitExtent);
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ goog.require('ol.Map');
|
|||||||
goog.require('ol.MapEvent');
|
goog.require('ol.MapEvent');
|
||||||
goog.require('ol.Overlay');
|
goog.require('ol.Overlay');
|
||||||
goog.require('ol.View');
|
goog.require('ol.View');
|
||||||
goog.require('ol.geom.Point');
|
goog.require('ol.geom.LineString');
|
||||||
goog.require('ol.has');
|
goog.require('ol.has');
|
||||||
goog.require('ol.interaction');
|
goog.require('ol.interaction');
|
||||||
goog.require('ol.interaction.DoubleClickZoom');
|
goog.require('ol.interaction.DoubleClickZoom');
|
||||||
@@ -199,12 +199,12 @@ describe('ol.Map', function() {
|
|||||||
target: target,
|
target: target,
|
||||||
layers: [new ol.layer.Vector({
|
layers: [new ol.layer.Vector({
|
||||||
source: new ol.source.Vector({
|
source: new ol.source.Vector({
|
||||||
features: [new ol.Feature(new ol.geom.Point([0, 0]))]
|
features: [new ol.Feature(new ol.geom.LineString([[-50, 0], [50, 0]]))]
|
||||||
})
|
})
|
||||||
})],
|
})],
|
||||||
view: new ol.View({
|
view: new ol.View({
|
||||||
center: [0, 0],
|
center: [0, 0],
|
||||||
zoom: 2
|
zoom: 17
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
map.renderSync();
|
map.renderSync();
|
||||||
@@ -224,6 +224,20 @@ describe('ol.Map', function() {
|
|||||||
expect(features[0]).to.be.an(ol.Feature);
|
expect(features[0]).to.be.an(ol.Feature);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns an array of found features with declutter: true', function() {
|
||||||
|
var layer = map.getLayers().item(0);
|
||||||
|
map.removeLayer(layer);
|
||||||
|
var otherLayer = new ol.layer.Vector({
|
||||||
|
declutter: true,
|
||||||
|
source: layer.getSource()
|
||||||
|
});
|
||||||
|
map.addLayer(otherLayer);
|
||||||
|
map.renderSync();
|
||||||
|
var features = map.getFeaturesAtPixel([50, 50]);
|
||||||
|
expect(features).to.be.an(Array);
|
||||||
|
expect(features[0]).to.be.an(ol.Feature);
|
||||||
|
});
|
||||||
|
|
||||||
it('respects options', function() {
|
it('respects options', function() {
|
||||||
var otherLayer = new ol.layer.Vector({
|
var otherLayer = new ol.layer.Vector({
|
||||||
source: new ol.source.Vector
|
source: new ol.source.Vector
|
||||||
|
|||||||
Reference in New Issue
Block a user