More context for url functions

With this change, url functions are called in the scope of the
source they are configured for. This allows us to simplify the
url function generation for WMS, using a more generic
createFromParamsFunction factory, and the source's new params
member.

Note that there is also a new url member for WMS sources. This
is the WMS base url (the first one in case there is an array of
urls for faster tile access). This can be used for accessing
other WMS services (especially GetFeatureInfo).
This commit is contained in:
ahocevar
2013-03-20 10:45:54 +01:00
parent 4fe67f09c0
commit 46ca98e484
10 changed files with 128 additions and 51 deletions

View File

@@ -3,25 +3,26 @@ goog.provide('ol.ImageUrlFunctionType');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.source.wms');
/**
* @typedef {function(ol.Extent, ol.Size, ol.Projection): (string|undefined)}
* @typedef {function(this:ol.source.Source, ol.Extent, ol.Size, ol.Projection):
* (string|undefined)}
*/
ol.ImageUrlFunctionType;
/**
* @param {string} baseUrl Base URL (may have query data).
* @param {Object.<string, string|number>} params WMS parameters.
* @param {function(string, Object.<string,*>, ol.Extent, ol.Size,
* ol.Projection)} paramsFunction params function.
* @return {ol.ImageUrlFunctionType} Image URL function.
*/
ol.ImageUrlFunction.createWMSParams =
function(baseUrl, params) {
ol.ImageUrlFunction.createFromParamsFunction =
function(baseUrl, paramsFunction) {
return function(extent, size, projection) {
return ol.source.wms.getUrl(
baseUrl, params, extent, size, projection);
return paramsFunction(
baseUrl, this.params, extent, size, projection);
};
};

View File

@@ -82,7 +82,7 @@ goog.inherits(ol.source.ImageSource, ol.source.Source);
ol.source.ImageSource.prototype.createImage =
function(extent, resolution, size, projection) {
var image = null;
var imageUrl = this.imageUrlFunction(extent, size, projection);
var imageUrl = this.imageUrlFunction.call(this, extent, size, projection);
if (goog.isDef(imageUrl)) {
image = new ol.Image(
extent, resolution, imageUrl, this.crossOrigin_,

View File

@@ -94,7 +94,8 @@ ol.source.ImageTileSource.prototype.getTile =
} else {
goog.asserts.assert(tileGrid);
goog.asserts.assert(projection);
var tileUrl = this.tileUrlFunction(tileCoord, tileGrid, projection);
var tileUrl = this.tileUrlFunction.call(this,
tileCoord, tileGrid, projection);
var tile = new ol.ImageTile(
tileCoord,
goog.isDef(tileUrl) ? ol.TileState.IDLE : ol.TileState.EMPTY,

View File

@@ -5,17 +5,20 @@ goog.require('ol.Image');
goog.require('ol.ImageUrlFunction');
goog.require('ol.Size');
goog.require('ol.source.ImageSource');
goog.require('ol.source.wms');
/**
* @constructor
* @implements {ol.source.IWMS}
* @extends {ol.source.ImageSource}
* @param {ol.source.SingleImageWMSOptions} options Options.
*/
ol.source.SingleImageWMS = function(options) {
var imageUrlFunction = goog.isDef(options.url) ?
ol.ImageUrlFunction.createWMSParams(options.url, options.params) :
ol.ImageUrlFunction.createFromParamsFunction(
options.url, ol.source.wms.getUrl) :
ol.ImageUrlFunction.nullImageUrlFunction;
goog.base(this, {
@@ -27,6 +30,16 @@ ol.source.SingleImageWMS = function(options) {
imageUrlFunction: imageUrlFunction
});
/**
* @inheritDoc
*/
this.url = options.url;
/**
* @inheritDoc
*/
this.params = options.params;
/**
* @private
* @type {ol.Image}

View File

@@ -8,11 +8,13 @@ goog.require('ol.Extent');
goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
goog.require('ol.source.ImageTileSource');
goog.require('ol.source.wms');
/**
* @constructor
* @implements {ol.source.IWMS}
* @extends {ol.source.ImageTileSource}
* @param {ol.source.TiledWMSOptions} tiledWMSOptions options.
*/
@@ -30,12 +32,13 @@ ol.source.TiledWMS = function(tiledWMSOptions) {
if (goog.isDef(urls)) {
var tileUrlFunctions = goog.array.map(
urls, function(url) {
return ol.TileUrlFunction.createWMSParams(
url, tiledWMSOptions.params);
return ol.TileUrlFunction.createFromParamsFunction(
url, ol.source.wms.getUrl);
});
tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(
tileUrlFunctions);
}
var transparent = goog.isDef(tiledWMSOptions.params['TRANSPARENT']) ?
tiledWMSOptions.params['TRANSPARENT'] : true;
var extent = tiledWMSOptions.extent;
@@ -65,6 +68,16 @@ ol.source.TiledWMS = function(tiledWMSOptions) {
return new ol.TileCoord(tileCoord.z, x, tileCoord.y);
};
/**
* @inheritDoc
*/
this.url = goog.isDef(urls) ? urls[0] : undefined;
/**
* @inheritDoc
*/
this.params = tiledWMSOptions.params;
goog.base(this, {
attributions: tiledWMSOptions.attributions,
crossOrigin: tiledWMSOptions.crossOrigin,

View File

@@ -1,6 +1,29 @@
goog.provide('ol.source.IWMS');
goog.provide('ol.source.wms');
/**
* Interface for WMS
* @interface
*/
ol.source.IWMS = function() {};
/**
* @type {string|undefined} The url for this source.
*/
ol.source.IWMS.prototype.url;
/**
* @type {Object.<string,*>} Parameters for WMS requests. 'LAYERS' is mandatory.
* 'STYLES' defaults to ''. 'VERSION' defaults to '1.3.0'. 'CRS'/'SRS',
* 'BBOX' and 'SIZE' are added dynamically.
*/
ol.source.IWMS.prototype.params;
/**
* @param {string} baseUrl WMS base url.
* @param {Object.<string, string|number>} params Request parameters.

View File

@@ -1,5 +1,6 @@
// FIXME cope with tile grids whose minium zoom is not zero
goog.provide('ol.tilegrid');
goog.provide('ol.tilegrid.TileGrid');
goog.require('goog.array');

View File

@@ -4,13 +4,12 @@ goog.provide('ol.TileUrlFunctionType');
goog.require('goog.array');
goog.require('goog.math');
goog.require('ol.TileCoord');
goog.require('ol.source.wms');
goog.require('ol.tilegrid.TileGrid');
/**
* @typedef {function(ol.TileCoord, ol.tilegrid.TileGrid, ol.Projection):
* (string|undefined)}
* @typedef {function(this:ol.source.Source, ol.TileCoord, ol.tilegrid.TileGrid,
* ol.Projection): (string|undefined)}
*/
ol.TileUrlFunctionType;
@@ -63,19 +62,20 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) {
/**
* @param {string} baseUrl Base URL (may have query data).
* @param {Object.<string, string|number>} params WMS parameters.
* @param {function(string, Object.<string,*>, ol.Extent, ol.Size,
* ol.Projection)} paramsFunction params function.
* @return {ol.TileUrlFunctionType} Tile URL function.
*/
ol.TileUrlFunction.createWMSParams =
function(baseUrl, params) {
ol.TileUrlFunction.createFromParamsFunction =
function(baseUrl, paramsFunction) {
return function(tileCoord, tileGrid, projection) {
if (goog.isNull(tileCoord)) {
return undefined;
} else {
var size = tileGrid.getTileSize(tileCoord.z);
var extent = tileGrid.getTileCoordExtent(tileCoord);
return ol.source.wms.getUrl(
baseUrl, params, extent, size, projection);
return paramsFunction(
baseUrl, this.params, extent, size, projection);
}
};
};
@@ -102,7 +102,7 @@ ol.TileUrlFunction.withTileCoordTransform =
if (goog.isNull(tileCoord)) {
return undefined;
} else {
return tileUrlFunction(
return tileUrlFunction.call(this,
transformFn(tileCoord, tileGrid, projection), tileGrid, projection);
}
};

View File

@@ -0,0 +1,40 @@
goog.provide('ol.source.test.wms');
describe('ol.source.wms', function() {
describe('ol.source.wms.getUrl', function() {
var that = {params: {}};
it('creates expected URL', function() {
var epsg3857 = ol.projection.get('EPSG:3857');
var tileGrid = ol.tilegrid.getForProjection(epsg3857);
var tileUrlFunction = ol.TileUrlFunction.createFromParamsFunction(
'http://wms?foo=bar', ol.source.wms.getUrl);
var tileCoord = new ol.TileCoord(1, 0, 0);
var tileUrl = tileUrlFunction.call(that, tileCoord, tileGrid, epsg3857);
var expected = 'http://wms?foo=bar&SERVICE=WMS&VERSION=1.3.0&REQUEST=' +
'GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&WIDTH=256&HEIGHT=256&' +
'STYLES=&CRS=EPSG%3A3857&BBOX=' +
'-20037508.342789244%2C-20037508.342789244%2C0%2C0';
expect(tileUrl).to.eql(expected);
});
it('creates expected URL respecting axis orientation', function() {
var epsg4326 = ol.projection.get('EPSG:4326');
var tileGrid = ol.tilegrid.getForProjection(epsg4326);
var tileUrlFunction = ol.TileUrlFunction.createFromParamsFunction(
'http://wms?foo=bar', ol.source.wms.getUrl);
var tileCoord = new ol.TileCoord(1, 0, 0);
var tileUrl = tileUrlFunction.call(that, tileCoord, tileGrid, epsg4326);
var expected = 'http://wms?foo=bar&SERVICE=WMS&VERSION=1.3.0&REQUEST=' +
'GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&WIDTH=256&HEIGHT=256&' +
'STYLES=&CRS=EPSG%3A4326&BBOX=-90%2C-180%2C90%2C0';
expect(tileUrl).to.eql(expected);
});
});
});
goog.require('ol.TileCoord');
goog.require('ol.projection');
goog.require('ol.source.wms');
goog.require('ol.tilegrid');

View File

@@ -78,38 +78,23 @@ describe('ol.TileUrlFunction', function() {
});
});
describe('createWMSParams', function() {
var tileGrid;
beforeEach(function() {
tileGrid = new ol.tilegrid.XYZ({
maxZoom: 10
});
});
it('creates expected URL', function() {
var epsg3857 = ol.projection.get('EPSG:3857');
var tileUrlFunction = ol.TileUrlFunction.createWMSParams(
'http://wms?foo=bar', {});
var tileCoord = new ol.TileCoord(1, 0, 0);
var tileUrl = tileUrlFunction(tileCoord, tileGrid, epsg3857);
var expected = 'http://wms?foo=bar&SERVICE=WMS&VERSION=1.3.0&REQUEST=' +
'GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&WIDTH=256&HEIGHT=256&' +
'STYLES=&CRS=EPSG%3A3857&BBOX=-20037508.342789244%2C2' +
'0037508.342789244%2C0%2C40075016.68557849';
expect(tileUrl).to.eql(expected);
});
it('creates expected URL respecting axis orientation', function() {
var epsg4326 = ol.projection.get('EPSG:4326');
var tileUrlFunction = ol.TileUrlFunction.createWMSParams(
'http://wms?foo=bar', {});
var tileCoord = new ol.TileCoord(1, 0, 0);
var tileUrl = tileUrlFunction(tileCoord, tileGrid, epsg4326);
var expected = 'http://wms?foo=bar&SERVICE=WMS&VERSION=1.3.0&REQUEST=' +
'GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&WIDTH=256&HEIGHT=256&' +
'STYLES=&CRS=EPSG%3A4326&BBOX=20037508.342789244%2C' +
'-20037508.342789244%2C40075016.68557849%2C0';
expect(tileUrl).to.eql(expected);
describe('createFromParamsFunction', function() {
var paramsFunction = function(url, params) { return arguments; };
var projection = ol.projection.get('EPSG:3857');
var tileUrlFunction = ol.TileUrlFunction.createFromParamsFunction(
'url', paramsFunction);
it('calls the passed function with the correct arguments', function() {
var that = {params: {foo: 'bar'}};
var args = tileUrlFunction.call(that, new ol.TileCoord(0, 0, 0),
ol.tilegrid.getForProjection(projection), projection);
expect(args[0]).to.eql('url');
expect(args[1]).to.be(that.params);
expect(args[2]).to.eql(projection.getExtent());
expect(args[3]).to.eql(new ol.Size(256, 256));
expect(args[4]).to.eql(projection);
});
});
});
goog.require('ol.TileCoord');