Merge pull request #6999 from ahocevar/vectortile-source-multilayer
Make VectorTile source work with multiple layers
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user