From 81d5849207df46b1674a5142b40bb786a3ac7611 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 18:27:19 -0600 Subject: [PATCH 01/10] Add a settable key for all tile sources The source's key is used as the key for all tiles in the source. For URL tile sources, the URL is the key. --- src/ol/source/tilesource.js | 21 ++++++++++++++++++++- src/ol/source/urltilesource.js | 18 ++++++++++-------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index bc0b789691..14542a41df 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -67,6 +67,12 @@ ol.source.Tile = function(options) { */ this.tmpSize = [0, 0]; + /** + * @private + * @type {string} + */ + this.key_ = ''; + }; goog.inherits(ol.source.Tile, ol.source.Source); @@ -144,7 +150,20 @@ ol.source.Tile.prototype.getGutter = function(projection) { * @protected */ ol.source.Tile.prototype.getKeyParams = function() { - return ''; + return this.key_; +}; + + +/** + * Set the value to be used as the key for all tiles in the source. + * @param {string} key The key for tiles. + * @protected + */ +ol.source.Tile.prototype.setKey = function(key) { + if (this.key_ !== key) { + this.key_ = key; + this.changed(); + } }; diff --git a/src/ol/source/urltilesource.js b/src/ol/source/urltilesource.js index 73a10b6a24..fd359b1c29 100644 --- a/src/ol/source/urltilesource.js +++ b/src/ol/source/urltilesource.js @@ -143,15 +143,16 @@ ol.source.UrlTile.prototype.setTileLoadFunction = function(tileLoadFunction) { /** * Set the tile URL function of the source. * @param {ol.TileUrlFunctionType} tileUrlFunction Tile URL function. + * @param {string=} opt_key Optional new tile key for the source. * @api */ -ol.source.UrlTile.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(); +ol.source.UrlTile.prototype.setTileUrlFunction = function(tileUrlFunction, opt_key) { this.tileUrlFunction = tileUrlFunction; - this.changed(); + if (typeof opt_key !== 'undefined') { + this.setKey(opt_key); + } else { + this.changed(); + } }; @@ -164,7 +165,7 @@ ol.source.UrlTile.prototype.setUrl = function(url) { var urls = this.urls = ol.TileUrlFunction.expandUrl(url); this.setTileUrlFunction(this.fixedTileUrlFunction ? this.fixedTileUrlFunction.bind(this) : - ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid)); + ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid), url); }; @@ -175,9 +176,10 @@ ol.source.UrlTile.prototype.setUrl = function(url) { */ ol.source.UrlTile.prototype.setUrls = function(urls) { this.urls = urls; + var key = urls.join('\n'); this.setTileUrlFunction(this.fixedTileUrlFunction ? this.fixedTileUrlFunction.bind(this) : - ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid)); + ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid), key); }; From 841c8a5747e2ce1fb001eccf46a58f4c1d4446f5 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 18:34:50 -0600 Subject: [PATCH 02/10] Rename source.getKeyParams() to source.getKey() --- src/ol/source/tileimagesource.js | 2 +- src/ol/source/tilesource.js | 7 +++---- src/ol/source/tilewmssource.js | 2 +- src/ol/source/wmtssource.js | 2 +- test/spec/ol/source/tileimagesource.test.js | 8 ++++---- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ol/source/tileimagesource.js b/src/ol/source/tileimagesource.js index 5f623d67f4..49ab00d1cd 100644 --- a/src/ol/source/tileimagesource.js +++ b/src/ol/source/tileimagesource.js @@ -279,7 +279,7 @@ ol.source.TileImage.prototype.getTile = function(z, x, y, pixelRatio, projection ol.source.TileImage.prototype.getTileInternal = function(z, x, y, pixelRatio, projection) { var /** @type {ol.Tile} */ tile = null; var tileCoordKey = this.getKeyZXY(z, x, y); - var paramsKey = this.getKeyParams(); + var paramsKey = this.getKey(); if (!this.tileCache.containsKey(tileCoordKey)) { goog.asserts.assert(projection, 'argument projection is truthy'); tile = this.createTile_(z, x, y, pixelRatio, projection, paramsKey); diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index 14542a41df..f397a3f4f5 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -144,12 +144,11 @@ ol.source.Tile.prototype.getGutter = function(projection) { /** - * Return the "parameters" key, a string composed of the source's - * parameters/dimensions. - * @return {string} The parameters key. + * Return the key to be used for all tiles in the source. + * @return {string} The key for all tiles. * @protected */ -ol.source.Tile.prototype.getKeyParams = function() { +ol.source.Tile.prototype.getKey = function() { return this.key_; }; diff --git a/src/ol/source/tilewmssource.js b/src/ol/source/tilewmssource.js index c74505442d..050c66e47c 100644 --- a/src/ol/source/tilewmssource.js +++ b/src/ol/source/tilewmssource.js @@ -185,7 +185,7 @@ ol.source.TileWMS.prototype.getGutterInternal = function() { /** * @inheritDoc */ -ol.source.TileWMS.prototype.getKeyParams = function() { +ol.source.TileWMS.prototype.getKey = function() { return this.paramsKey_; }; diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js index 017e6f1077..644d8b8784 100644 --- a/src/ol/source/wmtssource.js +++ b/src/ol/source/wmtssource.js @@ -216,7 +216,7 @@ ol.source.WMTS.prototype.getFormat = function() { /** * @inheritDoc */ -ol.source.WMTS.prototype.getKeyParams = function() { +ol.source.WMTS.prototype.getKey = function() { return this.dimensionsKey_; }; diff --git a/test/spec/ol/source/tileimagesource.test.js b/test/spec/ol/source/tileimagesource.test.js index 7d5cd3a12a..e79bbd7152 100644 --- a/test/spec/ol/source/tileimagesource.test.js +++ b/test/spec/ol/source/tileimagesource.test.js @@ -27,7 +27,7 @@ describe('ol.source.TileImage', function() { beforeEach(function() { source = createSource(); - expect(source.getKeyParams()).to.be(''); + expect(source.getKey()).to.be(''); source.getTileInternal(0, 0, -1, 1, ol.proj.get('EPSG:3857')); expect(source.tileCache.getCount()).to.be(1); tile = source.tileCache.get(source.getKeyZXY(0, 0, -1)); @@ -43,7 +43,7 @@ describe('ol.source.TileImage', function() { describe('tile is not loaded', function() { it('returns a tile with no interim tile', function() { - source.getKeyParams = function() { + source.getKey = function() { return 'key0'; }; var returnedTile = source.getTileInternal( @@ -56,7 +56,7 @@ describe('ol.source.TileImage', function() { describe('tile is loaded', function() { it('returns a tile with interim tile', function() { - source.getKeyParams = function() { + source.getKey = function() { return 'key0'; }; tile.state = ol.TileState.LOADED; @@ -71,7 +71,7 @@ describe('ol.source.TileImage', function() { describe('tile is not loaded but interim tile is', function() { it('returns a tile with interim tile', function() { var dynamicParamsKey, returnedTile; - source.getKeyParams = function() { + source.getKey = function() { return dynamicParamsKey; }; dynamicParamsKey = 'key0'; From 025c063251e267e6279187c20876d21356775775 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 18:47:38 -0600 Subject: [PATCH 03/10] Less special handling for WMS tiles --- src/ol/source/tilewmssource.js | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/ol/source/tilewmssource.js b/src/ol/source/tilewmssource.js index 050c66e47c..3d43f097c9 100644 --- a/src/ol/source/tilewmssource.js +++ b/src/ol/source/tilewmssource.js @@ -63,13 +63,6 @@ ol.source.TileWMS = function(opt_options) { */ this.params_ = params; - /** - * @private - * @type {string} - */ - this.paramsKey_ = ''; - this.resetParamsKey_(); - /** * @private * @type {boolean} @@ -103,6 +96,7 @@ ol.source.TileWMS = function(opt_options) { this.tmpExtent_ = ol.extent.createEmpty(); this.updateV13_(); + this.setKey(this.getKeyForParams_()); }; goog.inherits(ol.source.TileWMS, ol.source.TileImage); @@ -182,14 +176,6 @@ ol.source.TileWMS.prototype.getGutterInternal = function() { }; -/** - * @inheritDoc - */ -ol.source.TileWMS.prototype.getKey = function() { - return this.paramsKey_; -}; - - /** * @inheritDoc */ @@ -311,14 +297,15 @@ ol.source.TileWMS.prototype.resetCoordKeyPrefix_ = function() { /** * @private + * @return {string} The key for the current params. */ -ol.source.TileWMS.prototype.resetParamsKey_ = function() { +ol.source.TileWMS.prototype.getKeyForParams_ = function() { var i = 0; var res = []; for (var key in this.params_) { res[i++] = key + '-' + this.params_[key]; } - this.paramsKey_ = res.join('/'); + return res.join('/'); }; @@ -378,9 +365,8 @@ ol.source.TileWMS.prototype.fixedTileUrlFunction = function(tileCoord, pixelRati ol.source.TileWMS.prototype.updateParams = function(params) { ol.object.assign(this.params_, params); this.resetCoordKeyPrefix_(); - this.resetParamsKey_(); this.updateV13_(); - this.changed(); + this.setKey(this.getKeyForParams_()); }; From 5542f045d5f34458e9df7d78d0c40ed73e215dd2 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 18:52:42 -0600 Subject: [PATCH 04/10] Less special handling for WMTS tiles --- src/ol/source/wmtssource.js | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js index 644d8b8784..d247d4615f 100644 --- a/src/ol/source/wmtssource.js +++ b/src/ol/source/wmtssource.js @@ -54,13 +54,6 @@ ol.source.WMTS = function(options) { */ this.dimensions_ = options.dimensions !== undefined ? options.dimensions : {}; - /** - * @private - * @type {string} - */ - this.dimensionsKey_ = ''; - this.resetDimensionsKey_(); - /** * @private * @type {string} @@ -187,6 +180,8 @@ ol.source.WMTS = function(options) { wrapX: options.wrapX !== undefined ? options.wrapX : false }); + this.setKey(this.getKeyForDimensions_()); + }; goog.inherits(ol.source.WMTS, ol.source.TileImage); @@ -213,14 +208,6 @@ ol.source.WMTS.prototype.getFormat = function() { }; -/** - * @inheritDoc - */ -ol.source.WMTS.prototype.getKey = function() { - return this.dimensionsKey_; -}; - - /** * Return the layer of the WMTS source. * @return {string} Layer. @@ -273,14 +260,15 @@ ol.source.WMTS.prototype.getVersion = function() { /** * @private + * @return {string} The key for the current dimensions. */ -ol.source.WMTS.prototype.resetDimensionsKey_ = function() { +ol.source.WMTS.prototype.getKeyForDimensions_ = function() { var i = 0; var res = []; for (var key in this.dimensions_) { res[i++] = key + '-' + this.dimensions_[key]; } - this.dimensionsKey_ = res.join('/'); + return res.join('/'); }; @@ -291,8 +279,7 @@ ol.source.WMTS.prototype.resetDimensionsKey_ = function() { */ ol.source.WMTS.prototype.updateDimensions = function(dimensions) { ol.object.assign(this.dimensions_, dimensions); - this.resetDimensionsKey_(); - this.changed(); + this.setKey(this.getKeyForDimensions_()); }; From 9870e8c04c253d687c0d0d436d156d451f3465b4 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 21:13:55 -0600 Subject: [PATCH 05/10] Allow XYZ source construction without options --- src/ol/source/xyzsource.js | 1 + test/spec/ol/source/xyzsource.test.js | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/ol/source/xyzsource.js b/src/ol/source/xyzsource.js index 166df55699..fea537eebe 100644 --- a/src/ol/source/xyzsource.js +++ b/src/ol/source/xyzsource.js @@ -26,6 +26,7 @@ goog.require('ol.source.TileImage'); * @api stable */ ol.source.XYZ = function(options) { + options = options || {}; var projection = options.projection !== undefined ? options.projection : 'EPSG:3857'; diff --git a/test/spec/ol/source/xyzsource.test.js b/test/spec/ol/source/xyzsource.test.js index f260635dab..232ff43131 100644 --- a/test/spec/ol/source/xyzsource.test.js +++ b/test/spec/ol/source/xyzsource.test.js @@ -5,6 +5,14 @@ describe('ol.source.XYZ', function() { describe('constructor', function() { + it('can be constructed without options', function() { + var source = new ol.source.XYZ(); + expect(source).to.be.an(ol.source.XYZ); + expect(source).to.be.an(ol.source.TileImage); + expect(source).to.be.an(ol.source.UrlTile); + expect(source).to.be.an(ol.source.Tile); + }); + it('can be constructed with a custom tile grid', function() { var tileGrid = ol.tilegrid.createXYZ(); var tileSource = new ol.source.XYZ({ @@ -179,4 +187,7 @@ describe('ol.source.XYZ', function() { }); +goog.require('ol.source.Tile'); +goog.require('ol.source.TileImage'); +goog.require('ol.source.UrlTile'); goog.require('ol.source.XYZ'); From 6f5965f6a59f221b73a99cb5e053e93e1be9a673 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 21:14:25 -0600 Subject: [PATCH 06/10] Demonstrate how source.setUrl() works --- examples/reusable-source.html | 12 +++++++++++ examples/reusable-source.js | 39 +++++++++++++++++++++++++++++++++++ src/ol/source/xyzsource.js | 6 +++--- 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 examples/reusable-source.html create mode 100644 examples/reusable-source.js diff --git a/examples/reusable-source.html b/examples/reusable-source.html new file mode 100644 index 0000000000..e93074b7f6 --- /dev/null +++ b/examples/reusable-source.html @@ -0,0 +1,12 @@ +--- +layout: example.html +title: Reusable Source +shortdesc: Updating a tile source by changing the URL. +docs: > + You can call source.setUrl() to update the URL for a tile source. Note that when you change the URL for a tile source, existing tiles will not be replaced until new tiles are loaded. If you are interested instead in clearing currently rendered tiles, you can call the source.refresh() method. Alternatively, you can use two separate sources if you want to remove rendered tiles and start over loading new tiles. +--- +
+ + + + diff --git a/examples/reusable-source.js b/examples/reusable-source.js new file mode 100644 index 0000000000..b9c4ac3ca3 --- /dev/null +++ b/examples/reusable-source.js @@ -0,0 +1,39 @@ +goog.require('ol.Map'); +goog.require('ol.View'); +goog.require('ol.layer.Tile'); +goog.require('ol.source.XYZ'); + +var urls = [ + 'https://{a-c}.tiles.mapbox.com/v3/mapbox.blue-marble-topo-jan/{z}/{x}/{y}.png', + 'https://{a-c}.tiles.mapbox.com/v3/mapbox.blue-marble-topo-bathy-jan/{z}/{x}/{y}.png', + 'https://{a-c}.tiles.mapbox.com/v3/mapbox.blue-marble-topo-jul/{z}/{x}/{y}.png', + 'https://{a-c}.tiles.mapbox.com/v3/mapbox.blue-marble-topo-bathy-jul/{z}/{x}/{y}.png' +]; + +var source = new ol.source.XYZ(); + +var map = new ol.Map({ + target: 'map', + layers: [ + new ol.layer.Tile({ + source: source + }) + ], + view: new ol.View({ + center: [0, 0], + zoom: 2 + }) +}); + + +function updateUrl(index) { + source.setUrl(urls[index]); +} + +var buttons = document.getElementsByClassName('switcher'); +for (var i = 0, ii = buttons.length; i < ii; ++i) { + var button = buttons[i]; + button.addEventListener('click', updateUrl.bind(null, Number(button.value))); +} + +updateUrl(0); diff --git a/src/ol/source/xyzsource.js b/src/ol/source/xyzsource.js index fea537eebe..1091ada585 100644 --- a/src/ol/source/xyzsource.js +++ b/src/ol/source/xyzsource.js @@ -22,11 +22,11 @@ goog.require('ol.source.TileImage'); * * @constructor * @extends {ol.source.TileImage} - * @param {olx.source.XYZOptions} options XYZ options. + * @param {olx.source.XYZOptions=} opt_options XYZ options. * @api stable */ -ol.source.XYZ = function(options) { - options = options || {}; +ol.source.XYZ = function(opt_options) { + var options = opt_options || {}; var projection = options.projection !== undefined ? options.projection : 'EPSG:3857'; From b2b902e22fac70530bb841a146dc171944ded93a Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Wed, 18 May 2016 21:22:14 -0600 Subject: [PATCH 07/10] Less weird name --- src/ol/source/tileimagesource.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ol/source/tileimagesource.js b/src/ol/source/tileimagesource.js index 49ab00d1cd..c552c52068 100644 --- a/src/ol/source/tileimagesource.js +++ b/src/ol/source/tileimagesource.js @@ -279,19 +279,19 @@ ol.source.TileImage.prototype.getTile = function(z, x, y, pixelRatio, projection ol.source.TileImage.prototype.getTileInternal = function(z, x, y, pixelRatio, projection) { var /** @type {ol.Tile} */ tile = null; var tileCoordKey = this.getKeyZXY(z, x, y); - var paramsKey = this.getKey(); + var key = this.getKey(); if (!this.tileCache.containsKey(tileCoordKey)) { goog.asserts.assert(projection, 'argument projection is truthy'); - tile = this.createTile_(z, x, y, pixelRatio, projection, paramsKey); + tile = this.createTile_(z, x, y, pixelRatio, projection, key); this.tileCache.set(tileCoordKey, tile); } else { tile = /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey)); - if (tile.key != paramsKey) { + if (tile.key != key) { // The source's params changed. If the tile has an interim tile and if we // can use it then we use it. Otherwise we create a new tile. In both // cases we attempt to assign an interim tile to the new tile. var /** @type {ol.Tile} */ interimTile = tile; - if (tile.interimTile && tile.interimTile.key == paramsKey) { + if (tile.interimTile && tile.interimTile.key == key) { goog.asserts.assert(tile.interimTile.getState() == ol.TileState.LOADED); goog.asserts.assert(tile.interimTile.interimTile === null); tile = tile.interimTile; @@ -299,7 +299,7 @@ ol.source.TileImage.prototype.getTileInternal = function(z, x, y, pixelRatio, pr tile.interimTile = interimTile; } } else { - tile = this.createTile_(z, x, y, pixelRatio, projection, paramsKey); + tile = this.createTile_(z, x, y, pixelRatio, projection, key); if (interimTile.getState() == ol.TileState.LOADED) { tile.interimTile = interimTile; } else if (interimTile.interimTile && From feb6fe9dcee10110aa5926027cfb5eb48fa5c18f Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 19 May 2016 09:00:43 -0600 Subject: [PATCH 08/10] Tests for setUrl() and setUrls() --- test/spec/ol/source/urltilesource.test.js | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/spec/ol/source/urltilesource.test.js b/test/spec/ol/source/urltilesource.test.js index edeb89ad8c..d4de378da5 100644 --- a/test/spec/ol/source/urltilesource.test.js +++ b/test/spec/ol/source/urltilesource.test.js @@ -3,6 +3,54 @@ goog.provide('ol.test.source.UrlTile'); describe('ol.source.UrlTile', function() { + describe('#setUrl()', function() { + it('sets the URL for the source', function() { + var source = new ol.source.UrlTile({}); + + var url = 'https://example.com/'; + source.setUrl(url); + + expect(source.getUrls()).to.eql([url]); + }); + + it('updates the key for the source', function() { + var source = new ol.source.UrlTile({}); + + var url = 'https://example.com/'; + source.setUrl(url); + + expect(source.getKey()).to.eql(url); + }); + }); + + describe('#setUrls()', function() { + it('sets the URL for the source', function() { + var source = new ol.source.UrlTile({}); + + var urls = [ + 'https://a.example.com/', + 'https://b.example.com/', + 'https://c.example.com/' + ]; + source.setUrls(urls); + + expect(source.getUrls()).to.eql(urls); + }); + + it('updates the key for the source', function() { + var source = new ol.source.UrlTile({}); + + var urls = [ + 'https://a.example.com/', + 'https://b.example.com/', + 'https://c.example.com/' + ]; + source.setUrls(urls); + + expect(source.getKey()).to.eql(urls.join('\n')); + }); + }); + describe('url option', function() { it('expands url template', function() { var tileSource = new ol.source.UrlTile({ From ac4653ada5656ae03a8d930fd4e8f85cb0471092 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 19 May 2016 09:07:57 -0600 Subject: [PATCH 09/10] Tests for source.setKey() --- test/spec/ol/source/tilesource.test.js | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/spec/ol/source/tilesource.test.js b/test/spec/ol/source/tilesource.test.js index 779b829dee..110524dcfe 100644 --- a/test/spec/ol/source/tilesource.test.js +++ b/test/spec/ol/source/tilesource.test.js @@ -12,6 +12,47 @@ describe('ol.source.Tile', function() { }); }); + describe('#setKey()', function() { + it('sets the source key', function() { + var source = new ol.source.Tile({}); + expect(source.getKey()).to.equal(''); + + var key = 'foo'; + source.setKey(key); + expect(source.getKey()).to.equal(key); + }); + }); + + describe('#setKey()', function() { + it('dispatches a change event', function(done) { + var source = new ol.source.Tile({}); + + var key = 'foo'; + source.once('change', function() { + done(); + }); + source.setKey(key); + }); + + it('does not dispatch change if key does not change', function(done) { + var source = new ol.source.Tile({}); + + var key = 'foo'; + source.once('change', function() { + source.once('change', function() { + done(new Error('Unexpected change event after source.setKey()')); + }); + setTimeout(function() { + done(); + }, 10); + source.setKey(key); // this should not result in a change event + }); + + source.setKey(key); // this should result in a change event + }); + + }); + describe('#forEachLoadedTile()', function() { var callback; From d50082b860d5db67f77cef034f80cdd814cc1be7 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 19 May 2016 09:17:23 -0600 Subject: [PATCH 10/10] Upgrade note regarding tile rendering --- changelog/upgrade-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md index 7db2980213..5e5e9116bb 100644 --- a/changelog/upgrade-notes.md +++ b/changelog/upgrade-notes.md @@ -1,5 +1,9 @@ ## Upgrade notes +#### Rendering change for tile sources + +Previously, if you called `source.setUrl()` on a tile source, all currently rendered tiles would be cleared before new tiles were loaded and rendered. This clearing of the map is undesirable if you are trying to smoothly update the tiles used by a source. This behavior has now changed, and calling `source.setUrl()` (or `source.setUrls()`) will *not* clear currently rendered tiles before loading and rendering new tiles. Instead, previously rendered tiles remain rendered until new tiles have loaded and can replace them. If you want to achieve the old behavior (render a blank map before loading new tiles), you can call `source.refresh()` or you can replace the old source with a new one (using `layer.setSource()`). + #### Move of typedefs out of code and into separate file This change should not affect the great majority of application developers, but it's possible there are edge cases when compiling application code together with the library which cause compiler errors or warnings. In this case, please raise a GitHub issue. `goog.require`s for typedefs should not be necessary.