Files
openlayers/src/ol/source/tiledwmssource.js
ahocevar 87ce763ccb Use validity extent to generate default resolutions
Previously, the TiledWMS source generated a resolutions array
derived from the world extent in meters, to match the default
Web Mercator resolutions of the map. This wouldn't work for
projections with distance units different than meters. It is
better to commit to a default resolutions array where zoom level
0 is the validity extent of the projection (not the Web Mercator
world extent!) at a 256 pixel tile size.
2013-01-14 16:10:55 +01:00

108 lines
3.4 KiB
JavaScript

// FIXME add minZoom support
goog.provide('ol.source.TiledWMS');
goog.require('goog.asserts');
goog.require('goog.object');
goog.require('goog.uri.utils');
goog.require('ol.Attribution');
goog.require('ol.Projection');
goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
goog.require('ol.source.ImageTileSource');
goog.require('ol.tilegrid.TileGrid');
/**
* @constructor
* @extends {ol.source.ImageTileSource}
* @param {ol.source.TiledWMSOptions} tiledWMSOptions options.
*/
ol.source.TiledWMS = function(tiledWMSOptions) {
var projection = ol.Projection.createProjection(
tiledWMSOptions.projection, 'EPSG:3857');
var projectionExtent = projection.getExtent();
var extent = goog.isDef(tiledWMSOptions.extent) ?
tiledWMSOptions.extent : projectionExtent;
var version = goog.isDef(tiledWMSOptions.version) ?
tiledWMSOptions.version : '1.3';
var tileGrid;
if (goog.isDef(tiledWMSOptions.tileGrid)) {
tileGrid = tiledWMSOptions.tileGrid;
} else {
tileGrid = ol.tilegrid.createForProjection(projection,
tiledWMSOptions.maxZoom);
}
var baseParams = {
'SERVICE': 'WMS',
'VERSION': version,
'REQUEST': 'GetMap',
'STYLES': '',
'FORMAT': 'image/png',
'TRANSPARENT': true
};
var tileSize = tileGrid.getTileSize();
baseParams['WIDTH'] = tileSize.width;
baseParams['HEIGHT'] = tileSize.height;
baseParams[version >= '1.3' ? 'CRS' : 'SRS'] = projection.getCode();
goog.object.extend(baseParams, tiledWMSOptions.params);
var tileUrlFunction;
if (tiledWMSOptions.urls) {
var tileUrlFunctions = goog.array.map(
tiledWMSOptions.urls, function(url) {
url = goog.uri.utils.appendParamsFromMap(url, baseParams);
return ol.TileUrlFunction.createBboxParam(url, tileGrid);
});
tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(
tileUrlFunctions);
} else if (tiledWMSOptions.url) {
var url = goog.uri.utils.appendParamsFromMap(
tiledWMSOptions.url, baseParams);
tileUrlFunction = ol.TileUrlFunction.createBboxParam(url, tileGrid);
} else {
tileUrlFunction = ol.TileUrlFunction.nullTileUrlFunction;
}
function tileCoordTransform(tileCoord) {
if (tileGrid.getResolutions().length <= tileCoord.z) {
return null;
}
var x = tileCoord.x;
var tileExtent = tileGrid.getTileCoordExtent(tileCoord);
// FIXME do we want a wrapDateLine param? The code below will break maps
// with projections that do not span the whole world width.
if (extent.minX === projectionExtent.minX &&
extent.maxX === projectionExtent.maxX) {
var numCols = Math.ceil(
(extent.maxX - extent.minX) / (tileExtent.maxX - tileExtent.minX));
x = goog.math.modulo(x, numCols);
tileExtent = tileGrid.getTileCoordExtent(
new ol.TileCoord(tileCoord.z, x, tileCoord.y));
}
// FIXME We shouldn't need a typecast here.
if (!tileExtent.intersects(/** @type {ol.Extent} */ (extent))) {
return null;
}
return new ol.TileCoord(tileCoord.z, x, tileCoord.y);
}
goog.base(this, {
attributions: tiledWMSOptions.attributions,
crossOrigin: tiledWMSOptions.crossOrigin,
extent: extent,
tileGrid: tileGrid,
projection: projection,
tileUrlFunction: ol.TileUrlFunction.withTileCoordTransform(
tileCoordTransform, tileUrlFunction)
});
};
goog.inherits(ol.source.TiledWMS, ol.source.ImageTileSource);