Merge pull request #12413 from MoonE/vectorlayer-hitdetect-image-invalidation
Fix hitdetection image invalidation
This commit is contained in:
@@ -30,6 +30,7 @@ import {
|
|||||||
getSquaredTolerance as getSquaredRenderTolerance,
|
getSquaredTolerance as getSquaredRenderTolerance,
|
||||||
renderFeature,
|
renderFeature,
|
||||||
} from '../vector.js';
|
} from '../vector.js';
|
||||||
|
import {equals} from '../../array.js';
|
||||||
import {
|
import {
|
||||||
fromUserExtent,
|
fromUserExtent,
|
||||||
getTransformFromProjections,
|
getTransformFromProjections,
|
||||||
@@ -93,6 +94,12 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
|||||||
*/
|
*/
|
||||||
this.renderedExtent_ = createEmpty();
|
this.renderedExtent_ = createEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {import("../../extent.js").Extent}
|
||||||
|
*/
|
||||||
|
this.wrappedRenderedExtent_ = createEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -323,7 +330,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
|||||||
const resolution = this.renderedResolution_;
|
const resolution = this.renderedResolution_;
|
||||||
const rotation = this.renderedRotation_;
|
const rotation = this.renderedRotation_;
|
||||||
const projection = this.renderedProjection_;
|
const projection = this.renderedProjection_;
|
||||||
const extent = this.renderedExtent_;
|
const extent = this.wrappedRenderedExtent_;
|
||||||
const layer = this.getLayer();
|
const layer = this.getLayer();
|
||||||
const transforms = [];
|
const transforms = [];
|
||||||
const width = size[0] * HIT_DETECT_RESOLUTION;
|
const width = size[0] * HIT_DETECT_RESOLUTION;
|
||||||
@@ -548,6 +555,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
|||||||
frameStateExtent,
|
frameStateExtent,
|
||||||
vectorLayerRenderBuffer * resolution
|
vectorLayerRenderBuffer * resolution
|
||||||
);
|
);
|
||||||
|
const renderedExtent = extent.slice();
|
||||||
const loadExtents = [extent.slice()];
|
const loadExtents = [extent.slice()];
|
||||||
const projectionExtent = projection.getExtent();
|
const projectionExtent = projection.getExtent();
|
||||||
|
|
||||||
@@ -596,8 +604,13 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
|||||||
this.renderedResolution_ == resolution &&
|
this.renderedResolution_ == resolution &&
|
||||||
this.renderedRevision_ == vectorLayerRevision &&
|
this.renderedRevision_ == vectorLayerRevision &&
|
||||||
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
|
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
|
||||||
containsExtent(this.renderedExtent_, extent)
|
containsExtent(this.wrappedRenderedExtent_, extent)
|
||||||
) {
|
) {
|
||||||
|
if (!equals(this.renderedExtent_, renderedExtent)) {
|
||||||
|
this.hitDetectionImageData_ = null;
|
||||||
|
this.renderedExtent_ = renderedExtent;
|
||||||
|
}
|
||||||
|
this.renderedCenter_ = center;
|
||||||
this.replayGroupChanged = false;
|
this.replayGroupChanged = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -702,7 +715,8 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
|||||||
this.renderedResolution_ = resolution;
|
this.renderedResolution_ = resolution;
|
||||||
this.renderedRevision_ = vectorLayerRevision;
|
this.renderedRevision_ = vectorLayerRevision;
|
||||||
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
||||||
this.renderedExtent_ = extent;
|
this.renderedExtent_ = renderedExtent;
|
||||||
|
this.wrappedRenderedExtent_ = extent;
|
||||||
this.renderedCenter_ = center;
|
this.renderedCenter_ = center;
|
||||||
this.renderedProjection_ = projection;
|
this.renderedProjection_ = projection;
|
||||||
this.replayGroup_ = executorGroup;
|
this.replayGroup_ = executorGroup;
|
||||||
|
|||||||
@@ -239,7 +239,12 @@ describe('ol.renderer.canvas.VectorLayer', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#prepareFrame and #compose', function () {
|
describe('#prepareFrame and #compose', function () {
|
||||||
let frameState, projExtent, renderer, worldWidth, buffer, loadExtents;
|
/** @type {import("../../../../../../src/ol/PluggableMap").FrameState*/ let frameState;
|
||||||
|
/** @type {import("../../../../../../src/ol/extent").Extent*/ let projExtent;
|
||||||
|
/** @type {CanvasVectorLayerRenderer} */ let renderer;
|
||||||
|
/** @type {number} */ let worldWidth;
|
||||||
|
/** @type {number} */ let buffer;
|
||||||
|
/** @type {Array<import("../../../../../../src/ol/extent").Extent>*/ let loadExtents;
|
||||||
|
|
||||||
function loader(extent) {
|
function loader(extent) {
|
||||||
loadExtents.push(extent);
|
loadExtents.push(extent);
|
||||||
@@ -260,6 +265,7 @@ describe('ol.renderer.canvas.VectorLayer', function () {
|
|||||||
buffer = layer.getRenderBuffer();
|
buffer = layer.getRenderBuffer();
|
||||||
loadExtents = [];
|
loadExtents = [];
|
||||||
frameState = {
|
frameState = {
|
||||||
|
pixelRatio: 1,
|
||||||
viewHints: [],
|
viewHints: [],
|
||||||
viewState: {
|
viewState: {
|
||||||
projection: projection,
|
projection: projection,
|
||||||
@@ -412,9 +418,8 @@ describe('ol.renderer.canvas.VectorLayer', function () {
|
|||||||
});
|
});
|
||||||
frameState.layerStatesArray = [layer.getLayerState()];
|
frameState.layerStatesArray = [layer.getLayerState()];
|
||||||
frameState.layerIndex = 0;
|
frameState.layerIndex = 0;
|
||||||
frameState.extent = [-10000, -10000, 10000, 10000];
|
|
||||||
frameState.size = [100, 100];
|
frameState.size = [100, 100];
|
||||||
frameState.viewState.center = [0, 0];
|
setExtent([-10000, -10000, 10000, 10000]);
|
||||||
let rendered = false;
|
let rendered = false;
|
||||||
if (renderer.prepareFrame(frameState)) {
|
if (renderer.prepareFrame(frameState)) {
|
||||||
rendered = true;
|
rendered = true;
|
||||||
@@ -637,5 +642,61 @@ describe('ol.renderer.canvas.VectorLayer', function () {
|
|||||||
|
|
||||||
document.body.removeChild(target);
|
document.body.removeChild(target);
|
||||||
});
|
});
|
||||||
|
it('invalidates hitdetection image when map is moved horizontally', function (done) {
|
||||||
|
const layer = new VectorLayer({
|
||||||
|
source: new VectorSource({
|
||||||
|
wrapX: true,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const renderer = new CanvasVectorLayerRenderer(layer);
|
||||||
|
const projection = getProjection('EPSG:3857');
|
||||||
|
const projExtent = projection.getExtent();
|
||||||
|
const worldWidth = getWidth(projExtent);
|
||||||
|
/** @type {import("../../../../../../src/ol/PluggableMap").FrameState*/
|
||||||
|
const frameState = {
|
||||||
|
viewHints: [],
|
||||||
|
pixelRatio: 1,
|
||||||
|
layerStatesArray: [layer.getLayerState()],
|
||||||
|
layerIndex: 0,
|
||||||
|
size: [100, 100],
|
||||||
|
viewState: {
|
||||||
|
projection: projection,
|
||||||
|
resolution: 1,
|
||||||
|
rotation: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function setExtent(extent) {
|
||||||
|
frameState.extent = extent;
|
||||||
|
frameState.viewState.center = getCenter(extent);
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.getSource().addFeature(new Feature(new Point([0, 0])));
|
||||||
|
setExtent([-10000 - worldWidth, -10000, 10000 - worldWidth, 10000]);
|
||||||
|
if (renderer.prepareFrame(frameState)) {
|
||||||
|
renderer.renderFrame(frameState, null);
|
||||||
|
renderer.getFeatures([50, 50]).then((features) => {
|
||||||
|
const imageData = renderer.hitDetectionImageData_;
|
||||||
|
expect(imageData).to.be.an(ImageData);
|
||||||
|
expect(features).to.have.length(1);
|
||||||
|
|
||||||
|
setExtent([
|
||||||
|
5e8 - worldWidth,
|
||||||
|
-10000,
|
||||||
|
5e8 + 20000 - worldWidth,
|
||||||
|
10000,
|
||||||
|
]);
|
||||||
|
if (renderer.prepareFrame(frameState)) {
|
||||||
|
renderer.renderFrame(frameState);
|
||||||
|
renderer.getFeatures([50, 50]).then((features) => {
|
||||||
|
expect(renderer.hitDetectionImageData_).to.be.an(ImageData);
|
||||||
|
expect(renderer.hitDetectionImageData_ !== imageData).to.be(true);
|
||||||
|
expect(features).to.have.length(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user