Merge pull request #5724 from ahocevar/fix-tilelayer-extent
Fix clipping of the tile layer extent on HiDPI devices
This commit is contained in:
@@ -12,7 +12,6 @@ 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');
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -240,14 +239,12 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
|
|||||||
|
|
||||||
var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER);
|
var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER);
|
||||||
var renderContext = context;
|
var renderContext = context;
|
||||||
var drawOffsetX, drawOffsetY, drawScale, drawSize;
|
var drawScale = 1;
|
||||||
|
var drawOffsetX, drawOffsetY, drawSize;
|
||||||
if (rotation || hasRenderListeners) {
|
if (rotation || hasRenderListeners) {
|
||||||
renderContext = this.context;
|
renderContext = this.context;
|
||||||
var renderCanvas = renderContext.canvas;
|
var renderCanvas = renderContext.canvas;
|
||||||
var drawZ = tileGrid.getZForResolution(resolution);
|
drawScale = source.getTilePixelRatio(pixelRatio) / pixelRatio;
|
||||||
var drawTileSize = source.getTilePixelSize(drawZ, pixelRatio, projection);
|
|
||||||
var tileSize = ol.size.toSize(tileGrid.getTileSize(drawZ));
|
|
||||||
drawScale = drawTileSize[0] / tileSize[0];
|
|
||||||
var width = context.canvas.width * drawScale;
|
var width = context.canvas.width * drawScale;
|
||||||
var height = context.canvas.height * drawScale;
|
var height = context.canvas.height * drawScale;
|
||||||
// Make sure the canvas is big enough for all possible rotation angles
|
// Make sure the canvas is big enough for all possible rotation angles
|
||||||
@@ -294,14 +291,18 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
|
|||||||
var ox = drawOffsetX || 0;
|
var ox = drawOffsetX || 0;
|
||||||
var oy = drawOffsetY || 0;
|
var oy = drawOffsetY || 0;
|
||||||
renderContext.save();
|
renderContext.save();
|
||||||
var cx = (renderContext.canvas.width * pixelRatio) / 2;
|
var cx = (renderContext.canvas.width) / 2;
|
||||||
var cy = (renderContext.canvas.height * pixelRatio) / 2;
|
var cy = (renderContext.canvas.height) / 2;
|
||||||
ol.render.canvas.rotateAtOffset(renderContext, -rotation, cx, cy);
|
ol.render.canvas.rotateAtOffset(renderContext, -rotation, cx, cy);
|
||||||
renderContext.beginPath();
|
renderContext.beginPath();
|
||||||
renderContext.moveTo(topLeft[0] * pixelRatio + ox, topLeft[1] * pixelRatio + oy);
|
renderContext.moveTo(drawScale * (topLeft[0] * pixelRatio + ox),
|
||||||
renderContext.lineTo(topRight[0] * pixelRatio + ox, topRight[1] * pixelRatio + oy);
|
drawScale * (topLeft[1] * pixelRatio + oy));
|
||||||
renderContext.lineTo(bottomRight[0] * pixelRatio + ox, bottomRight[1] * pixelRatio + oy);
|
renderContext.lineTo(drawScale * (topRight[0] * pixelRatio + ox),
|
||||||
renderContext.lineTo(bottomLeft[0] * pixelRatio + ox, bottomLeft[1] * pixelRatio + oy);
|
drawScale * (topRight[1] * pixelRatio + oy));
|
||||||
|
renderContext.lineTo(drawScale * (bottomRight[0] * pixelRatio + ox),
|
||||||
|
drawScale * (bottomRight[1] * pixelRatio + oy));
|
||||||
|
renderContext.lineTo(drawScale * (bottomLeft[0] * pixelRatio + ox),
|
||||||
|
drawScale * (bottomLeft[1] * pixelRatio + oy));
|
||||||
renderContext.clip();
|
renderContext.clip();
|
||||||
ol.render.canvas.rotateAtOffset(renderContext, rotation, cx, cy);
|
ol.render.canvas.rotateAtOffset(renderContext, rotation, cx, cy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
goog.provide('ol.test.renderer.canvas.TileLayer');
|
||||||
|
|
||||||
|
goog.require('ol.transform');
|
||||||
|
goog.require('ol.layer.Tile');
|
||||||
|
goog.require('ol.renderer.Map');
|
||||||
|
goog.require('ol.renderer.canvas.TileLayer');
|
||||||
|
goog.require('ol.source.XYZ');
|
||||||
|
|
||||||
|
|
||||||
|
describe('ol.renderer.canvas.TileLayer', function() {
|
||||||
|
|
||||||
|
describe('#composeFrame()', function() {
|
||||||
|
it('uses correct draw scale when rotating (HiDPI)', function() {
|
||||||
|
var layer = new ol.layer.Tile({
|
||||||
|
source: new ol.source.XYZ()
|
||||||
|
});
|
||||||
|
var renderer = new ol.renderer.canvas.TileLayer(layer);
|
||||||
|
renderer.renderedTiles = [];
|
||||||
|
var frameState = {
|
||||||
|
viewState: {
|
||||||
|
center: [2, 3],
|
||||||
|
projection: ol.proj.get('EPSG:3857'),
|
||||||
|
resolution: 1,
|
||||||
|
rotation: Math.PI
|
||||||
|
},
|
||||||
|
size: [10, 10],
|
||||||
|
pixelRatio: 2,
|
||||||
|
coordinateToPixelTransform: ol.transform.create(),
|
||||||
|
pixelToCoordinateTransform: ol.transform.create()
|
||||||
|
};
|
||||||
|
renderer.getImageTransform = function() {
|
||||||
|
return ol.transform.create();
|
||||||
|
};
|
||||||
|
ol.renderer.Map.prototype.calculateMatrices2D(frameState);
|
||||||
|
var layerState = layer.getLayerState();
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 200;
|
||||||
|
canvas.height = 100;
|
||||||
|
var context = {
|
||||||
|
canvas: canvas,
|
||||||
|
drawImage: sinon.spy()
|
||||||
|
};
|
||||||
|
renderer.composeFrame(frameState, layerState, context);
|
||||||
|
expect(context.drawImage.firstCall.args[0].width).to.be(112);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -265,11 +265,13 @@ describe('ol.source.TileWMS', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('#setUrl()', function() {
|
describe('#setUrl()', function() {
|
||||||
var source = new ol.source.TileWMS(options);
|
it('sets the correct url', function() {
|
||||||
var url = 'http://foo/';
|
var source = new ol.source.TileWMS(options);
|
||||||
source.setUrl(url);
|
var url = 'http://foo/';
|
||||||
var tileUrl = source.tileUrlFunction([0, 0, 0], 1, ol.proj.get('EPSG:4326'));
|
source.setUrl(url);
|
||||||
expect(tileUrl.indexOf(url)).to.be(0);
|
var tileUrl = source.tileUrlFunction([0, 0, 0], 1, ol.proj.get('EPSG:4326'));
|
||||||
|
expect(tileUrl.indexOf(url)).to.be(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#setUrls()', function() {
|
describe('#setUrls()', function() {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -19,11 +19,12 @@ describe('ol.rendering.layer.Tile', function() {
|
|||||||
|
|
||||||
var target, map;
|
var target, map;
|
||||||
|
|
||||||
function createMap(renderer, opt_center, opt_size) {
|
function createMap(renderer, opt_center, opt_size, opt_pixelRatio) {
|
||||||
var size = opt_size !== undefined ? opt_size : [50, 50];
|
var size = opt_size !== undefined ? opt_size : [50, 50];
|
||||||
target = createMapDiv(size[0], size[1]);
|
target = createMapDiv(size[0], size[1]);
|
||||||
|
|
||||||
map = new ol.Map({
|
map = new ol.Map({
|
||||||
|
pixelRatio: opt_pixelRatio || 1,
|
||||||
target: target,
|
target: target,
|
||||||
renderer: renderer,
|
renderer: renderer,
|
||||||
view: new ol.View({
|
view: new ol.View({
|
||||||
@@ -152,6 +153,24 @@ describe('ol.rendering.layer.Tile', function() {
|
|||||||
IMAGE_TOLERANCE, done);
|
IMAGE_TOLERANCE, done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('tests canvas layer extent clipping (HiDPI)', function(done) {
|
||||||
|
map = createMap('canvas', undefined, undefined, 2);
|
||||||
|
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
|
||||||
|
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-hidpi.png',
|
||||||
|
IMAGE_TOLERANCE, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tests canvas layer extent clipping with rotation (HiDPI)', function(done) {
|
||||||
|
map = createMap('canvas', undefined, undefined, 2);
|
||||||
|
map.getView().setRotation(Math.PI / 2);
|
||||||
|
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
|
||||||
|
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-rotate-hidpi.png',
|
||||||
|
IMAGE_TOLERANCE, done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('tile layer with opacity', function() {
|
describe('tile layer with opacity', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user