Merge pull request #5482 from ischneider/layer-extent

Fix for regression in tile layer extent
This commit is contained in:
Tim Schaub
2016-06-30 15:19:13 -06:00
committed by GitHub
6 changed files with 79 additions and 15 deletions

View File

@@ -4,13 +4,12 @@ title: Limited Layer Extent
shortdesc: Restricting layer rendering to a limited extent.
docs: >
This example uses the <code>layer.setExtent()</code> method to
modify the extent of the overlay layer. Use the controls below
to limit rendering based on an extent.
modify the extent of the overlay layer. Use the controls above
to limit rendering based on an extent (approximate country bounds).
tags: "extent, tilejson"
---
<div id="map" class="map"></div>
<button type="button" class="btn btn-default" id="northwest">northwest</button>
<button type="button" class="btn btn-default" id="northeast">northeast</button>
<button type="button" class="btn btn-default" id="southeast">southeast</button>
<button type="button" class="btn btn-default" id="southwest">southwest</button>
<button type="button" class="btn btn-default" id="world">world</button>
<button type="button" class="btn btn-default" id="India">India</button>
<button type="button" class="btn btn-default" id="Argentina">Argentina</button>
<button type="button" class="btn btn-default" id="Nigeria">Nigeria</button>
<button type="button" class="btn btn-default" id="Sweden">Sweden</button>

View File

@@ -3,17 +3,17 @@ goog.require('ol.View');
goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.TileJSON');
goog.require('ol.interaction.DragRotateAndZoom');
function transform(extent) {
return ol.proj.transformExtent(extent, 'EPSG:4326', 'EPSG:3857');
}
var extents = {
northwest: transform([-180, 0, 0, 85]),
northeast: transform([0, 0, 180, 85]),
southeast: transform([0, -85, 180, 0]),
southwest: transform([-180, -85, 0, 0]),
world: transform([-180, -85, 180, 85])
India: transform([68.17665, 7.96553, 97.40256, 35.49401]),
Argentina: transform([-73.41544, -55.25, -53.62835, -21.83231]),
Nigeria: transform([2.6917, 4.24059, 14.57718, 13.86592]),
Sweden: transform([11.02737, 55.36174, 23.90338, 69.10625])
};
var base = new ol.layer.Tile({
@@ -25,7 +25,7 @@ var base = new ol.layer.Tile({
});
var overlay = new ol.layer.Tile({
extent: extents.northwest,
extent: extents.India,
source: new ol.source.TileJSON({
url: 'http://api.tiles.mapbox.com/v3/' +
'mapbox.world-glass.json',
@@ -43,6 +43,8 @@ var map = new ol.Map({
})
});
map.addInteraction(new ol.interaction.DragRotateAndZoom());
for (var key in extents) {
document.getElementById(key).onclick = function(event) {
overlay.setExtent(extents[event.target.id]);

View File

@@ -276,6 +276,41 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
tilesToDraw.reverse();
pixelExtents = [];
}
var extent = layerState.extent;
var clipped = extent !== undefined;
if (clipped) {
goog.asserts.assert(extent !== undefined,
'layerState extent is defined');
var topLeft = ol.extent.getTopLeft(extent);
var topRight = ol.extent.getTopRight(extent);
var bottomRight = ol.extent.getBottomRight(extent);
var bottomLeft = ol.extent.getBottomLeft(extent);
ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
topLeft, topLeft);
ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
topRight, topRight);
ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
bottomRight, bottomRight);
ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
bottomLeft, bottomLeft);
var ox = drawOffsetX || 0;
var oy = drawOffsetY || 0;
renderContext.save();
var cx = (renderContext.canvas.width * pixelRatio) / 2;
var cy = (renderContext.canvas.height * pixelRatio) / 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.clip();
ol.render.canvas.rotateAtOffset(renderContext, rotation, cx, cy);
}
for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) {
var tile = tilesToDraw[i];
var tileCoord = tile.getTileCoord();
@@ -324,6 +359,10 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
}
}
if (clipped) {
renderContext.restore();
}
if (hasRenderListeners) {
var dX = drawOffsetX - offsetX / drawScale + offsetX;
var dY = drawOffsetY - offsetY / drawScale + offsetY;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -29,7 +29,7 @@ describe('ol.rendering.layer.Tile', function() {
}
};
sources.forEach(function(source) {
sources.forEach(function(source, i) {
source.on('tileloadstart', function(event) {
tilesLoading++;
});
@@ -44,7 +44,7 @@ describe('ol.rendering.layer.Tile', function() {
var options = {
source: source
};
ol.object.assign(options, layerOptions);
ol.object.assign(options, layerOptions[i] || layerOptions);
map.addLayer(new ol.layer.Tile(options));
});
}
@@ -112,6 +112,30 @@ describe('ol.rendering.layer.Tile', function() {
IMAGE_TOLERANCE, done);
});
});
function centerExtent(map) {
var c = map.getView().calculateExtent(map.getSize());
var qw = ol.extent.getSize(c)[0] / 4;
var qh = ol.extent.getSize(c)[1] / 4;
return [c[0] + qw, c[1] + qh, c[2] - qw, c[3] - qh];
}
it('tests canvas layer extent clipping', function(done) {
map = createMap('canvas');
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent.png',
IMAGE_TOLERANCE, done);
});
});
it('tests canvas layer extent clipping with rotation', function(done) {
map = createMap('canvas');
map.getView().setRotation(Math.PI / 2);
waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() {
expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-rotate.png',
IMAGE_TOLERANCE, done);
});
});
});
describe('tile layer with opacity', function() {