问题
How do I deepzoom into OpenLayers images using Zoomify?
Taking cues from the answer How to display high resolution image in browser using openlayers, I was able to implement the zooming function but the maxZoom does not work here and I am unable zoom further into the image.
DZI image parser
function loadUrl(url, opt_options) {
const options = opt_options || {};
const crossOrigin =
options.crossOrigin === undefined ? 'anonymous' : options.crossOrigin;
const layer = new ol.layer.Tile();
const last = url.lastIndexOf('.');
const path = url.slice(0, last);
const xhr = new XMLHttpRequest();
let width;
let height;
xhr.open('GET', url);
xhr.onload = function() {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xhr.responseText, 'text/xml');
const elements = xmlDoc.getElementsByTagName('Image');
const tileSize = Number(elements[0].getAttribute('TileSize'));
const format = elements[0].getAttribute('Format');
width = Number(
elements[0].getElementsByTagName('Size')[0].getAttribute('Width')
);
height = Number(
elements[0].getElementsByTagName('Size')[0].getAttribute('Height')
);
const url = `${path}_files/{z}/{x}_{y}.${format}`;
const source = new ol.source.Zoomify({
url,
size: [width, height],
tileSize,
crossOrigin
});
const offset = Math.ceil(Math.log(tileSize) / Math.LN2);
source.setTileUrlFunction(function(tileCoord) {
return url
.replace('{z}', tileCoord[0] + offset)
.replace('{x}', tileCoord[1])
.replace('{y}', -(tileCoord[2] + 1));
});
layer.setExtent([0, -height, width, 0]);
layer.setSource(source);
};
xhr.send();
return {
layer,
width,
height
};
}
Map Object
const map = new ol.Map({
target: 'map',
logo: false
});
const { layer } = loadUrl(
'https://openseadragon.github.io/example-images/duomo/duomo.dzi'
);
layer.on('change:source', function(evt) {
map.setView(
new ol.View({
resolutions: layer.getSource().getTileGrid().getResolutions(),
extent: layer.getExtent(),
zoom: 5,
maxZoom: 30
})
);
map.getView().fit(layer.getExtent(), { size: map.getSize() });
});
map.addLayer(layer);
How do I remove the zoom constraints?
回答1:
I have figured it out.
Code for the same:
function loadUrl(url) {
return new Promise(resolve => {
const layer = new ol.layer.Tile();
const last = url.lastIndexOf('.');
const path = url.slice(0, last);
const xhr = new XMLHttpRequest();
let width = 0;
let height = 0;
xhr.open('GET', url);
xhr.onload = () => {
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xhr.responseText, 'text/xml');
const elements = xmlDoc.getElementsByTagName('Image');
const tileSize = Number(elements[0].getAttribute('TileSize'));
const format = elements[0].getAttribute('Format');
width = Number(
elements[0].getElementsByTagName('Size')[0].getAttribute('Width')
);
height = Number(
elements[0].getElementsByTagName('Size')[0].getAttribute('Height')
);
const formattedUrl = `${path}_files/{z}/{x}_{y}.${format}`;
const offset = Math.ceil(Math.log(tileSize) / Math.LN2);
return resolve({
url: formattedUrl,
offset,
layer,
imgWidth: width,
imgHeight: height,
tileSize
});
};
xhr.send();
});
}
function run(url, imgWidth, imgHeight, offset, tileSize) {
const imgCenter = [imgWidth / 2, -imgHeight / 2];
// Maps always need a projection, but Zoomify layers are not geo-referenced, and
// are only measured in pixels. So, we create a fake projection that the map
// can use to properly display the layer.
const proj = new ol.proj.Projection({
code: 'ZOOMIFY',
units: 'pixels',
extent: [0, 0, imgWidth, imgHeight]
});
const layer = new ol.layer.Tile({
source: new ol.source.Zoomify({
url,
size: [imgWidth, imgHeight],
tileSize,
crossOrigin: 'anonymous'
})
});
layer.getSource().setTileUrlFunction(tileCoord => {
return url
.replace('{z}', tileCoord[0] + offset)
.replace('{x}', tileCoord[1])
.replace('{y}', -(tileCoord[2] + 1));
});
const map = new ol.Map({
layers: [layer],
target: 'map',
view: new ol.View({
projection: proj,
center: imgCenter,
zoom: 0,
extent: [0, -imgHeight, imgWidth, 0]
})
});
}
const nwurl =
'https://openseadragon.github.io/example-images/duomo/duomo.dzi';
loadUrl(nwurl).then(res => {
const { url, offset, imgWidth, imgHeight, tileSize } = res;
run(url, imgWidth, imgHeight, offset, tileSize);
});
来源:https://stackoverflow.com/questions/58498434/deepzoom-into-openlayers-images-using-zoomify