Merge pull request #6999 from ahocevar/vectortile-source-multilayer

Make VectorTile source work with multiple layers
This commit is contained in:
Andreas Hocevar
2017-07-09 14:39:27 +02:00
committed by GitHub
5 changed files with 64 additions and 33 deletions
+1 -1
View File
@@ -274,7 +274,7 @@ ol.renderer.canvas.TileLayer.prototype.drawTileImage = function(tile, frameState
if (!this.getLayer().getSource().getOpaque(frameState.viewState.projection)) { if (!this.getLayer().getSource().getOpaque(frameState.viewState.projection)) {
this.context.clearRect(x, y, w, h); this.context.clearRect(x, y, w, h);
} }
var image = tile.getImage(); var image = tile.getImage(this.getLayer());
if (image) { if (image) {
this.context.drawImage(image, gutter, gutter, this.context.drawImage(image, gutter, gutter,
image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h); image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);
+7 -8
View File
@@ -111,7 +111,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
var renderOrder = /** @type {ol.RenderOrderFunction} */ var renderOrder = /** @type {ol.RenderOrderFunction} */
(layer.getRenderOrder()) || null; (layer.getRenderOrder()) || null;
var replayState = tile.getReplayState(); var replayState = tile.getReplayState(layer);
if (!replayState.dirty && replayState.renderedRevision == revision && if (!replayState.dirty && replayState.renderedRevision == revision &&
replayState.renderedRenderOrder == renderOrder) { replayState.renderedRenderOrder == renderOrder) {
return; return;
@@ -119,7 +119,6 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) { for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
var sourceTile = tile.getTile(tile.tileKeys[t]); var sourceTile = tile.getTile(tile.tileKeys[t]);
sourceTile.replayGroup = null;
replayState.dirty = false; replayState.dirty = false;
var source = /** @type {ol.source.VectorTile} */ (layer.getSource()); var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
@@ -195,7 +194,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
renderFeature.call(this, feature); renderFeature.call(this, feature);
} }
replayGroup.finish(); replayGroup.finish();
sourceTile.setReplayGroup(tile.tileCoord.toString(), replayGroup); sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), replayGroup);
} }
replayState.renderedRevision = revision; replayState.renderedRevision = revision;
replayState.renderedRenderOrder = renderOrder; replayState.renderedRenderOrder = renderOrder;
@@ -260,7 +259,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
} else { } else {
tileSpaceCoordinate = coordinate; tileSpaceCoordinate = coordinate;
} }
replayGroup = sourceTile.getReplayGroup(tile.tileCoord.toString()); replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
found = found || replayGroup.forEachFeatureAtCoordinate( found = found || replayGroup.forEachFeatureAtCoordinate(
tileSpaceCoordinate, resolution, rotation, hitTolerance, {}, tileSpaceCoordinate, resolution, rotation, hitTolerance, {},
/** /**
@@ -359,7 +358,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra
var sourceResolution = sourceTileGrid.getResolution(currentZ); var sourceResolution = sourceTileGrid.getResolution(currentZ);
var transform = this.getReplayTransform_(sourceTile, frameState); var transform = this.getReplayTransform_(sourceTile, frameState);
ol.transform.translate(transform, worldOffset * tilePixelRatio / sourceResolution, 0); 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); var currentClip = replayGroup.getClipCoords(transform);
context.save(); context.save();
context.globalAlpha = layerState.opacity; context.globalAlpha = layerState.opacity;
@@ -431,7 +430,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, s
ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function( ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
tile, frameState, layerState) { tile, frameState, layerState) {
var layer = this.getLayer(); var layer = this.getLayer();
var replayState = tile.getReplayState(); var replayState = tile.getReplayState(layer);
var revision = layer.getRevision(); var revision = layer.getRevision();
var replays = ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS[layer.getRenderMode()]; var replays = ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS[layer.getRenderMode()];
if (replays && replayState.renderedTileRevision !== revision) { if (replays && replayState.renderedTileRevision !== revision) {
@@ -444,7 +443,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
var tileGrid = source.getTileGridForProjection(frameState.viewState.projection); var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
var resolution = tileGrid.getResolution(z); var resolution = tileGrid.getResolution(z);
var tilePixelRatio = source.getTilePixelRatio(); var tilePixelRatio = source.getTilePixelRatio();
var context = tile.getContext(); var context = tile.getContext(layer);
var size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection); var size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection);
context.canvas.width = size[0]; context.canvas.width = size[0];
context.canvas.height = size[1]; context.canvas.height = size[1];
@@ -466,7 +465,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
ol.transform.scale(transform, pixelScale, -pixelScale); ol.transform.scale(transform, pixelScale, -pixelScale);
ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]); 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); replayGroup.replay(context, pixelRatio, transform, 0, {}, replays);
} }
} }
+26 -18
View File
@@ -40,9 +40,9 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction,
/** /**
* @private * @private
* @type {CanvasRenderingContext2D} * @type {Object.<string, CanvasRenderingContext2D>}
*/ */
this.context_ = null; this.context_ = {};
/** /**
* @private * @private
@@ -52,14 +52,9 @@ ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction,
/** /**
* @private * @private
* @type {ol.TileReplayState} * @type {Object.<string, ol.TileReplayState>}
*/ */
this.replayState_ = { this.replayState_ = {};
dirty: false,
renderedRenderOrder: null,
renderedRevision: -1,
renderedTileRevision: -1
};
/** /**
* @private * @private
@@ -155,31 +150,44 @@ ol.VectorImageTile.prototype.disposeInternal = function() {
/** /**
* @param {ol.layer.Layer} layer Layer.
* @return {CanvasRenderingContext2D} The rendering context. * @return {CanvasRenderingContext2D} The rendering context.
*/ */
ol.VectorImageTile.prototype.getContext = function() { ol.VectorImageTile.prototype.getContext = function(layer) {
if (!this.context_) { var key = ol.getUid(layer).toString();
this.context_ = ol.dom.createCanvasContext2D(); if (!(key in this.context_)) {
this.context_[key] = ol.dom.createCanvasContext2D();
} }
return this.context_; return this.context_[key];
}; };
/** /**
* Get the Canvas for this tile. * Get the Canvas for this tile.
* @param {ol.layer.Layer} layer Layer.
* @return {HTMLCanvasElement} Canvas. * @return {HTMLCanvasElement} Canvas.
*/ */
ol.VectorImageTile.prototype.getImage = function() { ol.VectorImageTile.prototype.getImage = function(layer) {
return this.replayState_.renderedTileRevision == -1 ? return this.getReplayState(layer).renderedTileRevision == -1 ?
null : this.context_.canvas; null : this.getContext(layer).canvas;
}; };
/** /**
* @param {ol.layer.Layer} layer Layer.
* @return {ol.TileReplayState} The replay state. * @return {ol.TileReplayState} The replay state.
*/ */
ol.VectorImageTile.prototype.getReplayState = function() { ol.VectorImageTile.prototype.getReplayState = function(layer) {
return this.replayState_; 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];
}; };
+6 -4
View File
@@ -122,11 +122,12 @@ ol.VectorTile.prototype.getProjection = function() {
/** /**
* @param {ol.layer.Layer} layer Layer.
* @param {string} key Key. * @param {string} key Key.
* @return {ol.render.ReplayGroup} Replay group. * @return {ol.render.ReplayGroup} Replay group.
*/ */
ol.VectorTile.prototype.getReplayGroup = function(key) { ol.VectorTile.prototype.getReplayGroup = function(layer, key) {
return this.replayGroups_[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 {string} key Key.
* @param {ol.render.ReplayGroup} replayGroup Replay group. * @param {ol.render.ReplayGroup} replayGroup Replay group.
*/ */
ol.VectorTile.prototype.setReplayGroup = function(key, replayGroup) { ol.VectorTile.prototype.setReplayGroup = function(layer, key, replayGroup) {
this.replayGroups_[key] = replayGroup; this.replayGroups_[ol.getUid(layer) + ',' + key] = replayGroup;
}; };
@@ -21,7 +21,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
describe('constructor', function() { describe('constructor', function() {
var map, layer, feature1, feature2, target, tileCallback; var map, layer, source, feature1, feature2, target, tileCallback;
beforeEach(function() { beforeEach(function() {
tileCallback = function() {}; tileCallback = function() {};
@@ -57,7 +57,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
tileCallback(this); tileCallback(this);
}; };
ol.inherits(TileClass, ol.VectorTile); ol.inherits(TileClass, ol.VectorTile);
var source = new ol.source.VectorTile({ source = new ol.source.VectorTile({
format: new ol.format.MVT(), format: new ol.format.MVT(),
tileClass: TileClass, tileClass: TileClass,
tileGrid: ol.tilegrid.createXYZ() tileGrid: ol.tilegrid.createXYZ()
@@ -152,6 +152,28 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
expect(feature1.getGeometry().getCoordinates()).to.eql([1, -1]); 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() { describe('#prepareFrame', function() {