2011-12-06 07:50:25 +04:00
|
|
|
|
|
|
|
(function( $ ){
|
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
/**
|
|
|
|
* @class
|
2012-02-01 00:59:09 +04:00
|
|
|
* @extends OpenSeadragon.TileSource
|
2012-08-29 22:46:34 +04:00
|
|
|
* @param {Number|Object} width - the pixel width of the image or the idiomatic
|
|
|
|
* options object which is used instead of positional arguments.
|
2012-02-01 00:59:09 +04:00
|
|
|
* @param {Number} height
|
|
|
|
* @param {Number} tileSize
|
|
|
|
* @param {Number} tileOverlap
|
|
|
|
* @param {String} tilesUrl
|
|
|
|
* @param {String} fileFormat
|
|
|
|
* @param {OpenSeadragon.DisplayRect[]} displayRects
|
|
|
|
* @property {String} tilesUrl
|
|
|
|
* @property {String} fileFormat
|
|
|
|
* @property {OpenSeadragon.DisplayRect[]} displayRects
|
|
|
|
*/
|
2012-01-24 07:48:45 +04:00
|
|
|
$.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, fileFormat, displayRects ) {
|
|
|
|
var i,
|
|
|
|
rect,
|
2012-06-05 15:52:00 +04:00
|
|
|
level,
|
|
|
|
options;
|
|
|
|
|
|
|
|
if( $.isPlainObject( width ) ){
|
|
|
|
options = width;
|
|
|
|
}else{
|
|
|
|
options = {
|
|
|
|
width: arguments[ 0 ],
|
|
|
|
height: arguments[ 1 ],
|
|
|
|
tileSize: arguments[ 2 ],
|
|
|
|
tileOverlap: arguments[ 3 ],
|
|
|
|
tilesUrl: arguments[ 4 ],
|
|
|
|
fileFormat: arguments[ 5 ],
|
|
|
|
dispRects: arguments[ 6 ]
|
|
|
|
};
|
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-24 07:48:45 +04:00
|
|
|
this._levelRects = {};
|
2012-06-05 15:52:00 +04:00
|
|
|
this.tilesUrl = options.tilesUrl;
|
|
|
|
this.fileFormat = options.fileFormat;
|
|
|
|
this.displayRects = options.displayRects;
|
2011-12-14 03:34:12 +04:00
|
|
|
|
|
|
|
if ( this.displayRects ) {
|
2012-01-24 07:48:45 +04:00
|
|
|
for ( i = this.displayRects.length - 1; i >= 0; i-- ) {
|
|
|
|
rect = this.displayRects[ i ];
|
|
|
|
for ( level = rect.minLevel; level <= rect.maxLevel; level++ ) {
|
|
|
|
if ( !this._levelRects[ level ] ) {
|
|
|
|
this._levelRects[ level ] = [];
|
2011-12-14 03:29:25 +04:00
|
|
|
}
|
2012-01-24 07:48:45 +04:00
|
|
|
this._levelRects[ level ].push( rect );
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
}
|
2011-12-14 03:34:12 +04:00
|
|
|
}
|
2012-06-05 15:52:00 +04:00
|
|
|
|
|
|
|
$.TileSource.apply( this, [ options ] );
|
2011-12-14 03:34:12 +04:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
$.extend( $.DziTileSource.prototype, $.TileSource.prototype, {
|
2012-06-05 15:52:00 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine if the data and/or url imply the image service is supported by
|
|
|
|
* this tile source.
|
|
|
|
* @function
|
|
|
|
* @name OpenSeadragon.DziTileSource.prototype.supports
|
|
|
|
* @param {Object|Array} data
|
|
|
|
* @param {String} optional - url
|
|
|
|
*/
|
|
|
|
supports: function( data, url ){
|
|
|
|
return (
|
|
|
|
data.Image &&
|
|
|
|
"http://schemas.microsoft.com/deepzoom/2008" == data.Image.xmlns
|
|
|
|
) || (
|
|
|
|
data.documentElement &&
|
|
|
|
"Image" == data.documentElement.tagName &&
|
|
|
|
"http://schemas.microsoft.com/deepzoom/2008" ==
|
|
|
|
data.documentElement.namespaceURI
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @function
|
|
|
|
* @name OpenSeadragon.DziTileSource.prototype.configure
|
2012-08-29 22:46:34 +04:00
|
|
|
* @param {Object|XMLDocument} data - the raw configuration
|
|
|
|
* @param {String} url - the url the data was retreived from if any.
|
|
|
|
* @return {Object} options - A dictionary of keyword arguments sufficient
|
|
|
|
* to configure this tile sources constructor.
|
2012-06-05 15:52:00 +04:00
|
|
|
*/
|
2012-08-29 22:46:34 +04:00
|
|
|
configure: function( data, url ){
|
2012-06-05 15:52:00 +04:00
|
|
|
|
|
|
|
var dziPath,
|
|
|
|
dziName,
|
|
|
|
tilesUrl,
|
|
|
|
options,
|
|
|
|
host;
|
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
if( !$.isPlainObject(data) ){
|
2012-06-05 15:52:00 +04:00
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
options = configureFromXML( this, data );
|
2012-06-05 15:52:00 +04:00
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
}else{
|
2012-06-05 15:52:00 +04:00
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
options = configureFromObject( this, data );
|
2012-06-05 15:52:00 +04:00
|
|
|
}
|
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
if( url && !options.tilesUrl ){
|
|
|
|
if( !( 'http' == url.substring( 0, 4 ) ) ){
|
2012-06-05 15:52:00 +04:00
|
|
|
host = location.protocol + '//' + location.host;
|
|
|
|
}
|
2012-08-29 22:46:34 +04:00
|
|
|
dziPath = url.split('/');
|
2012-06-05 15:52:00 +04:00
|
|
|
dziName = dziPath.pop();
|
|
|
|
dziName = dziName.substring(0, dziName.indexOf('.'));
|
|
|
|
dziPath = '/' + dziPath.join('/') + '/' + dziName + '_files/';
|
|
|
|
tilesUrl = dziPath;
|
|
|
|
if( host ){
|
|
|
|
tilesUrl = host + tilesUrl;
|
|
|
|
}
|
|
|
|
options.tilesUrl = tilesUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return options;
|
|
|
|
},
|
|
|
|
|
|
|
|
|
2012-02-01 00:59:09 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @name OpenSeadragon.DziTileSource.prototype.getTileUrl
|
|
|
|
* @param {Number} level
|
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
|
|
|
*/
|
2012-01-24 07:48:45 +04:00
|
|
|
getTileUrl: function( level, x, y ) {
|
|
|
|
return [ this.tilesUrl, level, '/', x, '_', y, '.', this.fileFormat ].join( '' );
|
2011-12-14 03:29:25 +04:00
|
|
|
},
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-06-05 15:52:00 +04:00
|
|
|
|
2012-02-01 00:59:09 +04:00
|
|
|
/**
|
|
|
|
* @function
|
|
|
|
* @name OpenSeadragon.DziTileSource.prototype.tileExists
|
|
|
|
* @param {Number} level
|
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
|
|
|
*/
|
2012-01-24 07:48:45 +04:00
|
|
|
tileExists: function( level, x, y ) {
|
|
|
|
var rects = this._levelRects[ level ],
|
|
|
|
rect,
|
|
|
|
scale,
|
|
|
|
xMin,
|
|
|
|
yMin,
|
|
|
|
xMax,
|
|
|
|
yMax,
|
|
|
|
i;
|
|
|
|
|
|
|
|
if ( !rects || !rects.length ) {
|
2011-12-14 03:29:25 +04:00
|
|
|
return true;
|
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-24 07:48:45 +04:00
|
|
|
for ( i = rects.length - 1; i >= 0; i-- ) {
|
|
|
|
rect = rects[ i ];
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-24 07:48:45 +04:00
|
|
|
if ( level < rect.minLevel || level > rect.maxLevel ) {
|
2011-12-14 03:29:25 +04:00
|
|
|
continue;
|
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-24 07:48:45 +04:00
|
|
|
scale = this.getLevelScale( level );
|
|
|
|
xMin = rect.x * scale;
|
|
|
|
yMin = rect.y * scale;
|
|
|
|
xMax = xMin + rect.width * scale;
|
|
|
|
yMax = yMin + rect.height * scale;
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-24 07:48:45 +04:00
|
|
|
xMin = Math.floor( xMin / this.tileSize );
|
|
|
|
yMin = Math.floor( yMin / this.tileSize );
|
|
|
|
xMax = Math.ceil( xMax / this.tileSize );
|
|
|
|
yMax = Math.ceil( yMax / this.tileSize );
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2012-01-24 07:48:45 +04:00
|
|
|
if ( xMin <= x && x < xMax && yMin <= y && y < yMax ) {
|
2011-12-14 03:29:25 +04:00
|
|
|
return true;
|
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
|
2011-12-14 03:29:25 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2011-12-06 07:50:25 +04:00
|
|
|
|
|
|
|
|
2012-06-05 15:52:00 +04:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @inner
|
|
|
|
* @function
|
|
|
|
*/
|
|
|
|
function configureFromXML( tileSource, xmlDoc ){
|
|
|
|
|
|
|
|
if ( !xmlDoc || !xmlDoc.documentElement ) {
|
|
|
|
throw new Error( $.getString( "Errors.Xml" ) );
|
|
|
|
}
|
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
var root = xmlDoc.documentElement,
|
|
|
|
rootName = root.tagName,
|
|
|
|
configuration = null,
|
|
|
|
displayRects = [],
|
2012-06-05 15:52:00 +04:00
|
|
|
dispRectNodes,
|
|
|
|
dispRectNode,
|
|
|
|
rectNode,
|
|
|
|
sizeNode,
|
|
|
|
i;
|
|
|
|
|
|
|
|
if ( rootName == "Image" ) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
sizeNode = root.getElementsByTagName( "Size" )[ 0 ];
|
2012-08-29 22:46:34 +04:00
|
|
|
configuration = {
|
2012-06-05 15:52:00 +04:00
|
|
|
Image: {
|
|
|
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
|
|
|
Format: root.getAttribute( "Format" ),
|
|
|
|
DisplayRect: null,
|
|
|
|
Overlap: parseInt( root.getAttribute( "Overlap" ) ),
|
|
|
|
TileSize: parseInt( root.getAttribute( "TileSize" ) ),
|
|
|
|
Size: {
|
|
|
|
Height: parseInt( sizeNode.getAttribute( "Height" ) ),
|
|
|
|
Width: parseInt( sizeNode.getAttribute( "Width" ) )
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
if ( !$.imageFormatSupported( configuration.Image.Format ) ) {
|
2012-06-05 15:52:00 +04:00
|
|
|
throw new Error(
|
2012-08-29 22:46:34 +04:00
|
|
|
$.getString( "Errors.ImageFormat", configuration.Image.Format.toUpperCase() )
|
2012-06-05 15:52:00 +04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
dispRectNodes = root.getElementsByTagName( "DisplayRect" );
|
|
|
|
for ( i = 0; i < dispRectNodes.length; i++ ) {
|
|
|
|
dispRectNode = dispRectNodes[ i ];
|
|
|
|
rectNode = dispRectNode.getElementsByTagName( "Rect" )[ 0 ];
|
|
|
|
|
|
|
|
displayRects.push({
|
|
|
|
Rect: {
|
|
|
|
X: parseInt( rectNode.getAttribute( "X" ) ),
|
|
|
|
Y: parseInt( rectNode.getAttribute( "Y" ) ),
|
|
|
|
Width: parseInt( rectNode.getAttribute( "Width" ) ),
|
|
|
|
Height: parseInt( rectNode.getAttribute( "Height" ) ),
|
|
|
|
MinLevel: 0, // ignore MinLevel attribute, bug in Deep Zoom Composer
|
|
|
|
MaxLevel: parseInt( dispRectNode.getAttribute( "MaxLevel" ) )
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if( displayRects.length ){
|
2012-08-29 22:46:34 +04:00
|
|
|
configuration.Image.DisplayRect = displayRects;
|
2012-06-05 15:52:00 +04:00
|
|
|
}
|
|
|
|
|
2012-08-29 22:46:34 +04:00
|
|
|
return configureFromObject( tileSource, configuration );
|
2012-06-05 15:52:00 +04:00
|
|
|
|
|
|
|
} catch ( e ) {
|
|
|
|
throw (e instanceof Error) ?
|
|
|
|
e :
|
|
|
|
new Error( $.getString("Errors.Dzi") );
|
|
|
|
}
|
|
|
|
} else if ( rootName == "Collection" ) {
|
|
|
|
throw new Error( $.getString( "Errors.Dzc" ) );
|
|
|
|
} else if ( rootName == "Error" ) {
|
|
|
|
return processDZIError( root );
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error( $.getString( "Errors.Dzi" ) );
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @inner
|
|
|
|
* @function
|
|
|
|
*/
|
|
|
|
function configureFromObject( tileSource, configuration ){
|
|
|
|
var imageData = configuration.Image,
|
|
|
|
tilesUrl = imageData.Url,
|
|
|
|
fileFormat = imageData.Format,
|
|
|
|
sizeData = imageData.Size,
|
|
|
|
dispRectData = imageData.DisplayRect || [],
|
|
|
|
width = parseInt( sizeData.Width ),
|
|
|
|
height = parseInt( sizeData.Height ),
|
|
|
|
tileSize = parseInt( imageData.TileSize ),
|
|
|
|
tileOverlap = parseInt( imageData.Overlap ),
|
|
|
|
dispRects = [],
|
|
|
|
rectData,
|
|
|
|
i;
|
|
|
|
|
|
|
|
//TODO: need to figure out out to better handle image format compatibility
|
|
|
|
// which actually includes additional file formats like xml and pdf
|
|
|
|
// and plain text for various tilesource implementations to avoid low
|
|
|
|
// level errors.
|
|
|
|
//
|
|
|
|
// For now, just don't perform the check.
|
|
|
|
//
|
|
|
|
/*if ( !imageFormatSupported( fileFormat ) ) {
|
|
|
|
throw new Error(
|
|
|
|
$.getString( "Errors.ImageFormat", fileFormat.toUpperCase() )
|
|
|
|
);
|
|
|
|
}*/
|
|
|
|
|
|
|
|
for ( i = 0; i < dispRectData.length; i++ ) {
|
|
|
|
rectData = dispRectData[ i ].Rect;
|
|
|
|
|
|
|
|
dispRects.push( new $.DisplayRect(
|
|
|
|
parseInt( rectData.X ),
|
|
|
|
parseInt( rectData.Y ),
|
|
|
|
parseInt( rectData.Width ),
|
|
|
|
parseInt( rectData.Height ),
|
|
|
|
0, // ignore MinLevel attribute, bug in Deep Zoom Composer
|
|
|
|
parseInt( rectData.MaxLevel )
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
width: width, /* width *required */
|
|
|
|
height: height, /* height *required */
|
|
|
|
tileSize: tileSize, /* tileSize *required */
|
|
|
|
tileOverlap: tileOverlap, /* tileOverlap *required */
|
|
|
|
minLevel: null, /* minLevel */
|
|
|
|
maxLevel: null, /* maxLevel */
|
|
|
|
tilesUrl: tilesUrl, /* tilesUrl */
|
|
|
|
fileFormat: fileFormat, /* fileFormat */
|
|
|
|
dispRects: dispRects /* dispRects */
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
2011-12-06 07:50:25 +04:00
|
|
|
|
|
|
|
}( OpenSeadragon ));
|