Use a common origin and resolution factors for tile alignment
This commit is contained in:
@@ -12,6 +12,7 @@ goog.require('ol.extent');
|
|||||||
goog.require('ol.render.canvas');
|
goog.require('ol.render.canvas');
|
||||||
goog.require('ol.render.EventType');
|
goog.require('ol.render.EventType');
|
||||||
goog.require('ol.renderer.canvas.Layer');
|
goog.require('ol.renderer.canvas.Layer');
|
||||||
|
goog.require('ol.size');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,6 +215,11 @@ ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = function(
|
|||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, frameState, layerState) {
|
ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, frameState, layerState) {
|
||||||
|
var tilesToDraw = this.renderedTiles;
|
||||||
|
if (tilesToDraw.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var pixelRatio = frameState.pixelRatio;
|
var pixelRatio = frameState.pixelRatio;
|
||||||
var viewState = frameState.viewState;
|
var viewState = frameState.viewState;
|
||||||
var center = viewState.center;
|
var center = viewState.center;
|
||||||
@@ -258,7 +264,16 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
|
|||||||
var alpha = renderContext.globalAlpha;
|
var alpha = renderContext.globalAlpha;
|
||||||
renderContext.globalAlpha = layerState.opacity;
|
renderContext.globalAlpha = layerState.opacity;
|
||||||
|
|
||||||
var tilesToDraw = this.renderedTiles;
|
// Origin of the lowest resolution tile that contains the map center. We will
|
||||||
|
// try to use the same origin for all resolutions for pixel-perfect tile
|
||||||
|
// alignment across resolutions.
|
||||||
|
var lowResTileCoord = tilesToDraw[0].getTileCoord();
|
||||||
|
var minZOrigin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
||||||
|
tileGrid.getTileCoordForCoordAndZ(center,
|
||||||
|
lowResTileCoord[0], this.tmpTileCoord_), this.tmpExtent));
|
||||||
|
var maxZ = tilesToDraw[tilesToDraw.length - 1].getTileCoord()[0];
|
||||||
|
var maxZResolution = tileGrid.getResolution(maxZ);
|
||||||
|
var maxZTileSize = ol.size.toSize(tileGrid.getTileSize(maxZ));
|
||||||
|
|
||||||
var pixelExtents;
|
var pixelExtents;
|
||||||
var opaque = source.getOpaque(projection) && layerState.opacity == 1;
|
var opaque = source.getOpaque(projection) && layerState.opacity == 1;
|
||||||
@@ -302,17 +317,23 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
|
|||||||
for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) {
|
for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) {
|
||||||
var tile = tilesToDraw[i];
|
var tile = tilesToDraw[i];
|
||||||
var tileCoord = tile.getTileCoord();
|
var tileCoord = tile.getTileCoord();
|
||||||
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
|
|
||||||
var currentZ = tileCoord[0];
|
var currentZ = tileCoord[0];
|
||||||
|
var tileSize = ol.size.toSize(tileGrid.getTileSize(currentZ));
|
||||||
// Calculate all insert points by tile widths from a common origin to avoid
|
// Calculate all insert points by tile widths from a common origin to avoid
|
||||||
// gaps caused by rounding
|
// gaps caused by rounding
|
||||||
var origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
var originTileCoord = tileGrid.getTileCoordForCoordAndZ(minZOrigin, currentZ, this.tmpTileCoord_);
|
||||||
tileGrid.getTileCoordForCoordAndZ(center, currentZ, this.tmpTileCoord_)));
|
var origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(originTileCoord, this.tmpExtent));
|
||||||
var w = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
|
// Calculate tile width and height by a tile size factor from the highest
|
||||||
var h = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
|
// resolution tile size to avoid gaps when combining tiles from different
|
||||||
var left = Math.round((tileExtent[0] - origin[0]) * pixelScale / w) * w +
|
// resolutions
|
||||||
|
var resolutionFactor = tileGrid.getResolution(currentZ) / maxZResolution;
|
||||||
|
var tileSizeFactorW = tileSize[0] / maxZTileSize[0] * resolutionFactor;
|
||||||
|
var tileSizeFactorH = tileSize[1] / maxZTileSize[1] * resolutionFactor;
|
||||||
|
var w = Math.round(maxZTileSize[0] / resolution * maxZResolution * pixelRatio * drawScale) * tileSizeFactorW;
|
||||||
|
var h = Math.round(maxZTileSize[1] / resolution * maxZResolution * pixelRatio * drawScale) * tileSizeFactorH;
|
||||||
|
var left = (tileCoord[1] - originTileCoord[1]) * w +
|
||||||
offsetX + Math.round((origin[0] - center[0]) * pixelScale);
|
offsetX + Math.round((origin[0] - center[0]) * pixelScale);
|
||||||
var top = Math.round((origin[1] - tileExtent[3]) * pixelScale / h) * h +
|
var top = (originTileCoord[2] - tileCoord[2] - 1) * h +
|
||||||
offsetY + Math.round((center[1] - origin[1]) * pixelScale);
|
offsetY + Math.round((center[1] - origin[1]) * pixelScale);
|
||||||
if (!opaque) {
|
if (!opaque) {
|
||||||
var pixelExtent = [left, top, left + w, top + h];
|
var pixelExtent = [left, top, left + w, top + h];
|
||||||
|
|||||||
@@ -40,6 +40,14 @@ describe('ol.renderer.canvas.TileLayer', function() {
|
|||||||
canvas: canvas,
|
canvas: canvas,
|
||||||
drawImage: sinon.spy()
|
drawImage: sinon.spy()
|
||||||
};
|
};
|
||||||
|
renderer.renderedTiles = [{
|
||||||
|
getTileCoord: function() {
|
||||||
|
return [0, 0, 0];
|
||||||
|
},
|
||||||
|
getImage: function() {
|
||||||
|
return new Image();
|
||||||
|
}
|
||||||
|
}];
|
||||||
renderer.composeFrame(frameState, layerState, context);
|
renderer.composeFrame(frameState, layerState, context);
|
||||||
expect(context.drawImage.firstCall.args[0].width).to.be(112);
|
expect(context.drawImage.firstCall.args[0].width).to.be(112);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user