Merge pull request #9629 from ahocevar/reuse-vectortile-overlay

Clear overlay canvas when reusing containers
This commit is contained in:
Andreas Hocevar
2019-06-02 18:20:24 +02:00
committed by GitHub
7 changed files with 56 additions and 2 deletions
+2 -1
View File
@@ -93,7 +93,8 @@ class BaseLayer extends BaseObject {
/** @type {import("./Layer.js").State} */ /** @type {import("./Layer.js").State} */
const state = this.state_ || /** @type {?} */ ({ const state = this.state_ || /** @type {?} */ ({
layer: this, layer: this,
managed: opt_managed === undefined ? true : opt_managed managed: opt_managed === undefined ? true : opt_managed,
hasOverlay: false
}); });
state.opacity = clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1); state.opacity = clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);
state.sourceState = this.getSourceState(); state.sourceState = this.getSourceState();
+1
View File
@@ -45,6 +45,7 @@ import SourceState from '../source/State.js';
* @property {SourceState} sourceState * @property {SourceState} sourceState
* @property {boolean} visible * @property {boolean} visible
* @property {boolean} managed * @property {boolean} managed
* @property {boolean} hasOverlay Set by the renderer when an overlay for points and text is used.
* @property {import("../extent.js").Extent} [extent] * @property {import("../extent.js").Extent} [extent]
* @property {number} zIndex * @property {number} zIndex
* @property {number} maxResolution * @property {number} maxResolution
+9
View File
@@ -87,9 +87,11 @@ class CompositeMapRenderer extends MapRenderer {
const viewResolution = frameState.viewState.resolution; const viewResolution = frameState.viewState.resolution;
this.children_.length = 0; this.children_.length = 0;
let hasOverlay = false;
let previousElement = null; let previousElement = null;
for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) { for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
const layerState = layerStatesArray[i]; const layerState = layerStatesArray[i];
hasOverlay = hasOverlay || layerState.hasOverlay;
frameState.layerIndex = i; frameState.layerIndex = i;
if (!visibleAtResolution(layerState, viewResolution) || if (!visibleAtResolution(layerState, viewResolution) ||
(layerState.sourceState != SourceState.READY && layerState.sourceState != SourceState.UNDEFINED)) { (layerState.sourceState != SourceState.READY && layerState.sourceState != SourceState.UNDEFINED)) {
@@ -98,8 +100,15 @@ class CompositeMapRenderer extends MapRenderer {
const layer = layerState.layer; const layer = layerState.layer;
const element = layer.render(frameState, previousElement); const element = layer.render(frameState, previousElement);
if (!element) {
continue;
}
if ((element !== previousElement || i == ii - 1) && element.childElementCount === 2 && !hasOverlay) {
element.removeChild(element.lastElementChild);
}
if (element !== previousElement) { if (element !== previousElement) {
this.children_.push(element); this.children_.push(element);
hasOverlay = false;
previousElement = element; previousElement = element;
} }
} }
+10 -1
View File
@@ -64,6 +64,11 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
*/ */
this.overlayContext_ = null; this.overlayContext_ = null;
/**
* @type {string}
*/
this.overlayContextUid_;
/** /**
* The transform for rendered pixels to viewport CSS pixels for the overlay canvas. * The transform for rendered pixels to viewport CSS pixels for the overlay canvas.
* @private * @private
@@ -126,6 +131,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
super.useContainer(target, transform, opacity); super.useContainer(target, transform, opacity);
if (containerReused && !this.containerReused && !overlayContext) { if (containerReused && !this.containerReused && !overlayContext) {
this.overlayContext_ = null; this.overlayContext_ = null;
this.overlayContextUid_ = undefined;
} }
if (this.containerReused && overlayContext) { if (this.containerReused && overlayContext) {
this.overlayContext_ = overlayContext; this.overlayContext_ = overlayContext;
@@ -136,6 +142,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
style.position = 'absolute'; style.position = 'absolute';
style.transformOrigin = 'top left'; style.transformOrigin = 'top left';
this.overlayContext_ = overlayContext; this.overlayContext_ = overlayContext;
this.overlayContextUid_ = getUid(overlayContext);
} }
if (this.container.childElementCount === 1) { if (this.container.childElementCount === 1) {
this.container.appendChild(this.overlayContext_.canvas); this.container.appendChild(this.overlayContext_.canvas);
@@ -219,6 +226,8 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState) { prepareFrame(frameState) {
const layerState = frameState.layerStatesArray[frameState.layerIndex];
layerState.hasOverlay = true;
const layerRevision = this.getLayer().getRevision(); const layerRevision = this.getLayer().getRevision();
if (this.renderedLayerRevision_ != layerRevision) { if (this.renderedLayerRevision_ != layerRevision) {
this.renderedTiles.length = 0; this.renderedTiles.length = 0;
@@ -434,7 +443,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
if (canvas.style.transform !== canvasTransform) { if (canvas.style.transform !== canvasTransform) {
canvas.style.transform = canvasTransform; canvas.style.transform = canvasTransform;
} }
} else if (!this.containerReused) { } else if (getUid(context) === this.overlayContextUid_) {
context.clearRect(0, 0, width, height); context.clearRect(0, 0, width, height);
} }
+7
View File
@@ -39,6 +39,7 @@ describe('ol.layer.Group', function() {
opacity: 1, opacity: 1,
visible: true, visible: true,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
@@ -158,6 +159,7 @@ describe('ol.layer.Group', function() {
opacity: 0.5, opacity: 0.5,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 10, zIndex: 10,
@@ -199,6 +201,7 @@ describe('ol.layer.Group', function() {
opacity: 0.5, opacity: 0.5,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: groupExtent, extent: groupExtent,
zIndex: 0, zIndex: 0,
@@ -239,6 +242,7 @@ describe('ol.layer.Group', function() {
opacity: 0.3, opacity: 0.3,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: groupExtent, extent: groupExtent,
zIndex: 10, zIndex: 10,
@@ -255,6 +259,7 @@ describe('ol.layer.Group', function() {
opacity: 0, opacity: 0,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
@@ -269,6 +274,7 @@ describe('ol.layer.Group', function() {
opacity: 1, opacity: 1,
visible: true, visible: true,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
@@ -441,6 +447,7 @@ describe('ol.layer.Group', function() {
opacity: 0.25, opacity: 0.25,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
+5
View File
@@ -49,6 +49,7 @@ describe('ol.layer.Layer', function() {
opacity: 1, opacity: 1,
visible: true, visible: true,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
@@ -84,6 +85,7 @@ describe('ol.layer.Layer', function() {
opacity: 0.5, opacity: 0.5,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 10, zIndex: 10,
@@ -182,6 +184,7 @@ describe('ol.layer.Layer', function() {
opacity: 0.33, opacity: 0.33,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 10, zIndex: 10,
@@ -198,6 +201,7 @@ describe('ol.layer.Layer', function() {
opacity: 0, opacity: 0,
visible: false, visible: false,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
@@ -212,6 +216,7 @@ describe('ol.layer.Layer', function() {
opacity: 1, opacity: 1,
visible: true, visible: true,
managed: true, managed: true,
hasOverlay: false,
sourceState: 'ready', sourceState: 'ready',
extent: undefined, extent: undefined,
zIndex: 0, zIndex: 0,
@@ -19,6 +19,8 @@ import Text from '../../../../../src/ol/style/Text.js';
import {createXYZ} from '../../../../../src/ol/tilegrid.js'; import {createXYZ} from '../../../../../src/ol/tilegrid.js';
import VectorTileRenderType from '../../../../../src/ol/layer/VectorTileRenderType.js'; import VectorTileRenderType from '../../../../../src/ol/layer/VectorTileRenderType.js';
import {getUid} from '../../../../../src/ol/util.js'; import {getUid} from '../../../../../src/ol/util.js';
import TileLayer from '../../../../../src/ol/layer/Tile.js';
import XYZ from '../../../../../src/ol/source/XYZ.js';
describe('ol.renderer.canvas.VectorTileLayer', function() { describe('ol.renderer.canvas.VectorTileLayer', function() {
@@ -39,6 +41,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
target.style.height = '256px'; target.style.height = '256px';
document.body.appendChild(target); document.body.appendChild(target);
map = new Map({ map = new Map({
pixelRatio: 1,
view: new View({ view: new View({
center: [0, 0], center: [0, 0],
zoom: 0 zoom: 0
@@ -203,6 +206,25 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
expect(Object.keys(tile.executorGroups)[1]).to.be(getUid(layer2)); expect(Object.keys(tile.executorGroups)[1]).to.be(getUid(layer2));
}); });
it('reuses render container and adds and removes overlay context', function(done) {
map.getLayers().insertAt(0, new TileLayer({
source: new XYZ({
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
})
}));
map.once('postcompose', function(e) {
expect(e.frameState.layerStatesArray[1].hasOverlay).to.be(true);
});
map.once('rendercomplete', function() {
expect(document.querySelector('.ol-layers').childElementCount).to.be(1);
expect(document.querySelector('.ol-layer').childElementCount).to.be(2);
map.removeLayer(map.getLayers().item(1));
map.renderSync();
expect(document.querySelector('.ol-layer').childElementCount).to.be(1);
done();
});
});
}); });
describe('#prepareFrame', function() { describe('#prepareFrame', function() {