Skip to content

Commit

Permalink
add support for automatic minZoom and minNativeZoom resizing for cont…
Browse files Browse the repository at this point in the history
…ent bigger than window size
  • Loading branch information
mejackreed committed Feb 13, 2018
1 parent 0ac3458 commit 213a817
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 16 deletions.
4 changes: 1 addition & 3 deletions examples/iiif-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ map = L.map('map', {
});

stanfordMlk = L.tileLayer.iiif('https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/info.json', {
attribution: '<a href="http://searchworks.stanford.edu/view/hg676jb4964">Martin Luther King Jr. & Joan Baez march to integrate schools, Grenada, MS, 1966</a>',
maxZoom: 5,
tileSize: 512
attribution: '<a href="http://searchworks.stanford.edu/view/hg676jb4964">Martin Luther King Jr. & Joan Baez march to integrate schools, Grenada, MS, 1966</a>'
}).addTo(map);

princetonMap = L.tileLayer.iiif('http://libimages.princeton.edu/loris2/pudl0076%2Fmap_pownall%2F00000001.jp2/info.json', {
Expand Down
54 changes: 41 additions & 13 deletions leaflet-iiif.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,25 @@ L.TileLayer.Iiif = L.TileLayer.extend({
// Set maxZoom for map
map._layersMaxZoom = _this.maxZoom;

// Set minZoom and minNativeZoom based on how the imageSizes match up
var smallestImage = _this._imageSizes[0];
var mapSize = _this._map.getSize();
var newMinZoom = 0;
// Loop back through 5 times to see if a better fit can be found.
for (var i = 1; i <= 5; i++) {
if (smallestImage.x > mapSize.x || smallestImage.y > mapSize.y) {
smallestImage = smallestImage.divideBy(2);
_this._imageSizes.unshift(smallestImage);
newMinZoom = -i;
} else {
break;
}
}
_this.options.minZoom = newMinZoom;
_this.options.minNativeZoom = newMinZoom;
_this._prev_map_layersMinZoom = _this._map._layersMinZoom;
_this._map._layersMinZoom = newMinZoom;

// Call add TileLayer
L.TileLayer.prototype.onAdd.call(_this, map);

Expand Down Expand Up @@ -98,6 +117,8 @@ L.TileLayer.Iiif = L.TileLayer.extend({
onRemove: function(map) {
var _this = this;

map._layersMinZoom = _this._prev_map_layersMinZoom;

// Remove maxBounds set for this image
if(_this.options.setMaxBounds) {
map.setMaxBounds(null);
Expand All @@ -112,7 +133,8 @@ L.TileLayer.Iiif = L.TileLayer.extend({

// Find best zoom level and center map
var initialZoom = _this._getInitialZoom(_this._map.getSize());
var imageSize = _this._imageSizes[initialZoom];
var offset = _this._imageSizes.length - 1 - _this.options.maxNativeZoom;
var imageSize = _this._imageSizes[initialZoom + offset];
var sw = _this._map.options.crs.pointToLatLng(L.point(0, imageSize.y), initialZoom);
var ne = _this._map.options.crs.pointToLatLng(L.point(imageSize.x, 0), initialZoom);
var bounds = L.latLngBounds(sw, ne);
Expand Down Expand Up @@ -177,6 +199,7 @@ L.TileLayer.Iiif = L.TileLayer.extend({
// Calculates maximum native zoom for the layer
_this.maxNativeZoom = Math.max(ceilLog2(_this.x / _this.options.tileSize),
ceilLog2(_this.y / _this.options.tileSize));
_this.options.maxNativeZoom = _this.maxNativeZoom;

// Enable zooming further than native if maxZoom option supplied
if (_this._customMaxZoom && _this.options.maxZoom > _this.maxNativeZoom) {
Expand Down Expand Up @@ -236,11 +259,15 @@ L.TileLayer.Iiif = L.TileLayer.extend({
return this._infoToBaseUrl() + '{region}/{size}/{rotation}/{quality}.{format}';
},
_isValidTile: function(coords) {
var _this = this,
zoom = _this._getZoomForUrl(),
sizes = _this._tierSizes[zoom],
x = coords.x,
y = (coords.y);
var tileBounds = this._tileCoordsToBounds(coords);
var _this = this;
var zoom = _this._getZoomForUrl();
var sizes = _this._tierSizes[zoom];
var x = coords.x;
var y = coords.y;
if (zoom < 0 && x >= 0 && y >= 0) {
return true;
}

if (!sizes) return false;
if (x < 0 || sizes[0] <= x || y < 0 || sizes[1] <= y) {
Expand All @@ -250,14 +277,15 @@ L.TileLayer.Iiif = L.TileLayer.extend({
}
},
_getInitialZoom: function (mapSize) {
var _this = this,
tolerance = 0.8,
imageSize;

for (var i = _this.maxNativeZoom; i >= 0; i--) {
imageSize = this._imageSizes[i];
var _this = this;
var tolerance = 0.8;
var imageSize;
// Calculate an offset between the zoom levels and the array accessors
var offset = _this._imageSizes.length - 1 - _this.options.maxNativeZoom;
for (var i = _this._imageSizes.length - 1; i >= 0; i--) {
imageSize = _this._imageSizes[i];
if (imageSize.x * tolerance < mapSize.x && imageSize.y * tolerance < mapSize.y) {
return i;
return i - offset;
}
}
// return a default zoom
Expand Down
41 changes: 41 additions & 0 deletions spec/LTileLayerIiifSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@ describe('L.TileLayer.Iiif', function() {
it('initializes the map', function(){
expect(typeof (map)).toEqual('object');
});

describe('onAdd', function() {
beforeEach(function() {
iiifLayer = iiifLayerFactory();
});

afterEach(function() {
iiifLayer.off('load');
});

it('with a fitable tileSize', function(done) {
map.addLayer(iiifLayer);
iiifLayer.on('load', function() {
expect(iiifLayer.options.minZoom).toBe(0);
expect(iiifLayer.options.minNativeZoom).toBe(0);
done();
});
});

it('with a large tileSize tries to best fit size by setting minNativeZoom and minZoom', function(done) {
var largeTileSize = L.tileLayer.iiif('http://localhost:9876/base/fixtures/cantaloupe/info.json');
map.addLayer(largeTileSize);
largeTileSize.on('load', function() {
expect(largeTileSize.options.minZoom).toBe(-2);
expect(largeTileSize.options.minNativeZoom).toBe(-2);
expect(largeTileSize._prev_map_layersMinZoom).toBe(0)
done();
});
});
});

describe('generated tile urls', function() {
var iiifLayer;
Expand Down Expand Up @@ -81,6 +111,17 @@ describe('L.TileLayer.Iiif', function() {
});
});

it('with a large tile size', function(done) {
var largeTileSize = L.tileLayer.iiif('http://localhost:9876/base/fixtures/cantaloupe/info.json');
map.addLayer(largeTileSize);
largeTileSize.on('load', function() {
expect(largeTileSize.options.fitBounds).toBe(true);
expect(map.getBounds().getSouthWest().toString()).toBe('LatLng(-1956, -592)');
expect(map.getBounds().getNorthEast().toString()).toBe('LatLng(444, 2608)');
done();
});
});

it('can be configured not to be on', function(done) {
var iiifLayerNoFitBounds = iiifLayerFactory({ fitBounds: false });
map.addLayer(iiifLayerNoFitBounds);
Expand Down
83 changes: 83 additions & 0 deletions spec/fixtures/cantaloupe/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"@context": "http://iiif.io/api/image/2/context.json",
"@id": "http://127.0.0.1:8182/iiif/2/IMG_1707.JPG",
"protocol": "http://iiif.io/api/image",
"width": 4032,
"height": 3024,
"sizes": [
{
"width": 126,
"height": 95
},
{
"width": 252,
"height": 189
},
{
"width": 504,
"height": 378
},
{
"width": 1008,
"height": 756
},
{
"width": 2016,
"height": 1512
}
],
"tiles": [
{
"width": 2016,
"height": 1512,
"scaleFactors": [
1,
2,
4,
8,
16,
32
]
}
],
"profile": [
"http://iiif.io/api/image/2/level2.json",
{
"formats": [
"tif",
"jpg",
"gif",
"png"
],
"maxArea": 400000000,
"qualities": [
"bitonal",
"default",
"gray",
"color"
],
"supports": [
"sizeByW",
"regionByPx",
"sizeByWhListed",
"cors",
"regionSquare",
"sizeByDistortedWh",
"sizeAboveFull",
"canonicalLinkHeader",
"sizeByConfinedWh",
"sizeByPct",
"jsonldMediaType",
"regionByPct",
"sizeByH",
"rotationArbitrary",
"baseUriRedirect",
"rotationBy90s",
"profileLinkHeader",
"sizeByForcedWh",
"sizeByWh",
"mirroring"
]
}
]
}

0 comments on commit 213a817

Please sign in to comment.