1 /** 2 * @namespace 3 */ 4 var TiledImageStore; if( !TiledImageStore ) TiledImageStore = {}; 5 6 /** 7 * Implements a store for image tiles that are only available at a 8 * fixed set of sizes and zoom levels. Most often used with 9 * pre-generated image tiles served statically. 10 * @class 11 * @extends Store 12 */ 13 14 TiledImageStore.Fixed = function(args) { 15 Store.call( this, args ); 16 if( !args ) 17 return; 18 19 this.tileToImage = {}; 20 this.zoomCache = {}; 21 22 this.refSeq = args.refSeq; 23 24 this.url = Util.resolveUrl( 25 args.baseUrl, 26 Util.fillTemplate( args.urlTemplate, 27 {'refseq': this.refSeq.name } ) 28 ); 29 }; 30 31 TiledImageStore.Fixed.prototype = new Store(''); 32 33 TiledImageStore.Fixed.prototype.loadSuccess = function(o) { 34 this.stats = o.stats; 35 36 //tileWidth: width, in pixels, of the tiles 37 this.tileWidth = o.tileWidth; 38 this.align = o.align; 39 //zoomLevels: array of {basesPerTile, urlPrefix} hashes 40 this.zoomLevels = o.zoomLevels; 41 this.setLoaded(); 42 }; 43 44 /** 45 * @private 46 */ 47 TiledImageStore.Fixed.prototype._getZoom = function(scale) { 48 var result = this.zoomCache[scale]; 49 if (result) return result; 50 51 result = this.zoomLevels[0]; 52 var desiredBases = this.tileWidth / scale; 53 for (var i = 1; i < this.zoomLevels.length; i++) { 54 if (Math.abs(this.zoomLevels[i].basesPerTile - desiredBases) 55 < Math.abs(result.basesPerTile - desiredBases)) 56 result = this.zoomLevels[i]; 57 } 58 59 this.zoomCache[scale] = result; 60 return result; 61 }; 62 63 /** 64 * Fetch an array of <code><img></code> elements for the image 65 * tiles that should be displayed for a certain magnification scale 66 * and section of the reference. 67 * @param {Number} scale the current ratio of pixels per base in the view 68 * @param {Number} startBase the start of the region (in interbase coordinates) 69 * @param {Number} endBase the end of the region (in interbase coordinates) 70 */ 71 TiledImageStore.Fixed.prototype.getImages = function( scale, startBase, endBase ) { 72 73 var zoom = this._getZoom( scale ); 74 75 var startTile = Math.max( startBase / zoom.basesPerTile, 0 ) | 0; 76 var endTile = endBase / zoom.basesPerTile | 0; 77 78 var result = []; 79 var im; 80 for (var i = startTile; i <= endTile; i++) { 81 im = this.tileToImage[i]; 82 if (!im) { 83 im = document.createElement("img"); 84 dojo.connect(im, "onerror", this.handleImageError ); 85 im.src = this._imageSource( zoom, i ); 86 //TODO: need image coord systems that don't start at 0? 87 im.startBase = (i * zoom.basesPerTile); // + this.refSeq.start; 88 im.baseWidth = zoom.basesPerTile; 89 im.tileNum = i; 90 this.tileToImage[i] = im; 91 } 92 result.push(im); 93 } 94 return result; 95 }; 96 97 /** 98 * Gives the image source for a given zoom (as returned by _getZoom()) 99 * and tileIndex. 100 * @private 101 */ 102 TiledImageStore.Fixed.prototype._imageSource = function( zoom, tileIndex ) { 103 return Util.resolveUrl(this.url, zoom.urlPrefix + tileIndex + ".png"); 104 }; 105 106 /** 107 * Clear the store's cache of image elements. 108 */ 109 TiledImageStore.Fixed.prototype.clearCache = function() { 110 this.tileToImage = {}; 111 }; 112 113 /** 114 * Remove the given image element from the cache. 115 */ 116 TiledImageStore.Fixed.prototype.unCacheImage = function( /**HTMLImageElement*/ im) { 117 delete this.tileToImage[ im.tileNum ]; 118 }; 119