Refactor ol.source.TileWMS URL logic

This commit is contained in:
Tom Payne
2014-01-08 23:28:06 +01:00
parent 46d8b81661
commit c5a5acbf89

View File

@@ -1,10 +1,13 @@
// FIXME add minZoom support
// FIXME add date line wrap (tile coord transform)
goog.provide('ol.source.TileWMS');
goog.require('goog.array');
goog.require('goog.math');
goog.require('goog.object');
goog.require('goog.string');
goog.require('goog.uri.utils');
goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
goog.require('ol.extent');
@@ -16,22 +19,40 @@ goog.require('ol.source.wms');
/**
* @constructor
* @extends {ol.source.TileImage}
* @param {olx.source.TileWMSOptions} options Tile WMS options.
* @param {olx.source.TileWMSOptions=} opt_options Tile WMS options.
* @todo stability experimental
*/
ol.source.TileWMS = function(options) {
ol.source.TileWMS = function(opt_options) {
var tileGrid;
if (goog.isDef(options.tileGrid)) {
tileGrid = options.tileGrid;
}
var options = goog.isDef(opt_options) ? opt_options : {};
var params = goog.isDef(options.params) ? options.params : {};
var transparent = goog.object.get(params, 'TRANSPARENT', true);
goog.base(this, {
attributions: options.attributions,
crossOrigin: options.crossOrigin,
extent: options.extent,
logo: options.logo,
opaque: !transparent,
projection: options.projection,
tileGrid: options.tileGrid,
tileLoadFunction: options.tileLoadFunction,
tileUrlFunction: goog.bind(this.tileUrlFunction_, this)
});
var tileUrlFunction = ol.TileUrlFunction.nullTileUrlFunction;
var urls = options.urls;
if (!goog.isDef(urls) && goog.isDef(options.url)) {
urls = ol.TileUrlFunction.expandUrl(options.url);
}
/**
* @private
* @type {Array.<string>|undefined}
*/
this.urls_ = urls;
/**
* @private
* @type {number}
@@ -42,7 +63,13 @@ ol.source.TileWMS = function(options) {
* @private
* @type {Object}
*/
this.params_ = options.params;
this.params_ = params;
/**
* @private
* @type {boolean}
*/
this.v13_ = true;
/**
* @private
@@ -51,62 +78,13 @@ ol.source.TileWMS = function(options) {
this.coordKeyPrefix_ = '';
this.resetCoordKeyPrefix_();
if (goog.isDef(urls)) {
var tileUrlFunctions = goog.array.map(
urls, function(url) {
return ol.TileUrlFunction.createFromParamsFunction(
url, this.params_, this.gutter_, ol.source.wms.getUrl);
}, this);
tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(
tileUrlFunctions);
}
/**
* @private
* @type {ol.Extent}
*/
this.tmpExtent_ = ol.extent.createEmpty();
var transparent = goog.isDef(options.params['TRANSPARENT']) ?
options.params['TRANSPARENT'] : true;
var extent = options.extent;
var tileCoordTransform = function(tileCoord, projection) {
var tileGrid = this.getTileGrid();
if (goog.isNull(tileGrid)) {
tileGrid = ol.tilegrid.getForProjection(projection);
}
if (tileGrid.getResolutions().length <= tileCoord.z) {
return null;
}
var x = tileCoord.x;
var tileExtent = tileGrid.getTileCoordExtent(tileCoord);
var projectionExtent = projection.getExtent();
extent = goog.isDef(extent) ? extent : projectionExtent;
if (!goog.isNull(extent) && projection.isGlobal() &&
extent[0] === projectionExtent[0] &&
extent[2] === projectionExtent[2]) {
var numCols = Math.ceil(
(extent[2] - extent[0]) /
(tileExtent[2] - tileExtent[0]));
x = goog.math.modulo(x, numCols);
tileExtent = tileGrid.getTileCoordExtent(
new ol.TileCoord(tileCoord.z, x, tileCoord.y));
}
if (!goog.isNull(extent) && (!ol.extent.intersects(tileExtent, extent) ||
ol.extent.touches(tileExtent, extent))) {
return null;
}
return new ol.TileCoord(tileCoord.z, x, tileCoord.y);
};
goog.base(this, {
attributions: options.attributions,
crossOrigin: options.crossOrigin,
extent: extent,
logo: options.logo,
tileGrid: options.tileGrid,
opaque: !transparent,
projection: options.projection,
tileLoadFunction: options.tileLoadFunction,
tileUrlFunction: ol.TileUrlFunction.withTileCoordTransform(
tileCoordTransform, tileUrlFunction)
});
this.updateV13_();
};
goog.inherits(ol.source.TileWMS, ol.source.TileImage);
@@ -152,6 +130,83 @@ ol.source.TileWMS.prototype.resetCoordKeyPrefix_ = function() {
};
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.proj.Projection} projection Projection.
* @private
* @return {string|undefined} Tile URL.
*/
ol.source.TileWMS.prototype.tileUrlFunction_ = function(tileCoord, projection) {
var urls = this.urls_;
if (!goog.isDef(urls) || goog.array.isEmpty(urls)) {
return undefined;
}
var tileGrid = this.getTileGrid();
if (goog.isNull(tileGrid)) {
tileGrid = ol.tilegrid.getForProjection(projection);
}
if (tileGrid.getResolutions().length <= tileCoord.z) {
return undefined;
}
var tileExtent = tileGrid.getTileCoordExtent(tileCoord);
var params = {
'SERVICE': 'WMS',
'VERSION': ol.source.wms.DEFAULT_VERSION,
'REQUEST': 'GetMap',
'FORMAT': 'image/png',
'TRANSPARENT': true
};
goog.object.extend(params, this.params_);
var tileResolution = tileGrid.getResolution(tileCoord.z);
var tileSize = tileGrid.getTileSize(tileCoord.z);
var gutter = this.gutter_;
if (gutter === 0) {
goog.object.set(params, 'WIDTH', tileSize[0]);
goog.object.set(params, 'HEIGHT', tileSize[1]);
} else {
goog.object.set(params, 'WIDTH', tileSize[0] + 2 * gutter);
goog.object.set(params, 'HEIGHT', tileSize[1] + 2 * gutter);
tileExtent =
ol.extent.buffer(tileExtent, tileResolution * gutter, this.tmpExtent_);
}
params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
if (!('STYLES' in this.params_)) {
goog.object.set(params, 'STYLES', new String(''));
}
var axisOrientation = projection.getAxisOrientation();
var bbox;
if (this.v13_ && axisOrientation.substr(0, 2) == 'ne') {
bbox = this.tmpExtent_;
bbox[0] = tileExtent[1];
bbox[1] = tileExtent[0];
bbox[2] = tileExtent[3];
bbox[3] = tileExtent[2];
} else {
bbox = tileExtent;
}
goog.object.set(params, 'BBOX', bbox.join(','));
var url;
if (urls.length == 1) {
url = urls[0];
} else {
var index = goog.math.modulo(tileCoord.hash(), this.urls_.length);
url = urls[index];
}
return goog.uri.utils.appendParamsFromMap(url, params);
};
/**
* Update the user-provided params.
* @param {Object} params Params.
@@ -160,5 +215,16 @@ ol.source.TileWMS.prototype.resetCoordKeyPrefix_ = function() {
ol.source.TileWMS.prototype.updateParams = function(params) {
goog.object.extend(this.params_, params);
this.resetCoordKeyPrefix_();
this.updateV13_();
this.dispatchChangeEvent();
};
/**
* @private
*/
ol.source.TileWMS.prototype.updateV13_ = function() {
var version =
goog.object.get(this.params_, 'VERSION', ol.source.wms.DEFAULT_VERSION);
this.v13_ = goog.string.compareVersions(version, '1.3') >= 0;
};