From 1c7e0f8481dae072da52ddaf3980fd4e91cb0794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 21 Jun 2012 18:56:43 +0200 Subject: [PATCH] add an ol.TileCache and use it in ol.TileLayer --- src/ol.js | 1 + src/ol/Tile.js | 7 +++++++ src/ol/TileCache.js | 29 +++++++++++++++++++++++++++++ src/ol/layer/TileLayer.js | 22 ++++++++++++++++++++++ src/ol/layer/XYZ.js | 13 ++++++++++++- test/index.html | 1 + test/spec/ol/TileCache.test.js | 20 ++++++++++++++++++++ 7 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/ol/TileCache.js create mode 100644 test/spec/ol/TileCache.test.js diff --git a/src/ol.js b/src/ol.js index c4ae4425f3..4489f2b092 100644 --- a/src/ol.js +++ b/src/ol.js @@ -12,6 +12,7 @@ goog.require("ol.layer.xyz"); goog.require("ol.layer.osm"); goog.require("ol.Tile"); goog.require("ol.TileSet"); +goog.require("ol.TileCache"); goog.require("ol.geom.geometry"); goog.require("ol.geom.point"); goog.require("ol.geom.multipoint"); diff --git a/src/ol/Tile.js b/src/ol/Tile.js index 788322f163..e6eb5bb905 100644 --- a/src/ol/Tile.js +++ b/src/ol/Tile.js @@ -88,6 +88,13 @@ ol.Tile.prototype.handleImageError = function(evt) { this.events_.triggerEvent('error'); }; +/** + * + */ +ol.Tile.prototype.destroy = function() { + this.events_.triggerEvent('destroy'); +}; + /** * Create an image node. This is done by cloning * the same image element. diff --git a/src/ol/TileCache.js b/src/ol/TileCache.js new file mode 100644 index 0000000000..08311ae19f --- /dev/null +++ b/src/ol/TileCache.js @@ -0,0 +1,29 @@ +goog.provide('ol.TileCache'); + +goog.require('goog.structs.LinkedMap'); + +/** + * A cache of ol.Tile objects. + * @constructor + * @extends {goog.structs.LinkedMap} + * @param {number=} opt_size + */ +ol.TileCache = function(opt_size) { + /** + * @constant + * @type {number} + */ + this.size_ = opt_size || 100; + + goog.base(this, 1, true /* cache mode */); +}; + +goog.inherits(ol.TileCache, goog.structs.LinkedMap); + +/** + * @inheritDoc + */ +ol.TileCache.prototype.removeNode = function(node) { + goog.base(this, 'removeNode', node); + node.value.destroy(); +}; diff --git a/src/ol/layer/TileLayer.js b/src/ol/layer/TileLayer.js index c87a318d0c..075d624d07 100644 --- a/src/ol/layer/TileLayer.js +++ b/src/ol/layer/TileLayer.js @@ -1,6 +1,7 @@ goog.provide('ol.layer.TileLayer'); goog.require('ol.layer.Layer'); +goog.require('ol.TileCache'); /** * @constructor @@ -68,6 +69,12 @@ ol.layer.TileLayer = function() { */ this.resolutions_ = null; + /** + * @private + * @type {ol.TileCache} + */ + this.cache_ = new ol.TileCache(); + }; goog.inherits(ol.layer.TileLayer, ol.layer.Layer); @@ -214,3 +221,18 @@ ol.layer.TileLayer.prototype.setNumZoomLevels = function(numZoomLevels) { ol.layer.TileLayer.prototype.setResolutions = function(resolutions) { this.resolutions_ = resolutions; }; + +/** + * Get a tile from the cache, or create a tile and add to + * the cache. + * @param url {string} + * @param bounds {ol.Bounds} + */ +ol.layer.TileLayer.prototype.getTile = function(url, bounds) { + var tile = this.cache_.get(url); + if (!goog.isDef(tile)) { + tile = new ol.Tile(url, bounds); + this.cache_.set(tile.getUrl(), tile); + } + return tile; +}; diff --git a/src/ol/layer/XYZ.js b/src/ol/layer/XYZ.js index b9f1200347..72b604aba8 100644 --- a/src/ol/layer/XYZ.js +++ b/src/ol/layer/XYZ.js @@ -25,6 +25,17 @@ ol.layer.XYZ = function(url) { goog.base(this); this.setMaxResolution(156543.03390625); + + this.setResolutions([ + 156543.03390625, 78271.516953125, 39135.7584765625, + 19567.87923828125, 9783.939619140625, 4891.9698095703125, + 2445.9849047851562, 1222.9924523925781, 611.4962261962891, + 305.74811309814453, 152.87405654907226, 76.43702827453613, + 38.218514137268066, 19.109257068634033, 9.554628534317017, + 4.777314267158508, 2.388657133579254, 1.194328566789627, + 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, + 0.07464553542435169 + ]); }; goog.inherits(ol.layer.XYZ, ol.layer.TileLayer); @@ -81,7 +92,7 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { url = me.url_.replace('{x}', offsetX + x + '') .replace('{y}', offsetY + y + '') .replace('{z}', zoom + ''); - tile = new ol.Tile(url, tileBounds); + tile = this.getTile(url, tileBounds); tiles[y][x] = tile; } } diff --git a/test/index.html b/test/index.html index f218500bb1..53d0f6c39d 100644 --- a/test/index.html +++ b/test/index.html @@ -63,6 +63,7 @@ + diff --git a/test/spec/ol/TileCache.test.js b/test/spec/ol/TileCache.test.js new file mode 100644 index 0000000000..5211ac22a1 --- /dev/null +++ b/test/spec/ol/TileCache.test.js @@ -0,0 +1,20 @@ +describe('ol.TileCache', function() { + + describe('exceed the cache capacity', function() { + + var tilecache, tile; + + beforeEach(function() { + tilecache = new ol.TileCache(1); + tile = new ol.Tile('url1'); + tilecache.set('url1', tile); + spyOn(tile, 'destroy'); + }); + + it('calls tile.destroy', function() { + tilecache.set('url2', new ol.Tile('url2')); + expect(tile.destroy).toHaveBeenCalled(); + }); + }); + +});