Merge pull request #1533 from twpayne/vector-api-tile-hidpi
[vector-api] HiDPI support for tile layers
This commit is contained in:
@@ -18,7 +18,7 @@ var projection = ol.proj.configureProj4jsProjection({
|
||||
var extent = [420000, 30000, 900000, 350000];
|
||||
var layers = [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileWMS({
|
||||
source: new ol.source.TileWMS(/** @type {olx.source.TileWMSOptions} */ ({
|
||||
url: 'http://wms.geo.admin.ch/',
|
||||
crossOrigin: 'anonymous',
|
||||
attributions: [new ol.Attribution({
|
||||
@@ -31,11 +31,12 @@ var layers = [
|
||||
'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
|
||||
'FORMAT': 'image/jpeg'
|
||||
},
|
||||
extent: extent
|
||||
})
|
||||
extent: extent,
|
||||
serverType: 'mapserver'
|
||||
}))
|
||||
}),
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileWMS({
|
||||
source: new ol.source.TileWMS(/** @type {olx.source.TileWMSOptions} */ ({
|
||||
url: 'http://wms.geo.admin.ch/',
|
||||
crossOrigin: 'anonymous',
|
||||
attributions: [new ol.Attribution({
|
||||
@@ -45,8 +46,9 @@ var layers = [
|
||||
'National parks / geo.admin.ch</a>'
|
||||
})],
|
||||
params: {'LAYERS': 'ch.bafu.schutzgebiete-paerke_nationaler_bedeutung'},
|
||||
extent: extent
|
||||
})
|
||||
extent: extent,
|
||||
serverType: 'mapserver'
|
||||
}))
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
@@ -11,11 +11,12 @@ var layers = [
|
||||
source: new ol.source.MapQuest({layer: 'sat'})
|
||||
}),
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileWMS({
|
||||
source: new ol.source.TileWMS(/** @type {olx.source.TileWMSOptions} */ ({
|
||||
url: 'http://demo.opengeo.org/geoserver/wms',
|
||||
params: {'LAYERS': 'topp:states', 'TILED': true},
|
||||
extent: [-13884991, 2870341, -7455066, 6338219]
|
||||
})
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
serverType: 'geoserver'
|
||||
}))
|
||||
})
|
||||
];
|
||||
var map = new ol.Map({
|
||||
|
||||
@@ -755,10 +755,15 @@
|
||||
* edges" issues by properly configuring the WMS service. For example, MapServer
|
||||
* has a `tile_map_edge_buffer` configuration parameter for this. See
|
||||
* http://mapserver.org/output/tile_mode.html.
|
||||
* @property {boolean|undefined} hidpi Use the `ol.Map#pixelRatio` value when
|
||||
* requesting the image from the remote server. Default is `true`.
|
||||
* @property {string|undefined} logo Logo.
|
||||
* @property {ol.tilegrid.TileGrid|undefined} tileGrid Tile grid.
|
||||
* @property {number|undefined} maxZoom Maximum zoom.
|
||||
* @property {ol.proj.ProjectionLike} projection Projection.
|
||||
* @property {ol.source.wms.ServerType|undefined} serverType The type of the remote WMS
|
||||
* server: `mapserver`, `geoserver` or `qgis`. Only needed if `hidpi` is `true`.
|
||||
* Default is `undefined`.
|
||||
* @property {ol.TileLoadFunctionType|undefined} tileLoadFunction Optional
|
||||
* function to load a tile given a URL.
|
||||
* @property {string|undefined} url WMS service URL.
|
||||
|
||||
@@ -164,6 +164,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
// composition and positioning.
|
||||
//
|
||||
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var view2DState = frameState.view2DState;
|
||||
var projection = view2DState.projection;
|
||||
|
||||
@@ -171,14 +172,14 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
goog.asserts.assertInstanceof(tileLayer, ol.layer.Tile);
|
||||
var tileSource = tileLayer.getSource();
|
||||
goog.asserts.assertInstanceof(tileSource, ol.source.Tile);
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
if (goog.isNull(tileGrid)) {
|
||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||
}
|
||||
var tileGrid = tileSource.getTileGridForProjection(projection);
|
||||
var tileGutter = tileSource.getGutter();
|
||||
var z = tileGrid.getZForResolution(view2DState.resolution);
|
||||
var tileSize = tileGrid.getTileSize(z);
|
||||
var tilePixelSize =
|
||||
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
|
||||
var tilePixelRatio = tilePixelSize / tileGrid.getTileSize(z);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
var tilePixelResolution = tileResolution / tilePixelRatio;
|
||||
var center = view2DState.center;
|
||||
var extent;
|
||||
if (tileResolution == view2DState.resolution) {
|
||||
@@ -191,8 +192,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||
extent, tileResolution);
|
||||
|
||||
var canvasWidth = tileSize * tileRange.getWidth();
|
||||
var canvasHeight = tileSize * tileRange.getHeight();
|
||||
var canvasWidth = tilePixelSize * tileRange.getWidth();
|
||||
var canvasHeight = tilePixelSize * tileRange.getHeight();
|
||||
|
||||
var canvas, context;
|
||||
if (goog.isNull(this.canvas_)) {
|
||||
@@ -231,8 +232,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
|
||||
var canvasTileRange, canvasTileRangeWidth, minX, minY;
|
||||
if (goog.isNull(this.renderedCanvasTileRange_)) {
|
||||
canvasTileRangeWidth = canvasWidth / tileSize;
|
||||
var canvasTileRangeHeight = canvasHeight / tileSize;
|
||||
canvasTileRangeWidth = canvasWidth / tilePixelSize;
|
||||
var canvasTileRangeHeight = canvasHeight / tilePixelSize;
|
||||
minX = tileRange.minX -
|
||||
Math.floor((canvasTileRangeWidth - tileRange.getWidth()) / 2);
|
||||
minY = tileRange.minY -
|
||||
@@ -261,7 +262,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
|
||||
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
|
||||
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED;
|
||||
}, tileSource, projection);
|
||||
}, tileSource, pixelRatio, projection);
|
||||
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
|
||||
tilesToDrawByZ, getTileIfLoaded);
|
||||
|
||||
@@ -271,7 +272,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
|
||||
tile = tileSource.getTile(z, x, y, projection);
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.LOADED ||
|
||||
tileState == ol.TileState.EMPTY ||
|
||||
@@ -299,9 +300,9 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
var i, ii;
|
||||
for (i = 0, ii = tilesToClear.length; i < ii; ++i) {
|
||||
tile = tilesToClear[i];
|
||||
x = tileSize * (tile.tileCoord.x - canvasTileRange.minX);
|
||||
y = tileSize * (canvasTileRange.maxY - tile.tileCoord.y);
|
||||
context.clearRect(x, y, tileSize, tileSize);
|
||||
x = tilePixelSize * (tile.tileCoord.x - canvasTileRange.minX);
|
||||
y = tilePixelSize * (canvasTileRange.maxY - tile.tileCoord.y);
|
||||
context.clearRect(x, y, tilePixelSize, tilePixelSize);
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
@@ -316,7 +317,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
var height, width;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
currentZ = zs[i];
|
||||
tileSize = tileGrid.getTileSize(currentZ);
|
||||
tilePixelSize =
|
||||
tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
|
||||
tilesToDraw = tilesToDrawByZ[currentZ];
|
||||
if (currentZ == z) {
|
||||
for (tileCoordKey in tilesToDraw) {
|
||||
@@ -325,18 +327,18 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
(tile.tileCoord.y - canvasTileRange.minY) * canvasTileRangeWidth +
|
||||
(tile.tileCoord.x - canvasTileRange.minX);
|
||||
if (this.renderedTiles_[index] != tile) {
|
||||
x = tileSize * (tile.tileCoord.x - canvasTileRange.minX);
|
||||
y = tileSize * (canvasTileRange.maxY - tile.tileCoord.y);
|
||||
x = tilePixelSize * (tile.tileCoord.x - canvasTileRange.minX);
|
||||
y = tilePixelSize * (canvasTileRange.maxY - tile.tileCoord.y);
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.EMPTY ||
|
||||
tileState == ol.TileState.ERROR ||
|
||||
!opaque) {
|
||||
context.clearRect(x, y, tileSize, tileSize);
|
||||
context.clearRect(x, y, tilePixelSize, tilePixelSize);
|
||||
}
|
||||
if (tileState == ol.TileState.LOADED) {
|
||||
context.drawImage(tile.getImage(),
|
||||
tileGutter, tileGutter, tileSize, tileSize,
|
||||
x, y, tileSize, tileSize);
|
||||
tileGutter, tileGutter, tilePixelSize, tilePixelSize,
|
||||
x, y, tilePixelSize, tilePixelSize);
|
||||
}
|
||||
this.renderedTiles_[index] = tile;
|
||||
}
|
||||
@@ -346,17 +348,17 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
for (tileCoordKey in tilesToDraw) {
|
||||
tile = tilesToDraw[tileCoordKey];
|
||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
||||
x = (tileExtent[0] - origin[0]) / tileResolution;
|
||||
y = (origin[1] - tileExtent[3]) / tileResolution;
|
||||
width = scale * tileSize;
|
||||
height = scale * tileSize;
|
||||
x = (tileExtent[0] - origin[0]) / tilePixelResolution;
|
||||
y = (origin[1] - tileExtent[3]) / tilePixelResolution;
|
||||
width = scale * tilePixelSize;
|
||||
height = scale * tilePixelSize;
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.EMPTY || !opaque) {
|
||||
context.clearRect(x, y, width, height);
|
||||
}
|
||||
if (tileState == ol.TileState.LOADED) {
|
||||
context.drawImage(tile.getImage(),
|
||||
tileGutter, tileGutter, tileSize, tileSize,
|
||||
tileGutter, tileGutter, tilePixelSize, tilePixelSize,
|
||||
x, y, width, height);
|
||||
}
|
||||
interimTileRange =
|
||||
@@ -377,19 +379,18 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
|
||||
}
|
||||
|
||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||
this.manageTilePyramid(frameState, tileSource, tileGrid, projection, extent,
|
||||
z, tileLayer.getPreload());
|
||||
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
|
||||
projection, extent, z, tileLayer.getPreload());
|
||||
this.scheduleExpireCache(frameState, tileSource);
|
||||
this.updateLogos(frameState, tileSource);
|
||||
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
ol.vec.Mat4.makeTransform2D(this.imageTransform_,
|
||||
pixelRatio * frameState.size[0] / 2,
|
||||
pixelRatio * frameState.size[1] / 2,
|
||||
pixelRatio * tileResolution / view2DState.resolution,
|
||||
pixelRatio * tileResolution / view2DState.resolution,
|
||||
pixelRatio * tilePixelResolution / view2DState.resolution,
|
||||
pixelRatio * tilePixelResolution / view2DState.resolution,
|
||||
view2DState.rotation,
|
||||
(origin[0] - center[0]) / tileResolution,
|
||||
(center[1] - origin[1]) / tileResolution);
|
||||
(origin[0] - center[0]) / tilePixelResolution,
|
||||
(center[1] - origin[1]) / tilePixelResolution);
|
||||
|
||||
};
|
||||
|
||||
@@ -81,6 +81,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
|
||||
return;
|
||||
}
|
||||
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var view2DState = frameState.view2DState;
|
||||
var projection = view2DState.projection;
|
||||
|
||||
@@ -88,10 +89,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
|
||||
goog.asserts.assertInstanceof(tileLayer, ol.layer.Tile);
|
||||
var tileSource = tileLayer.getSource();
|
||||
goog.asserts.assertInstanceof(tileSource, ol.source.Tile);
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
if (goog.isNull(tileGrid)) {
|
||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||
}
|
||||
var tileGrid = tileSource.getTileGridForProjection(projection);
|
||||
var tileGutter = tileSource.getGutter();
|
||||
var z = tileGrid.getZForResolution(view2DState.resolution);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
@@ -113,7 +111,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
|
||||
|
||||
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
|
||||
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED;
|
||||
}, tileSource, projection);
|
||||
}, tileSource, pixelRatio, projection);
|
||||
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
|
||||
tilesToDrawByZ, getTileIfLoaded);
|
||||
|
||||
@@ -123,7 +121,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
|
||||
tile = tileSource.getTile(z, x, y, projection);
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.LOADED) {
|
||||
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
|
||||
@@ -241,8 +239,8 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
|
||||
}
|
||||
|
||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||
this.manageTilePyramid(frameState, tileSource, tileGrid, projection, extent,
|
||||
z, tileLayer.getPreload());
|
||||
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
|
||||
projection, extent, z, tileLayer.getPreload());
|
||||
this.scheduleExpireCache(frameState, tileSource);
|
||||
this.updateLogos(frameState, tileSource);
|
||||
|
||||
@@ -339,8 +337,12 @@ ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) {
|
||||
imageStyle.position = 'absolute';
|
||||
imageStyle.left = -tileGutter + 'px';
|
||||
imageStyle.top = -tileGutter + 'px';
|
||||
imageStyle.width = (tileSize + 2 * tileGutter) + 'px';
|
||||
imageStyle.height = (tileSize + 2 * tileGutter) + 'px';
|
||||
goog.dom.appendChild(tileElement, image);
|
||||
} else {
|
||||
imageStyle.width = tileSize + 'px';
|
||||
imageStyle.height = tileSize + 'px';
|
||||
tileElement = image;
|
||||
tileElementStyle = imageStyle;
|
||||
}
|
||||
|
||||
@@ -197,13 +197,14 @@ ol.renderer.Layer.prototype.updateUsedTiles =
|
||||
* @param {function(ol.Tile): boolean} isLoadedFunction Function to
|
||||
* determine if the tile is loaded.
|
||||
* @param {ol.source.Tile} tileSource Tile source.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @protected
|
||||
* @return {function(number, number, number): ol.Tile} Returns a tile if it is
|
||||
* loaded.
|
||||
*/
|
||||
ol.renderer.Layer.prototype.createGetTileIfLoadedFunction =
|
||||
function(isLoadedFunction, tileSource, projection) {
|
||||
function(isLoadedFunction, tileSource, pixelRatio, projection) {
|
||||
return (
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
@@ -212,7 +213,7 @@ ol.renderer.Layer.prototype.createGetTileIfLoadedFunction =
|
||||
* @return {ol.Tile} Tile.
|
||||
*/
|
||||
function(z, x, y) {
|
||||
var tile = tileSource.getTile(z, x, y, projection);
|
||||
var tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
return isLoadedFunction(tile) ? tile : null;
|
||||
});
|
||||
};
|
||||
@@ -244,6 +245,7 @@ ol.renderer.Layer.prototype.snapCenterToPixel =
|
||||
* @param {ol.FrameState} frameState Frame state.
|
||||
* @param {ol.source.Tile} tileSource Tile source.
|
||||
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} currentZ Current Z.
|
||||
@@ -254,8 +256,8 @@ ol.renderer.Layer.prototype.snapCenterToPixel =
|
||||
* @template T
|
||||
*/
|
||||
ol.renderer.Layer.prototype.manageTilePyramid = function(
|
||||
frameState, tileSource, tileGrid, projection, extent, currentZ, preload,
|
||||
opt_tileCallback, opt_this) {
|
||||
frameState, tileSource, tileGrid, pixelRatio, projection, extent,
|
||||
currentZ, preload, opt_tileCallback, opt_this) {
|
||||
var tileSourceKey = goog.getUid(tileSource).toString();
|
||||
if (!(tileSourceKey in frameState.wantedTiles)) {
|
||||
frameState.wantedTiles[tileSourceKey] = {};
|
||||
@@ -270,7 +272,7 @@ ol.renderer.Layer.prototype.manageTilePyramid = function(
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
if (currentZ - z <= preload) {
|
||||
tile = tileSource.getTile(z, x, y, projection);
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
if (tile.getState() == ol.TileState.IDLE) {
|
||||
wantedTiles[tile.tileCoord.toString()] = true;
|
||||
if (!tileQueue.isKeyQueued(tile.getKey())) {
|
||||
|
||||
@@ -473,10 +473,11 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||
layerRenderer.prepareFrame(frameState, layerState);
|
||||
}
|
||||
|
||||
var size = frameState.size;
|
||||
if (this.canvas_.width != size[0] || this.canvas_.height != size[1]) {
|
||||
this.canvas_.width = size[0];
|
||||
this.canvas_.height = size[1];
|
||||
var width = frameState.size[0] * frameState.pixelRatio;
|
||||
var height = frameState.size[1] * frameState.pixelRatio;
|
||||
if (this.canvas_.width != width || this.canvas_.height != height) {
|
||||
this.canvas_.width = width;
|
||||
this.canvas_.height = height;
|
||||
}
|
||||
|
||||
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, null);
|
||||
|
||||
@@ -121,14 +121,14 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
goog.asserts.assertInstanceof(tileLayer, ol.layer.Tile);
|
||||
var tileSource = tileLayer.getSource();
|
||||
goog.asserts.assertInstanceof(tileSource, ol.source.Tile);
|
||||
var tileGrid = tileSource.getTileGrid();
|
||||
if (goog.isNull(tileGrid)) {
|
||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||
}
|
||||
var tileGrid = tileSource.getTileGridForProjection(projection);
|
||||
var z = tileGrid.getZForResolution(view2DState.resolution);
|
||||
var tileResolution = tileGrid.getResolution(z);
|
||||
|
||||
var tileSize = tileGrid.getTileSize(z);
|
||||
var tilePixelSize =
|
||||
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
|
||||
var pixelRatio = tilePixelSize / tileGrid.getTileSize(z);
|
||||
var tilePixelResolution = tileResolution / pixelRatio;
|
||||
var tileGutter = tileSource.getGutter();
|
||||
|
||||
var center = view2DState.center;
|
||||
@@ -152,13 +152,13 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
|
||||
var tileRangeSize = tileRange.getSize();
|
||||
|
||||
var maxDimension =
|
||||
Math.max(tileRangeSize[0] * tileSize, tileRangeSize[1] * tileSize);
|
||||
var maxDimension = Math.max(
|
||||
tileRangeSize[0] * tilePixelSize, tileRangeSize[1] * tilePixelSize);
|
||||
var framebufferDimension = ol.math.roundUpToPowerOfTwo(maxDimension);
|
||||
var framebufferExtentDimension = tileResolution * framebufferDimension;
|
||||
var framebufferExtentDimension = tilePixelResolution * framebufferDimension;
|
||||
var origin = tileGrid.getOrigin(z);
|
||||
var minX = origin[0] + tileRange.minX * tileSize * tileResolution;
|
||||
var minY = origin[1] + tileRange.minY * tileSize * tileResolution;
|
||||
var minX = origin[0] + tileRange.minX * tilePixelSize * tilePixelResolution;
|
||||
var minY = origin[1] + tileRange.minY * tilePixelSize * tilePixelResolution;
|
||||
framebufferExtent = [
|
||||
minX, minY,
|
||||
minX + framebufferExtentDimension, minY + framebufferExtentDimension
|
||||
@@ -196,7 +196,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
|
||||
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED &&
|
||||
mapRenderer.isTileTextureLoaded(tile);
|
||||
}, tileSource, projection);
|
||||
}, tileSource, pixelRatio, projection);
|
||||
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
|
||||
tilesToDrawByZ, getTileIfLoaded);
|
||||
|
||||
@@ -207,7 +207,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
|
||||
tile = tileSource.getTile(z, x, y, projection);
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
tileState = tile.getState();
|
||||
if (tileState == ol.TileState.LOADED) {
|
||||
if (mapRenderer.isTileTextureLoaded(tile)) {
|
||||
@@ -254,8 +254,8 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
framebufferExtentDimension - 1;
|
||||
goog.vec.Vec4.setFromValues(u_tileOffset, sx, sy, tx, ty);
|
||||
gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);
|
||||
mapRenderer.bindTileTexture(tile, tileSize, tileGutter,
|
||||
goog.webgl.LINEAR, goog.webgl.LINEAR);
|
||||
mapRenderer.bindTileTexture(tile, tilePixelSize,
|
||||
tileGutter * pixelRatio, goog.webgl.LINEAR, goog.webgl.LINEAR);
|
||||
gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||
var tileTextureQueue = mapRenderer.getTileTextureQueue();
|
||||
this.manageTilePyramid(
|
||||
frameState, tileSource, tileGrid, projection, extent, z,
|
||||
frameState, tileSource, tileGrid, pixelRatio, projection, extent, z,
|
||||
tileLayer.getPreload(),
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
@@ -289,7 +289,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
|
||||
tile,
|
||||
tileGrid.getTileCoordCenter(tile.tileCoord),
|
||||
tileGrid.getResolution(tile.tileCoord.z),
|
||||
tileSize, tileGutter
|
||||
tilePixelSize, tileGutter * pixelRatio
|
||||
]);
|
||||
}
|
||||
}, this);
|
||||
|
||||
@@ -101,10 +101,11 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse =
|
||||
/**
|
||||
* @this {ol.source.BingMaps}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, projection) {
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
goog.asserts.assert(ol.proj.equivalent(
|
||||
projection, this.getProjection()));
|
||||
if (goog.isNull(tileCoord)) {
|
||||
|
||||
@@ -119,14 +119,15 @@ ol.source.TileImage.prototype.expireCache = function(usedTiles) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.TileImage.prototype.getTile = function(z, x, y, projection) {
|
||||
ol.source.TileImage.prototype.getTile =
|
||||
function(z, x, y, pixelRatio, projection) {
|
||||
var tileCoordKey = this.getKeyZXY(z, x, y);
|
||||
if (this.tileCache.containsKey(tileCoordKey)) {
|
||||
return /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey));
|
||||
} else {
|
||||
goog.asserts.assert(projection);
|
||||
var tileCoord = new ol.TileCoord(z, x, y);
|
||||
var tileUrl = this.tileUrlFunction(tileCoord, projection);
|
||||
var tileUrl = this.tileUrlFunction(tileCoord, pixelRatio, projection);
|
||||
var tile = new this.tileClass(
|
||||
tileCoord,
|
||||
goog.isDef(tileUrl) ? ol.TileState.IDLE : ol.TileState.EMPTY,
|
||||
|
||||
@@ -144,6 +144,7 @@ ol.source.Tile.prototype.getResolutions = function() {
|
||||
* @param {number} z Tile coordinate z.
|
||||
* @param {number} x Tile coordinate x.
|
||||
* @param {number} y Tile coordinate y.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection=} opt_projection Projection.
|
||||
* @return {!ol.Tile} Tile.
|
||||
*/
|
||||
@@ -158,6 +159,32 @@ ol.source.Tile.prototype.getTileGrid = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {ol.tilegrid.TileGrid} Tile grid.
|
||||
*/
|
||||
ol.source.Tile.prototype.getTileGridForProjection = function(projection) {
|
||||
if (goog.isNull(this.tileGrid)) {
|
||||
return ol.tilegrid.getForProjection(projection);
|
||||
} else {
|
||||
return this.tileGrid;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {number} Tile size.
|
||||
*/
|
||||
ol.source.Tile.prototype.getTilePixelSize =
|
||||
function(z, pixelRatio, projection) {
|
||||
var tileGrid = this.getTileGridForProjection(projection);
|
||||
return tileGrid.getTileSize(z);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Marks a tile coord as being used, without triggering a load.
|
||||
* @param {number} z Tile coordinate z.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
goog.provide('ol.source.TileWMS');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
@@ -13,6 +14,7 @@ goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.source.TileImage');
|
||||
goog.require('ol.source.wms');
|
||||
goog.require('ol.source.wms.ServerType');
|
||||
|
||||
|
||||
|
||||
@@ -71,6 +73,18 @@ ol.source.TileWMS = function(opt_options) {
|
||||
*/
|
||||
this.v13_ = true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.source.wms.ServerType|undefined}
|
||||
*/
|
||||
this.serverType_ = options.serverType;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.hidpi_ = goog.isDef(options.hidpi) ? options.hidpi : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
@@ -117,6 +131,23 @@ ol.source.TileWMS.prototype.getParams = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Z.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {number} Size.
|
||||
*/
|
||||
ol.source.TileWMS.prototype.getTilePixelSize =
|
||||
function(z, pixelRatio, projection) {
|
||||
var tileSize = goog.base(this, 'getTilePixelSize', z, pixelRatio, projection);
|
||||
if (pixelRatio == 1 || !this.hidpi_ || !goog.isDef(this.serverType_)) {
|
||||
return tileSize;
|
||||
} else {
|
||||
return (tileSize * pixelRatio + 0.5) | 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -132,11 +163,13 @@ ol.source.TileWMS.prototype.resetCoordKeyPrefix_ = function() {
|
||||
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @private
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
ol.source.TileWMS.prototype.tileUrlFunction_ = function(tileCoord, projection) {
|
||||
ol.source.TileWMS.prototype.tileUrlFunction_ =
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
|
||||
var urls = this.urls_;
|
||||
if (!goog.isDef(urls) || goog.array.isEmpty(urls)) {
|
||||
@@ -145,7 +178,7 @@ ol.source.TileWMS.prototype.tileUrlFunction_ = function(tileCoord, projection) {
|
||||
|
||||
var tileGrid = this.getTileGrid();
|
||||
if (goog.isNull(tileGrid)) {
|
||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||
tileGrid = this.getTileGridForProjection(projection);
|
||||
}
|
||||
|
||||
if (tileGrid.getResolutions().length <= tileCoord.z) {
|
||||
@@ -164,17 +197,21 @@ ol.source.TileWMS.prototype.tileUrlFunction_ = function(tileCoord, projection) {
|
||||
goog.object.extend(params, this.params_);
|
||||
|
||||
var tileResolution = tileGrid.getResolution(tileCoord.z);
|
||||
if (pixelRatio != 1 && (!this.hidpi_ || !goog.isDef(this.serverType_))) {
|
||||
pixelRatio = 1;
|
||||
}
|
||||
var tileSize = tileGrid.getTileSize(tileCoord.z);
|
||||
var gutter = this.gutter_;
|
||||
if (gutter === 0) {
|
||||
goog.object.set(params, 'WIDTH', tileSize);
|
||||
goog.object.set(params, 'HEIGHT', tileSize);
|
||||
} else {
|
||||
goog.object.set(params, 'WIDTH', tileSize + 2 * gutter);
|
||||
goog.object.set(params, 'HEIGHT', tileSize + 2 * gutter);
|
||||
if (gutter !== 0) {
|
||||
tileSize += 2 * gutter;
|
||||
tileExtent =
|
||||
ol.extent.buffer(tileExtent, tileResolution * gutter, this.tmpExtent_);
|
||||
}
|
||||
if (pixelRatio != 1) {
|
||||
tileSize = (tileSize * pixelRatio + 0.5) | 0;
|
||||
}
|
||||
goog.object.set(params, 'WIDTH', tileSize);
|
||||
goog.object.set(params, 'HEIGHT', tileSize);
|
||||
|
||||
params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
|
||||
|
||||
@@ -182,6 +219,24 @@ ol.source.TileWMS.prototype.tileUrlFunction_ = function(tileCoord, projection) {
|
||||
goog.object.set(params, 'STYLES', new String(''));
|
||||
}
|
||||
|
||||
if (pixelRatio != 1) {
|
||||
switch (this.serverType_) {
|
||||
case ol.source.wms.ServerType.GEOSERVER:
|
||||
var dpi = (90 * pixelRatio + 0.5) | 0;
|
||||
goog.object.set(params, 'FORMAT_OPTIONS', 'dpi:' + dpi);
|
||||
break;
|
||||
case ol.source.wms.ServerType.MAPSERVER:
|
||||
goog.object.set(params, 'MAP_RESOLUTION', 90 * pixelRatio);
|
||||
break;
|
||||
case ol.source.wms.ServerType.QGIS:
|
||||
goog.object.set(params, 'DPI', 90 * pixelRatio);
|
||||
break;
|
||||
default:
|
||||
goog.asserts.fail();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var axisOrientation = projection.getAxisOrientation();
|
||||
var bbox;
|
||||
if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {
|
||||
|
||||
@@ -96,10 +96,11 @@ ol.source.WMTS = function(options) {
|
||||
/**
|
||||
* @this {ol.source.WMTS}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, projection) {
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (goog.isNull(tileCoord)) {
|
||||
return undefined;
|
||||
} else {
|
||||
|
||||
@@ -61,10 +61,11 @@ ol.source.Zoomify = function(opt_options) {
|
||||
/**
|
||||
* @this {ol.source.TileImage}
|
||||
* @param {ol.TileCoord} tileCoord Tile Coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, projection) {
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (goog.isNull(tileCoord)) {
|
||||
return undefined;
|
||||
} else {
|
||||
|
||||
@@ -8,7 +8,7 @@ goog.require('ol.TileCoord');
|
||||
|
||||
/**
|
||||
* @typedef {function(this: ol.source.TileImage, ol.TileCoord,
|
||||
* ol.proj.Projection): (string|undefined)}
|
||||
* number, ol.proj.Projection): (string|undefined)}
|
||||
*/
|
||||
ol.TileUrlFunctionType;
|
||||
|
||||
@@ -29,10 +29,11 @@ ol.TileUrlFunction.createFromTemplate = function(template) {
|
||||
/**
|
||||
* @this {ol.source.TileImage}
|
||||
* @param {ol.TileCoord} tileCoord Tile Coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, projection) {
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (goog.isNull(tileCoord)) {
|
||||
return undefined;
|
||||
} else {
|
||||
@@ -66,16 +67,18 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) {
|
||||
/**
|
||||
* @this {ol.source.TileImage}
|
||||
* @param {ol.TileCoord} tileCoord Tile Coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, projection) {
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (goog.isNull(tileCoord)) {
|
||||
return undefined;
|
||||
} else {
|
||||
var index =
|
||||
goog.math.modulo(tileCoord.hash(), tileUrlFunctions.length);
|
||||
return tileUrlFunctions[index].call(this, tileCoord, projection);
|
||||
return tileUrlFunctions[index].call(
|
||||
this, tileCoord, pixelRatio, projection);
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -84,10 +87,12 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) {
|
||||
/**
|
||||
* @this {ol.source.TileImage}
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
ol.TileUrlFunction.nullTileUrlFunction = function(tileCoord, projection) {
|
||||
ol.TileUrlFunction.nullTileUrlFunction =
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
@@ -104,16 +109,18 @@ ol.TileUrlFunction.withTileCoordTransform =
|
||||
/**
|
||||
* @this {ol.source.TileImage}
|
||||
* @param {ol.TileCoord} tileCoord Tile Coordinate.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {string|undefined} Tile URL.
|
||||
*/
|
||||
function(tileCoord, projection) {
|
||||
function(tileCoord, pixelRatio, projection) {
|
||||
if (goog.isNull(tileCoord)) {
|
||||
return undefined;
|
||||
} else {
|
||||
return tileUrlFunction.call(
|
||||
this,
|
||||
transformFn.call(this, tileCoord, projection, tmpTileCoord),
|
||||
pixelRatio,
|
||||
projection);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ describe('ol.source.TileWMS', function() {
|
||||
|
||||
it('returns a tile with the expected URL', function() {
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('EPSG:3857'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
|
||||
expect(tile).to.be.an(ol.ImageTile);
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
expect(uri.getScheme()).to.be('http');
|
||||
@@ -44,7 +44,7 @@ describe('ol.source.TileWMS', function() {
|
||||
it('returns a larger tile when a gutter is specified', function() {
|
||||
options.gutter = 16;
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('EPSG:3857'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
|
||||
expect(tile).to.be.an(ol.ImageTile);
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
var queryData = uri.getQueryData();
|
||||
@@ -58,7 +58,7 @@ describe('ol.source.TileWMS', function() {
|
||||
it('sets the SRS query value instead of CRS if version < 1.3', function() {
|
||||
options.params.VERSION = '1.2';
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('EPSG:4326'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
var queryData = uri.getQueryData();
|
||||
expect(queryData.get('CRS')).to.be(undefined);
|
||||
@@ -69,7 +69,7 @@ describe('ol.source.TileWMS', function() {
|
||||
options.params.FORMAT = 'image/jpeg';
|
||||
options.params.TRANSPARENT = false;
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('EPSG:4326'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
var queryData = uri.getQueryData();
|
||||
expect(queryData.get('FORMAT')).to.be('image/jpeg');
|
||||
@@ -79,7 +79,7 @@ describe('ol.source.TileWMS', function() {
|
||||
it('does not add a STYLES= option if one is specified', function() {
|
||||
options.params.STYLES = 'foo';
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('EPSG:4326'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
var queryData = uri.getQueryData();
|
||||
expect(queryData.get('STYLES')).to.be('foo');
|
||||
@@ -87,7 +87,7 @@ describe('ol.source.TileWMS', function() {
|
||||
|
||||
it('changes the BBOX order for EN axis orientations', function() {
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('EPSG:4326'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
var queryData = uri.getQueryData();
|
||||
expect(queryData.get('BBOX')).to.be('-45,-90,0,-45');
|
||||
@@ -96,7 +96,7 @@ describe('ol.source.TileWMS', function() {
|
||||
it('uses EN BBOX order if version < 1.3', function() {
|
||||
options.params.VERSION = '1.1.0';
|
||||
var source = new ol.source.TileWMS(options);
|
||||
var tile = source.getTile(3, 2, 1, ol.proj.get('CRS:84'));
|
||||
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('CRS:84'));
|
||||
var uri = new goog.Uri(tile.src_);
|
||||
var queryData = uri.getQueryData();
|
||||
expect(queryData.get('BBOX')).to.be('-90,-45,-45,0');
|
||||
|
||||
Reference in New Issue
Block a user