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.EventType');
|
||||
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 renderContext = context;
|
||||
var drawOffsetX, drawOffsetY, drawScale, drawSize;
|
||||
var drawScale = 1;
|
||||
var drawOffsetX, drawOffsetY, drawSize;
|
||||
if (rotation || hasRenderListeners) {
|
||||
renderContext = this.context;
|
||||
var renderCanvas = renderContext.canvas;
|
||||
var drawZ = tileGrid.getZForResolution(resolution);
|
||||
var drawTileSize = source.getTilePixelSize(drawZ, pixelRatio, projection);
|
||||
var tileSize = ol.size.toSize(tileGrid.getTileSize(drawZ));
|
||||
drawScale = drawTileSize[0] / tileSize[0];
|
||||
drawScale = source.getTilePixelRatio(pixelRatio) / pixelRatio;
|
||||
var width = context.canvas.width * drawScale;
|
||||
var height = context.canvas.height * drawScale;
|
||||
// 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 oy = drawOffsetY || 0;
|
||||
renderContext.save();
|
||||
var cx = (renderContext.canvas.width * pixelRatio) / 2;
|
||||
var cy = (renderContext.canvas.height * pixelRatio) / 2;
|
||||
var cx = (renderContext.canvas.width) / 2;
|
||||
var cy = (renderContext.canvas.height) / 2;
|
||||
ol.render.canvas.rotateAtOffset(renderContext, -rotation, cx, cy);
|
||||
renderContext.beginPath();
|
||||
renderContext.moveTo(topLeft[0] * pixelRatio + ox, topLeft[1] * pixelRatio + oy);
|
||||
renderContext.lineTo(topRight[0] * pixelRatio + ox, topRight[1] * pixelRatio + oy);
|
||||
renderContext.lineTo(bottomRight[0] * pixelRatio + ox, bottomRight[1] * pixelRatio + oy);
|
||||
renderContext.lineTo(bottomLeft[0] * pixelRatio + ox, bottomLeft[1] * pixelRatio + oy);
|
||||
renderContext.moveTo(drawScale * (topLeft[0] * pixelRatio + ox),
|
||||
drawScale * (topLeft[1] * pixelRatio + oy));
|
||||
renderContext.lineTo(drawScale * (topRight[0] * pixelRatio + ox),
|
||||
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();
|
||||
ol.render.canvas.rotateAtOffset(renderContext, rotation, cx, cy);
|
||||
}
|
||||
|
||||
48
test/spec/ol/renderer/canvas/tilelayer.test.js
Normal file
48
test/spec/ol/renderer/canvas/tilelayer.test.js
Normal file
@@ -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() {
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var url = 'http://foo/';
|
||||
source.setUrl(url);
|
||||
var tileUrl = source.tileUrlFunction([0, 0, 0], 1, ol.proj.get('EPSG:4326'));
|
||||
expect(tileUrl.indexOf(url)).to.be(0);
|
||||
it('sets the correct url', function() {
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var url = 'http://foo/';
|
||||
source.setUrl(url);
|
||||
var tileUrl = source.tileUrlFunction([0, 0, 0], 1, ol.proj.get('EPSG:4326'));
|
||||
expect(tileUrl.indexOf(url)).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
target = createMapDiv(size[0], size[1]);
|
||||
|
||||
map = new ol.Map({
|
||||
pixelRatio: opt_pixelRatio || 1,
|
||||
target: target,
|
||||
renderer: renderer,
|
||||
view: new ol.View({
|
||||
@@ -152,6 +153,24 @@ describe('ol.rendering.layer.Tile', function() {
|
||||
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() {
|
||||
|
||||
Reference in New Issue
Block a user