Automagically center a Zoomify image

804 views Asked by At

I am a newbie when it comes to programming and I was hoping y'all could help me. I am trying to automatically center a Zoomify image created through VIPS.

Unfortunately I am having a hard finding out how to center an image. If I use the example from openlayers . org http://openlayers.org/en/v3.3.0/examples/zoomify.js I end up centering in a weird way.

Is there anything I am doing wrong or a way I can automatically center the image and zoom that is based on varying image sizes?

Here is a snippet of the code I am using and funny center to make it half passable (but not robust: center: [-20000000,20000000])

var imgWidth = 41056;
var imgHeight = 16168;
var imgCenter = [imgWidth / 2, imgHeight / 2];

// Maps always need a projection, but 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.
var proj = new ol.proj.Projection({
code: 'pixel',
units: 'pixels',
extent: [0, 0, imgWidth, imgHeight]
});

var source = new ol.source.XYZ({
url: 'Zoomify_Image/1/{z}/{y}/{x}.jpg'
});

  var map = new ol.Map({
    target: 'map',
    layers: [
        new ol.layer.Tile({
            source: source,
            wrapX: false,
            projection: proj
        }),
        new ol.layer.Tile({
            source: new ol.source.TileDebug({tileGrid: new ol.tilegrid.XYZ({})}),
            wrapX: false,
            projection: proj
        })
    ],
    //renderer: exampleNS.getRendererFromQueryString(),
    view: new ol.View({
        projection: proj,
        center: [-20000000,20000000],
        zoom: 0
    })
  });
1

There are 1 answers

2
ahocevar On BEST ANSWER

Your data structure does not follow the Zoomify specification, which demands URLs in '/TileGroup{g}/{z}-{x}-{y}.jpg' format. Your URL format, 'Zoomify_Image/1/{z}/{y}/{x}.jpg' is quite a bit different from that, and I guess this is why you are using ol.source.XYZ instead of ol.source.Zoomify.

To fix your code, you will have to use ol.source.TileImage instead of ol.source.XYZ, because ol.source.XYZ currently only supports the EPSG:3857 projection. Assuming you have 7 zoom levels and your directory structure otherwise follows the Zoomify standard, but does not use clipped tiles at the boundaries of the image, your source definition could look something like this:

var source = new ol.source.TileImage({
  projection: proj,
  tileUrlFunction: function(tileCoord, pixelRatio, projection) {
    return url + 'Zoomify_Image/1/' + tileCoord[0] + '-' + tileCoord[1] +
        '-' + (-tileCoord[2] - 1) + '.jpg';
  },
  tileGrid: new ol.tilegrid.Zoomify({
    resolutions: [1, 2, 4, 8, 16, 32, 64].reverse()
  })
});

Your Tile layer definition would look like this:

new ol.layer.Tile({
  extent: [0, -imgHeight, imgWidth, 0],
  source: source
})

And finally, your View definition would look like this:

new ol.View({
  projection: proj,
  center: imgCenter,
  zoom: 0,
  extent: [0, -imgHeight, imgWidth, 0]
})

If you have tiles that are not 256x256 pixels at the image boundaries, then this approach will not work correctly - the clipped tiles will not be displayed. In this case you should change your Zoomify_Image/ directory structure to match the Zoomify standard and use ol.source.Zoomify, which supports clipped tiles.