Make VectorTile source work with multiple layers

This commit is contained in:
Andreas Hocevar
2017-07-09 14:08:08 +02:00
parent 4a0f97ac6a
commit 7739239e89
5 changed files with 64 additions and 33 deletions

View File

@@ -274,7 +274,7 @@ ol.renderer.canvas.TileLayer.prototype.drawTileImage = function(tile, frameState
if (!this.getLayer().getSource().getOpaque(frameState.viewState.projection)) {
this.context.clearRect(x, y, w, h);
}
var image = tile.getImage();
var image = tile.getImage(this.getLayer());
if (image) {
this.context.drawImage(image, gutter, gutter,
image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);

View File

@@ -111,7 +111,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
var renderOrder = /** @type {ol.RenderOrderFunction} */
(layer.getRenderOrder()) || null;
var replayState = tile.getReplayState();
var replayState = tile.getReplayState(layer);
if (!replayState.dirty && replayState.renderedRevision == revision &&
replayState.renderedRenderOrder == renderOrder) {
return;
@@ -119,7 +119,6 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
var sourceTile = tile.getTile(tile.tileKeys[t]);
sourceTile.replayGroup = null;
replayState.dirty = false;
var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
@@ -195,7 +194,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
renderFeature.call(this, feature);
}
replayGroup.finish();
sourceTile.setReplayGroup(tile.tileCoord.toString(), replayGroup);
sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), replayGroup);
}
replayState.renderedRevision = revision;
replayState.renderedRenderOrder = renderOrder;
@@ -260,7 +259,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
} else {
tileSpaceCoordinate = coordinate;
}
replayGroup = sourceTile.getReplayGroup(tile.tileCoord.toString());
replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
found = found || replayGroup.forEachFeatureAtCoordinate(
tileSpaceCoordinate, resolution, rotation, hitTolerance, {},
/**
@@ -359,7 +358,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra
var sourceResolution = sourceTileGrid.getResolution(currentZ);
var transform = this.getReplayTransform_(sourceTile, frameState);
ol.transform.translate(transform, worldOffset * tilePixelRatio / sourceResolution, 0);
var replayGroup = sourceTile.getReplayGroup(tileCoord.toString());
var replayGroup = sourceTile.getReplayGroup(layer, tileCoord.toString());
var currentClip = replayGroup.getClipCoords(transform);
context.save();
context.globalAlpha = layerState.opacity;
@@ -431,7 +430,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, s
ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
tile, frameState, layerState) {
var layer = this.getLayer();
var replayState = tile.getReplayState();
var replayState = tile.getReplayState(layer);
var revision = layer.getRevision();
var replays = ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS[layer.getRenderMode()];
if (replays && replayState.renderedTileRevision !== revision) {
@@ -444,7 +443,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
var resolution = tileGrid.getResolution(z);
var tilePixelRatio = source.getTilePixelRatio();
var context = tile.getContext();
var context = tile.getContext(layer);
var size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection);
context.canvas.width = size[0];
context.canvas.height = size[1];
@@ -466,7 +465,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
ol.transform.scale(transform, pixelScale, -pixelScale);
ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
}
var replayGroup = sourceTile.getReplayGroup(tile.tileCoord.toString());
var replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
replayGroup.replay(context, pixelRatio, transform, 0, {}, replays);
}
}

View File

@@ -40,9 +40,9 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction,
/**
* @private
* @type {CanvasRenderingContext2D}
* @type {Object.<string, CanvasRenderingContext2D>}
*/
this.context_ = null;
this.context_ = {};
/**
* @private
@@ -52,14 +52,9 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction,
/**
* @private
* @type {ol.TileReplayState}
* @type {Object.<string, ol.TileReplayState>}
*/
this.replayState_ = {
dirty: false,
renderedRenderOrder: null,
renderedRevision: -1,
renderedTileRevision: -1
};
this.replayState_ = {};
/**
* @private
@@ -155,31 +150,44 @@ ol.VectorImageTile.prototype.disposeInternal = function() {
/**
* @param {ol.layer.Layer} layer Layer.
* @return {CanvasRenderingContext2D} The rendering context.
*/
ol.VectorImageTile.prototype.getContext = function() {
if (!this.context_) {
this.context_ = ol.dom.createCanvasContext2D();
ol.VectorImageTile.prototype.getContext = function(layer) {
var key = ol.getUid(layer).toString();
if (!(key in this.context_)) {
this.context_[key] = ol.dom.createCanvasContext2D();
}
return this.context_;
return this.context_[key];
};
/**
* Get the Canvas for this tile.
* @param {ol.layer.Layer} layer Layer.
* @return {HTMLCanvasElement} Canvas.
*/
ol.VectorImageTile.prototype.getImage = function() {
return this.replayState_.renderedTileRevision == -1 ?
null : this.context_.canvas;
ol.VectorImageTile.prototype.getImage = function(layer) {
return this.getReplayState(layer).renderedTileRevision == -1 ?
null : this.getContext(layer).canvas;
};
/**
* @param {ol.layer.Layer} layer Layer.
* @return {ol.TileReplayState} The replay state.
*/
ol.VectorImageTile.prototype.getReplayState = function() {
return this.replayState_;
ol.VectorImageTile.prototype.getReplayState = function(layer) {
var key = ol.getUid(layer).toString();
if (!(key in this.replayState_)) {
this.replayState_[key] = {
dirty: false,
renderedRenderOrder: null,
renderedRevision: -1,
renderedTileRevision: -1
};
}
return this.replayState_[key];
};

View File

@@ -122,11 +122,12 @@ ol.VectorTile.prototype.getProjection = function() {
/**
* @param {ol.layer.Layer} layer Layer.
* @param {string} key Key.
* @return {ol.render.ReplayGroup} Replay group.
*/
ol.VectorTile.prototype.getReplayGroup = function(key) {
return this.replayGroups_[key];
ol.VectorTile.prototype.getReplayGroup = function(layer, key) {
return this.replayGroups_[ol.getUid(layer) + ',' + key];
};
@@ -182,11 +183,12 @@ ol.VectorTile.prototype.setProjection = function(projection) {
/**
* @param {ol.layer.Layer} layer Layer.
* @param {string} key Key.
* @param {ol.render.ReplayGroup} replayGroup Replay group.
*/
ol.VectorTile.prototype.setReplayGroup = function(key, replayGroup) {
this.replayGroups_[key] = replayGroup;
ol.VectorTile.prototype.setReplayGroup = function(layer, key, replayGroup) {
this.replayGroups_[ol.getUid(layer) + ',' + key] = replayGroup;
};

View File

@@ -21,7 +21,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
describe('constructor', function() {
var map, layer, feature1, feature2, target, tileCallback;
var map, layer, source, feature1, feature2, target, tileCallback;
beforeEach(function() {
tileCallback = function() {};
@@ -57,7 +57,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
tileCallback(this);
};
ol.inherits(TileClass, ol.VectorTile);
var source = new ol.source.VectorTile({
source = new ol.source.VectorTile({
format: new ol.format.MVT(),
tileClass: TileClass,
tileGrid: ol.tilegrid.createXYZ()
@@ -152,6 +152,28 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
expect(feature1.getGeometry().getCoordinates()).to.eql([1, -1]);
});
it('works for multiple layers that use the same source', function() {
var layer2 = new ol.layer.VectorTile({
source: source,
style: new ol.style.Style({
text: new ol.style.Text({
text: 'layer2'
})
})
});
map.addLayer(layer2);
var spy1 = sinon.spy(ol.VectorTile.prototype,
'getReplayGroup');
var spy2 = sinon.spy(ol.VectorTile.prototype,
'setReplayGroup');
map.renderSync();
expect(spy1.callCount).to.be(4);
expect(spy2.callCount).to.be(2);
spy1.restore();
spy2.restore();
});
});
describe('#prepareFrame', function() {