diff --git a/examples/xyz-seturl.html b/examples/xyz-seturl.html
new file mode 100644
index 0000000000..2adb6c1310
--- /dev/null
+++ b/examples/xyz-seturl.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+ SetURL example
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
XYZ set URL example
+
Example of a setting the URL on an XYZ source
+
+
xyz, seturl
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/xyz-seturl.js b/examples/xyz-seturl.js
new file mode 100644
index 0000000000..f412819514
--- /dev/null
+++ b/examples/xyz-seturl.js
@@ -0,0 +1,34 @@
+goog.require('ol.Map');
+goog.require('ol.RendererHints');
+goog.require('ol.View2D');
+goog.require('ol.layer.Tile');
+goog.require('ol.source.XYZ');
+
+
+var source = new ol.source.XYZ({
+ url: 'http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
+});
+var map = new ol.Map({
+ layers: [
+ new ol.layer.Tile({
+ source: source
+ })
+ ],
+ renderers: ol.RendererHints.createFromQueryData(),
+ target: 'map',
+ view: new ol.View2D({
+ center: [0, 0],
+ zoom: 4
+ })
+});
+
+$('#set-stamen').click(function() {
+ source.setUrl('http://{a-d}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg');
+});
+$('#set-opencyclemap').click(function() {
+ source.setUrl('http://{a-c}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png');
+});
+$('#set-esri').click(function() {
+ source.setUrl('http://server.arcgisonline.com/ArcGIS/rest/services/' +
+ 'World_Topo_Map/MapServer/tile/{z}/{y}/{x}');
+});
diff --git a/src/ol/source/imagetilesource.js b/src/ol/source/imagetilesource.js
index 453dd29126..8769cf71cf 100644
--- a/src/ol/source/imagetilesource.js
+++ b/src/ol/source/imagetilesource.js
@@ -108,6 +108,19 @@ ol.source.TileImage.prototype.getTile = function(z, x, y, projection) {
};
+/**
+ * @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function.
+ */
+ol.source.TileImage.prototype.setTileUrlFunction = function(tileUrlFunction) {
+ // FIXME It should be possible to be more intelligent and avoid clearing the
+ // FIXME cache. The tile URL function would need to be incorporated into the
+ // FIXME cache key somehow.
+ this.tileCache_.clear();
+ this.tileUrlFunction = tileUrlFunction;
+ this.dispatchChangeEvent();
+};
+
+
/**
* @inheritDoc
*/
diff --git a/src/ol/source/xyzsource.js b/src/ol/source/xyzsource.js
index 0f00bc385a..51e5f43080 100644
--- a/src/ol/source/xyzsource.js
+++ b/src/ol/source/xyzsource.js
@@ -18,33 +18,12 @@ ol.source.XYZ = function(options) {
var projection = options.projection || ol.proj.get('EPSG:3857');
- /**
- * @type {ol.TileUrlFunctionType}
- */
- var tileUrlFunction = ol.TileUrlFunction.nullTileUrlFunction;
- // FIXME use goog.nullFunction ?
- if (goog.isDef(options.tileUrlFunction)) {
- tileUrlFunction = options.tileUrlFunction;
- } else if (goog.isDef(options.urls)) {
- tileUrlFunction = ol.TileUrlFunction.createFromTemplates(options.urls);
- } else if (goog.isDef(options.url)) {
- tileUrlFunction = ol.TileUrlFunction.createFromTemplates(
- ol.TileUrlFunction.expandUrl(options.url));
- }
-
var maxZoom = goog.isDef(options.maxZoom) ? options.maxZoom : 18;
var tileGrid = new ol.tilegrid.XYZ({
maxZoom: maxZoom
});
- var tileCoordTransform = tileGrid.createTileCoordTransform({
- extent: options.extent
- });
-
- tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
- tileCoordTransform, tileUrlFunction);
-
goog.base(this, {
attributions: options.attributions,
crossOrigin: options.crossOrigin,
@@ -52,8 +31,51 @@ ol.source.XYZ = function(options) {
logo: options.logo,
projection: projection,
tileGrid: tileGrid,
- tileUrlFunction: tileUrlFunction
+ tileUrlFunction: ol.TileUrlFunction.nullTileUrlFunction
});
+ /**
+ * @private
+ * @type {ol.TileCoordTransformType}
+ */
+ this.tileCoordTransform_ = tileGrid.createTileCoordTransform({
+ extent: options.extent
+ });
+
+ if (goog.isDef(options.tileUrlFunction)) {
+ this.setTileUrlFunction(options.tileUrlFunction);
+ } else if (goog.isDef(options.urls)) {
+ this.setUrls(options.urls);
+ } else if (goog.isDef(options.url)) {
+ this.setUrl(options.url);
+ }
+
};
goog.inherits(ol.source.XYZ, ol.source.TileImage);
+
+
+/**
+ * @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function.
+ */
+ol.source.XYZ.prototype.setTileUrlFunction = function(tileUrlFunction) {
+ goog.base(this, 'setTileUrlFunction',
+ ol.TileUrlFunction.withTileCoordTransform(
+ this.tileCoordTransform_, tileUrlFunction));
+};
+
+
+/**
+ * @param {string} url URL.
+ */
+ol.source.XYZ.prototype.setUrl = function(url) {
+ this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates(
+ ol.TileUrlFunction.expandUrl(url)));
+};
+
+
+/**
+ * @param {Array.} urls URLs.
+ */
+ol.source.XYZ.prototype.setUrls = function(urls) {
+ this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates(urls));
+};
diff --git a/src/ol/tileurlfunction.js b/src/ol/tileurlfunction.js
index d2d348a7e0..d69080dc0a 100644
--- a/src/ol/tileurlfunction.js
+++ b/src/ol/tileurlfunction.js
@@ -14,6 +14,12 @@ goog.require('ol.extent');
ol.TileUrlFunctionType;
+/**
+ * @typedef {function(ol.TileCoord, ol.Projection, ol.TileCoord=): ol.TileCoord}
+ */
+ol.TileCoordTransformType;
+
+
/**
* @param {string} template Template.
* @return {ol.TileUrlFunctionType} Tile URL function.
@@ -121,8 +127,7 @@ ol.TileUrlFunction.nullTileUrlFunction = function(tileCoord, projection) {
/**
- * @param {function(ol.TileCoord, ol.Projection, ol.TileCoord=): ol.TileCoord}
- * transformFn Transform function.
+ * @param {ol.TileCoordTransformType} transformFn Transform function.
* @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function.
* @return {ol.TileUrlFunctionType} Tile URL function.
*/