diff --git a/src/highlightoverlay.js b/src/highlightoverlay.js new file mode 100644 index 00000000..0a045e62 --- /dev/null +++ b/src/highlightoverlay.js @@ -0,0 +1,33 @@ +function addOverlay(viewer, x1, y1, x2, y2) +{ + var div = document.createElement("div"); + var rect = new Seadragon.Rect(x1, y1, x2, y2); + + div.className = "overlay"; + viewer.drawer.addOverlay(div, rect); +}; + +function addOverlays(viewer) +{ + var factor = viewer.source.height / viewer.source.width; + $.each("".split("+"), function(index, word) { + if (word!="") { + $.getJSON('/beta/lccn/sn83030213/1865-04-10/ed-1/seq-1/coordinates/;words='+word, function(all_coordinates) { + var boxes = []; + for (word in all_coordinates) { + var coordinates = all_coordinates[word]; + for (k in coordinates) { + var v = coordinates[k]; + addOverlay( + viewer, + v["hpos"], + v["vpos"]*factor, + v["width"], + v["height"]*factor + ); + } + } + }); + } + }); +}; diff --git a/src/iiiftilesource.js b/src/iiiftilesource.js new file mode 100644 index 00000000..36ac6f6e --- /dev/null +++ b/src/iiiftilesource.js @@ -0,0 +1,294 @@ +(function( $ ){ + +/** + * A client implementation of the International Image Interoperability + * Format: Image API Draft 0.2 - Please read more about the specification + * at + * + * The getTileUrl implementation is based on the gist from: + * https://gist.github.com/jpstroop/4624253 + * + * @class + * @name OpenSeadragon.IIIFTileSource + * @see http://library.stanford.edu/iiif/image-api/ + */ +$.IIIFTileSource = function( options ){ + + $.extend( true, this, options ); + + if( !(this.height && this.width && this.identifier && this.tilesUrl ) ){ + throw new Error('IIIF required parameters not provided.'); + } + + //TODO: at this point the base tile source implementation assumes + // a tile is a square and so only has one property tileSize + // to store it. It may be possible to make tileSize a vector + // OpenSeadraon.Point but would require careful implementation + // to preserve backward compatibility. + options.tileSize = this.tile_width; + + options.maxLevel = options.maxLevel ? options.maxLevel : Number( + Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ) ) + ); + + $.TileSource.apply( this, [ options ] ); +}; + +$.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, { + + + /** + * Determine if the data and/or url imply the image service is supported by + * this tile source. + * @function + * @name OpenSeadragon.IIIFTileSource.prototype.supports + * @param {Object|Array} data + * @param {String} optional - url + */ + supports: function( data, url ){ + return ( + data.ns && + "http://library.stanford.edu/iiif/image-api/ns/" == data.ns + ) || ( + data.profile && ( + "http://library.stanford.edu/iiif/image-api/compliance.html#level1" == data.profile || + "http://library.stanford.edu/iiif/image-api/compliance.html#level2" == data.profile || + "http://library.stanford.edu/iiif/image-api/compliance.html#level3" == data.profile || + "http://library.stanford.edu/iiif/image-api/compliance.html" == data.profile + ) + ) || ( + data.documentElement && + "info" == data.documentElement.tagName && + "http://library.stanford.edu/iiif/image-api/ns/" == + data.documentElement.namespaceURI + ); + }, + + /** + * + * @function + * @name OpenSeadragon.IIIFTileSource.prototype.configure + * @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 source via it's constructor. + */ + configure: function( data, url ){ + var service, + identifier, + options, + host; + + if( !$.isPlainObject(data) ){ + + options = configureFromXML( this, data ); + + }else{ + + options = configureFromObject( this, data ); + } + + if( url && !options.tilesUrl ){ + service = url.split('/'); + service.pop(); //info.json or info.xml + service = service.join('/'); + if( !( 'http' == url.substring( 0, 4 ) ) ){ + host = location.protocol + '//' + location.host; + service = host + service; + } + options.tilesUrl = service.replace( + data.identifier, + '' + ); + } + + return options; + }, + + /** + * Responsible for retreiving the url which will return an image for the + * region speified by the given x, y, and level components. + * @function + * @name OpenSeadragon.IIIFTileSource.prototype.getTileUrl + * @param {Number} level - z index + * @param {Number} x + * @param {Number} y + * @throws {Error} + */ + getTileUrl: function( level, x, y ){ + + //# constants + var IIIF_ROTATION = '0', + IIIF_QUALITY = 'native.jpg', + + //## get the scale (level as a decimal) + scale = Math.pow( 0.5, this.maxLevel - level ), + + //## get iiif size + iiif_size = 'pct:' + ( scale * 100 ), + + //# image dimensions at this level + level_width = Math.ceil( this.width * scale ), + level_height = Math.ceil( this.height * scale ), + + //## iiif region + iiif_tile_size_width = Math.ceil( this.tileSize / scale ), + iiif_tile_size_height = Math.ceil( this.tileSize / scale ), + iiif_region, + iiif_tile_x, + iiif_tile_y, + iiif_tile_w, + iiif_tile_h; + + + if ( level_width < this.tile_width || level_height < this.tile_height ){ + iiif_region = 'full'; + } else { + iiif_tile_x = x * iiif_tile_size_width; + iiif_tile_y = y * iiif_tile_size_height; + iiif_tile_w = Math.min( iiif_tile_size_width, this.width - iiif_tile_x ); + iiif_tile_h = Math.min( iiif_tile_size_height, this.height - iiif_tile_y ); + iiif_region = [ iiif_tile_x, iiif_tile_y, iiif_tile_w, iiif_tile_h ].join(','); + } + + return [ + this.tilesUrl, + this.identifier, + iiif_region, + iiif_size, + IIIF_ROTATION, + IIIF_QUALITY + ].join('/'); + } + + +}); + +/** + * @private + * @inner + * @function + * + + + 1E34750D-38DB-4825-A38A-B60A345E591C + 6000 + 4000 + + 1 + 2 + 4 + + 1024 + 1024 + + jpg + png + + + native + grey + + + */ +function configureFromXml( tileSource, xmlDoc ){ + var configuration = {}; + + //parse the xml + if ( !xmlDoc || !xmlDoc.documentElement ) { + throw new Error( $.getString( "Errors.Xml" ) ); + } + + var root = xmlDoc.documentElement, + rootName = root.tagName, + configuration = null, + scale_factors, + formats, + qualities, + i; + + if ( rootName == "info" ) { + + try { + + configuration = { + "ns": root.namespaceURI, + "identifier": root.getElement('identifier').innerHTML, + "width": root.getElement('width').innerHTML, + "height": root.getElement('height').innerHTML, + "scale_factors": null, + "tile_width": root.getElement('tile_width').innerHTML, + "tile_height": root.getElement('tile_height').innerHTML, + "formats": [ "jpg", "png" ], + "quality": [ "native", "grey" ] + }; + + scale_factors = root.getElement('scale_factors'); + if( scale_factors ){ + scale_factors = scale_factors.getElementsByTagName('scale_factor'); + configuration.scale_factors = []; + for( i = 0; i < scale_factors.length; i++ ){ + configuration.scale_factors.push( + scale_factors[ i ].innerHTML + ); + } + } + + formats = root.getElement('formats'); + if( formats ){ + formats = formats.getElementsByTagName('format'); + configuration.formats = []; + for( i = 0; i < formats.length; i++ ){ + configuration.formats.push( + formats[ i ].innerHTML + ); + } + } + + qualities = root.getElement('qualities'); + if( qualities ){ + qualities = formats.getElementsByTagName('quality'); + configuration.quality = []; + for( i = 0; i < qualities.length; i++ ){ + configuration.quality.push( + qualities[ i ].innerHTML + ); + } + } + + return configureFromObject( tileSource, configuration ); + + } catch ( e ) { + throw (e instanceof Error) ? + e : + new Error( $.getString("Errors.IIIF") ); + } + } + + throw new Error( $.getString( "Errors.IIIF" ) ); + +}; + + +/** + * @private + * @inner + * @function + * + { + "profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level1", + "identifier" : "1E34750D-38DB-4825-A38A-B60A345E591C", + "width" : 6000, + "height" : 4000, + "scale_factors" : [ 1, 2, 4 ], + "tile_width" : 1024, + "tile_height" : 1024, + "formats" : [ "jpg", "png" ], + "quality" : [ "native", "grey" ] + } + */ +function configureFromObject( tileSource, configuration ){ + return configuration; +}; + +}( OpenSeadragon )); \ No newline at end of file diff --git a/src/osmtilesource.js b/src/osmtilesource.js new file mode 100644 index 00000000..3672231c --- /dev/null +++ b/src/osmtilesource.js @@ -0,0 +1,106 @@ +(function( $ ){ + +/** + * A tilesource implementation for OpenStreetMap. Adopted from Rainer Simon + * project http://github.com/rsimon/seajax-utils. + * + * Note 1. Zoomlevels. Deep Zoom and OSM define zoom levels differently. In Deep + * Zoom, level 0 equals an image of 1x1 pixels. In OSM, level 0 equals an image of + * 256x256 levels (see http://gasi.ch/blog/inside-deep-zoom-2). I.e. there is a + * difference of log2(256)=8 levels. + * + * Note 2. Image dimension. According to the OSM Wiki + * (http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels) + * the highest Mapnik zoom level has 256.144x256.144 tiles, with a 256x256 + * pixel size. I.e. the Deep Zoom image dimension is 65.572.864x65.572.864 + * pixels. + * + * @class + * @extends OpenSeadragon.TileSource + * @param {Number|Object} width - the pixel width of the image or the idiomatic + * options object which is used instead of positional arguments. + * @param {Number} height + * @param {Number} tileSize + * @param {Number} tileOverlap + * @param {String} tilesUrl + */ +$.OsmTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) { + var options; + + if( $.isPlainObject( width ) ){ + options = width; + }else{ + options = { + width: arguments[0], + height: arguments[1], + tileSize: arguments[2], + tileOverlap: arguments[3], + tilesUrl: arguments[4] + }; + } + //apply default setting for standard public OpenStreatMaps service + //but allow them to be specified so fliks can host there own instance + //or apply against other services supportting the same standard + if( !options.width || !options.height ){ + options.width = 65572864; + options.height = 65572864; + } + if( !options.tileSize ){ + options.tileSize = 256; + options.tileOverlap = 0; + } + if( !options.tilesUrl ){ + options.tilesUrl = "http://tile.openstreetmap.org/"; + } + options.minLevel = 8; + + $.TileSource.apply( this, [ options ] ); + +}; + +$.extend( $.OsmTileSource.prototype, $.TileSource.prototype, { + + + /** + * 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.type && + "openstreetmaps" == data.type + ) + }, + + /** + * + * @function + * @name OpenSeadragon.OsmTileSource.prototype.configure + * @param {Object} 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. + */ + configure: function( data, url ){ + return data; + }, + + + /** + * @function + * @name OpenSeadragon.OsmTileSource.prototype.getTileUrl + * @param {Number} level + * @param {Number} x + * @param {Number} y + */ + getTileUrl: function( level, x, y ) { + return this.tilesUrl + (level - 8) + "/" + x + "/" + y + ".png"; + } +}); + + +}( OpenSeadragon )); diff --git a/src/tmstilesource.js b/src/tmstilesource.js new file mode 100644 index 00000000..1ab550fc --- /dev/null +++ b/src/tmstilesource.js @@ -0,0 +1,98 @@ +(function( $ ){ + +/** + * A tilesource implementation for Tiled Map Services (TMS). Adopted from Rainer Simon + * project http://github.com/rsimon/seajax-utils. TMS tile + * scheme ( [ as supported by OpenLayers ] is described here + * ( http://openlayers.org/dev/examples/tms.html ) ) + * + * @class + * @extends OpenSeadragon.TileSource + * @param {Number|Object} width - the pixel width of the image or the idiomatic + * options object which is used instead of positional arguments. + * @param {Number} height + * @param {Number} tileSize + * @param {Number} tileOverlap + * @param {String} tilesUrl + */ +$.TmsTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) { + var options; + + if( $.isPlainObject( width ) ){ + options = width; + }else{ + options = { + width: arguments[0], + height: arguments[1], + tileSize: arguments[2], + tileOverlap: arguments[3], + tilesUrl: arguments[4] + }; + } + // TMS has integer multiples of 256 for width/height and adds buffer + // if necessary -> account for this! + var bufferedWidth = Math.ceil(options.width / 256) * 256, + bufferedHeight = Math.ceil(options.height / 256) * 256, + max; + + // Compute number of zoomlevels in this tileset + if (bufferedWidth > bufferedHeight) { + max = bufferedWidth / 256; + } else { + max = bufferedHeight / 256; + } + options.maxLevel = Math.ceil(Math.log(max)/Math.log(2)) - 1; + options.tileSize = 256; + options.width = bufferedWidth; + options.height = bufferedHeight; + + $.TileSource.apply( this, [ options ] ); + +}; + +$.extend( $.TmsTileSource.prototype, $.TileSource.prototype, { + + + /** + * Determine if the data and/or url imply the image service is supported by + * this tile source. + * @function + * @name OpenSeadragon.TmsTileSource.prototype.supports + * @param {Object|Array} data + * @param {String} optional - url + */ + supports: function( data, url ){ + return ( data.type && "tiledmapservice" == data.type ); + }, + + /** + * + * @function + * @name OpenSeadragon.TmsTileSource.prototype.configure + * @param {Object} 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. + */ + configure: function( data, url ){ + return data; + }, + + + /** + * @function + * @name OpenSeadragon.TmsTileSource.prototype.getTileUrl + * @param {Number} level + * @param {Number} x + * @param {Number} y + */ + getTileUrl: function( level, x, y ) { + // Convert from Deep Zoom definition to TMS zoom definition + var yTiles = this.getNumTiles( level ).y - 1; + + return this.tilesUrl + level + "/" + x + "/" + (yTiles - y) + ".png"; + } +}); + + +}( OpenSeadragon )); \ No newline at end of file diff --git a/www/base.html b/www/base.html index ebe3ec25..1cb052fc 100644 --- a/www/base.html +++ b/www/base.html @@ -70,9 +70,9 @@
  • Legacy Image Pyramids
  • - +
  • DZI (Deep Zoom Images)
  • diff --git a/www/tilesource-iiif.html b/www/tilesource-iiif.html index 4bad843b..7756afca 100644 --- a/www/tilesource-iiif.html +++ b/www/tilesource-iiif.html @@ -43,10 +43,17 @@ viewport zoom and position when changing pages.

    +

    + In order to make this feel just a little more like a basic book turner, we are + adding a useful combination of other options that help to constrain the viewport. +

     OpenSeadragon({
         ...
         preserveViewport: true,
    +    visibilityRatio:    1,
    +    minZoomLevel:       1,
    +    defaultZoomLevel:   1,
         tileSources:   [{
             "tilesUrl":     "http://img.princeton.edu/loris",
             "identifier":   "pudl0001/4609321/s42/00000001",   
    @@ -70,7 +77,10 @@ OpenSeadragon({
         OpenSeadragon({
             id:                 "example-inline-configuration-for-iiif",
             prefixUrl:          "/openseadragon/images/",
    -        preserveViewport: true,
    +        preserveViewport:   true,
    +        visibilityRatio:    1,
    +        minZoomLevel:       1,
    +        defaultZoomLevel:   1,
             tileSources:   [{
                 "tilesUrl":     "http://img.princeton.edu/loris",
                 "identifier":   "pudl0001/4609321/s42/00000001",   
    diff --git a/www/tilesource-layers.html b/www/tilesource-layers.html
    new file mode 100644
    index 00000000..e69de29b
    diff --git a/www/tilesource-osm.html b/www/tilesource-osm.html
    new file mode 100644
    index 00000000..d92921a5
    --- /dev/null
    +++ b/www/tilesource-osm.html
    @@ -0,0 +1,62 @@
    +

    + example: openstreetmaps tiles support +

    +

    + The OpenStreetMaps is a popular tile source used by many online geographic + mapping specifications. You can read more about it at http://openstreetmaps.org/ and details about + the tile set at http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels +

    +

    + OpenSeadragon has added support for OpenStreetMaps as a tile source thanks to + Rainer Simon (http://github.com/rsimon). +

    + + +
    +

    Inline Configuration for OSM

    +

    + Inline configuration couldn't be much simpler for using OpenStreetMaps as a tile source. +

    +
    +
    +
    + Example Inline Configuration for OSM +
    +
    +
    +

    + Configuration is done via the 'tileSources' option ( or programatically ). Because of its rich + levels and depth, we slow down the zoomPerScroll option a litte, wrap horitonally, and hide the + navigator. Also we set a lower minimum zoom image ratio to allow the user to pull back just a little further. +

    +
    +OpenSeadragon({
    +    ...
    +    showNavigator:      false,
    +    wrapHorizontal:     true,
    +    zoomPerScroll:      1.2,
    +    minZoomImageRatio:  0.5,
    +    tileSources:   [{
    +        type: 'openstreetmaps'
    +    }]
    +    ...
    +});
    +
    + + diff --git a/www/tilesource-tms.html b/www/tilesource-tms.html new file mode 100644 index 00000000..d2d7cf6c --- /dev/null +++ b/www/tilesource-tms.html @@ -0,0 +1,62 @@ +

    + example: tiledmapservice support +

    +

    + The Tiled Map Service TMS tile is a tile scheme ( [ as supported by OpenLayers ] + is described here ( http://openlayers.org/dev/examples/tms.html ) ) +

    +

    + OpenSeadragon has added support for TMS tile sources thanks to + Rainer Simon (http://github.com/rsimon). +

    + + +
    +

    Inline Configuration for Tiled Map Services

    +

    + Inline configuration couldn't be much simpler for using a TMS as a tile source. +

    +
    +
    +
    + Example Inline Configuration for TMS tile sources +
    +
    +
    +

    + Configuration is done via the 'tileSources' option ( or programatically ). Because of its rich + levels and depth, we slow down the zoomPerScroll option a litte, wrap horitonally, and hide the + navigator. Also we set a lower minimum zoom pixel ratio to allow the user to pull back just a little further. +

    +
    +OpenSeadragon({
    +    ...
    +    showNavigator:      false,
    +    wrapHorizontal:     true,
    +    zoomPerScroll:      1.2,
    +    minZoomImageRatio:  0.5,
    +    tileSources:   [{
    +        type: 'openstreetmaps'
    +    }]
    +    ...
    +});
    +
    + + diff --git a/www/ui-zoom-and-pan.html b/www/ui-zoom-and-pan.html new file mode 100644 index 00000000..1d5af620 --- /dev/null +++ b/www/ui-zoom-and-pan.html @@ -0,0 +1,114 @@ +

    example: zoom and pan options

    + +

    +A deep zoom viewport allows several options to be set in order to constrain +the minimum and maximum zoom range as well as the range of panning. +

    +

    + These features are generally controlled through various combinations of + the options:

    +

    + +
    +

    Constraining by viewport visibility as a ratio.

    +

    + The option + visibilityRatio, which is by default 0.5, + ensure that you cannot pan the image far enough to fill the viewport with + more than 50% background. Setting it to 1, as in this example, ensure + the image cannot be panned so as to show any background. +

    +
    +
    +
    + A visibilityRatio of 1. +
    +
    +
    + +

    + Below is the relevant configuration. +

    +
    OpenSeadragon({
    +		...
    +        visibilityRatio: 1.0,
    +        ...
    +    });
    +
    + + +
    +

    Constraining pan direction and using a default zoom level.

    +

    + In this example we combine a number of options to produce an effect similar to + a pdf view 'fit-width'. +

    +
    +
    +
    + A visibilityRatio of 1. +
    +
    +
    + +

    + Below is the relevant configuration. +

    +
    OpenSeadragon({
    +		...
    +        panHorizontal: 		false,
    +        defaultZoomLevel: 	1,
    +        minZoomLevel: 		1,
    +        maxZoomLevel: 		1,
    +        visibilityRatio: 	1
    +        ...
    +    });
    +
    \ No newline at end of file diff --git a/www/workspace-dzi.html b/www/workspace-dzi.html new file mode 100644 index 00000000..afe6f3d4 --- /dev/null +++ b/www/workspace-dzi.html @@ -0,0 +1,82 @@ +

    + example: deep zoom image support +

    +

    + The DZI (Deep Zoom Image) format is an + xml specification maintained by Microsoft and described here. +

    +

    + OpenSeadragon has added supports for DZI format via AJAX ( XML/JSON ), JSONP, + and as inline configuration ( using the json format ). The DZI specification + does not officially describe a JSON format however the + examples below illustrate how DZI xml is mapped to json following some + simple conventions. +

    + + + + +
    +

    Inline Configuration for DZI

    +

    + Inline configuration is convenient as well because it avoids a potentially + complicated JSON/XML Ajax request over the network. Just plop the equivalent + json directly into 'tileSources' option. +

    +
    +
    +
    + Example Inline Configuration for DZI +
    +
    +
    +

    + Configuration is done via the 'tileSources' option ( or programatically ). +

    +

    + Note however the non-standard dzi property 'Url' which we must supply + explicitly since this is normally inferred by the path specified + for the dzi XML/JSON/JSONP. +

    +
    +OpenSeadragon({
    +    ...
    +    tileSources:   {
    +        Image: {
    +            xmlns:    "http://schemas.microsoft.com/deepzoom/2008",
    +            Url:      "/openseadragon/examples/images/highsmith/highsmith_files/",
    +            Format:   "jpg", 
    +            Overlap:  "2", 
    +            TileSize: "256",
    +            Size: {
    +                Height: "9221",
    +                Width:  "7026"
    +            }
    +        }
    +    }
    +    ...
    +});
    +
    + +