From 7e950fda2bece4698d5b9080fa1d33a44edc6703 Mon Sep 17 00:00:00 2001 From: Conner Wingard Date: Fri, 26 Jun 2015 14:17:40 -0400 Subject: [PATCH] Add support for viewing custom tile sources with non-square tiles --- src/iiiftilesource.js | 9 +++++---- src/tiledimage.js | 2 +- src/tilesource.js | 43 ++++++++++++++++++++++++++++++------------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/iiiftilesource.js b/src/iiiftilesource.js index 484b7092..54779158 100644 --- a/src/iiiftilesource.js +++ b/src/iiiftilesource.js @@ -192,7 +192,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea if (this.tileSizePerScaleFactor && this.tileSizePerScaleFactor[scaleFactor]) { this.tileSize = this.tileSizePerScaleFactor[scaleFactor]; } - return this.tileSize; + return new $.Point(this.tileSize, this.tileSize); }, /** @@ -229,8 +229,9 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea uri; tileSize = this.getTileSize(level); - iiifTileSizeWidth = Math.ceil( tileSize / scale ); - iiifTileSizeHeight = iiifTileSizeWidth; + + iiifTileSizeWidth = Math.ceil( tileSize.x / scale ); + iiifTileSizeHeight = Math.ceil( tileSize.y / scale ); if ( this['@context'].indexOf('/1.0/context.json') > -1 || this['@context'].indexOf('/1.1/context.json') > -1 || @@ -240,7 +241,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea iiifQuality = "default.jpg"; } - if ( levelWidth < tileSize && levelHeight < tileSize ){ + if ( levelWidth < tileSize.x && levelHeight < tileSize.y ){ iiifSize = levelWidth + ","; iiifRegion = 'full'; } else { diff --git a/src/tiledimage.js b/src/tiledimage.js index 363df7c6..699ca254 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -1036,7 +1036,7 @@ function onTileLoad( tiledImage, tile, time, image ) { var finish = function() { var cutoff = Math.ceil( Math.log( - tiledImage.source.getTileSize(tile.level) ) / Math.log( 2 ) ); + tiledImage.source.getTileSize(tile.level).x ) / Math.log( 2 ) ); setTileLoaded(tiledImage, tile, image, cutoff); }; diff --git a/src/tilesource.js b/src/tilesource.js index 1c0d29d2..9ed329dc 100644 --- a/src/tilesource.js +++ b/src/tilesource.js @@ -73,6 +73,11 @@ * The size of the tiles to assumed to make up each pyramid layer in pixels. * Tile size determines the point at which the image pyramid must be * divided into a matrix of smaller images. + * Use options.tileWidth and options.tileHeight to support non-square tiles. + * @param {Number} [options.tileWidth] + * The width of the tiles to assumed to make up each pyramid layer in pixels. + * @param {Number} [options.tileHeight] + * The height of the tiles to assumed to make up each pyramid layer in pixels. * @param {Number} [options.tileOverlap] * The number of pixels each tile is expected to overlap touching tiles. * @param {Number} [options.minLevel] @@ -191,7 +196,10 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve this.aspectRatio = ( options.width && options.height ) ? ( options.width / options.height ) : 1; this.dimensions = new $.Point( options.width, options.height ); - this.tileSize = options.tileSize ? options.tileSize : 0; + this.tileSize = new $.Point( + ( options.tileSize ? options.tileSize : options.tileWidth ), + ( options.tileSize ? options.tileSize : options.tileHeight ) + ); this.tileOverlap = options.tileOverlap ? options.tileOverlap : 0; this.minLevel = options.minLevel ? options.minLevel : 0; this.maxLevel = ( undefined !== options.maxLevel && null !== options.maxLevel ) ? @@ -219,6 +227,7 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ * from .tileSize directly. tileSize may be deprecated in a future release. * @function * @param {Number} level + * @returns {OpenSeadragon.Point} The dimensions of tiles in level */ getTileSize: function( level ) { return this.tileSize; @@ -250,8 +259,8 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ */ getNumTiles: function( level ) { var scale = this.getLevelScale( level ), - x = Math.ceil( scale * this.dimensions.x / this.getTileSize(level) ), - y = Math.ceil( scale * this.dimensions.y / this.getTileSize(level) ); + x = Math.ceil( scale * this.dimensions.x / this.getTileSize(level).x ), + y = Math.ceil( scale * this.dimensions.y / this.getTileSize(level).y ); return new $.Point( x, y ); }, @@ -276,11 +285,19 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ getClosestLevel: function( rect ) { var i, tilesPerSide, - tiles; + tiles, + tileSize; + for( i = this.minLevel; i < this.maxLevel; i++ ){ tiles = this.getNumTiles( i ); - tilesPerSide = Math.floor( Math.max( rect.x, rect.y ) / this.getTileSize(i) ); - if( Math.max( tiles.x, tiles.y ) + 1 >= tilesPerSide ){ + tileSize = this.getTileSize(i); + + tilesPerSide = new $.Point( + Math.floor( rect.x / tileSize.x ), + Math.floor( rect.y / tileSize.y ) + ); + + if( tiles.x + 1 >= tilesPerSide.x && tiles.y + 1 >= tilesPerSide.y ){ break; } } @@ -293,9 +310,9 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ * @param {OpenSeadragon.Point} point */ getTileAtPoint: function( level, point ) { - var pixel = point.times( this.dimensions.x ).times( this.getLevelScale(level ) ), - tx = Math.floor( pixel.x / this.getTileSize(level) ), - ty = Math.floor( pixel.y / this.getTileSize(level) ); + var pixel = point.times( this.dimensions.x ).times( this.getLevelScale(level) ), + tx = Math.floor( pixel.x / this.getTileSize(level).x ), + ty = Math.floor( pixel.y / this.getTileSize(level).y ); return new $.Point( tx, ty ); }, @@ -309,10 +326,10 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ getTileBounds: function( level, x, y ) { var dimensionsScaled = this.dimensions.times( this.getLevelScale( level ) ), tileSize = this.getTileSize(level), - px = ( x === 0 ) ? 0 : tileSize * x - this.tileOverlap, - py = ( y === 0 ) ? 0 : tileSize * y - this.tileOverlap, - sx = tileSize + ( x === 0 ? 1 : 2 ) * this.tileOverlap, - sy = tileSize + ( y === 0 ? 1 : 2 ) * this.tileOverlap, + px = ( x === 0 ) ? 0 : tileSize.x * x - this.tileOverlap, + py = ( y === 0 ) ? 0 : tileSize.y * y - this.tileOverlap, + sx = tileSize.x + ( x === 0 ? 1 : 2 ) * this.tileOverlap, + sy = tileSize.y + ( y === 0 ? 1 : 2 ) * this.tileOverlap, scale = 1.0 / dimensionsScaled.x; sx = Math.min( sx, dimensionsScaled.x - px );