0

I am trying to create a basic image viewer using OpenLayers. I have a large image that I have split into image tiles of the Google Maps format where tiles are stored in a set of numbered directories, one for each zoom level. e.g.

Directory structure:
   /0
      /0
         0.jpg
   /1
      /0
         0.jpg  
         1.jpg
      /1
         0.jpg  
         1.jpg

I am using flask and having done some research, I am using the following code to initialise the map for an image with zoom levels 0-4:

// the image height and width values
var imgWidth = x;
var imgHeight = u;
var imgCenter = [imgWidth / 2, -imgHeight / 2];

var zoomMin = 0;
var zoomMax = 4;

var resolutions = [];
for (var i = zoomMax; i >= zoomMin; --i) {
    resolutions.push(Math.pow(2, i));
}

var extent = [0, -imgHeight, imgWidth, 0];

var view = new ol.View({
    center: ol.extent.getCenter(extent),
    zoom: zoomMin,
    resolutions: resolutions
})

var source = new ol.source.TileImage({
    url: "tiles/{z}/{x}/{y}",
    tileGrid: new ol.tilegrid.TileGrid({
        resolutions: resolutions,
        origin: [0, 0]
    })
});

var layer = new ol.layer.Tile({
    source: source,
    extent: extent
})

var map = new ol.Map({
    target: 'map',
    layers: [layer],
    view: view
});

To serve the image tiles I am using the following flask view which is retrieving the z/x/y image tile from the backend:

@app.route('/tiles')
@app.route('/tiles/<int:z>/<int:x>/<int:y>', methods=['GET'])
def tiles(z,x,y):
    file = ....
    # retrieve the file with path of z/x/y.jpg 
    return file

Running this, the first image with tile 0/0/0.jpg is displayed correctly. However, zooming in, the tiles are not in the correct order and I am getting some 404 errors for tiles that do not exist. Is there an issue with the way I am handling the tile URL? Any help would be greatly appreciated!

Gecko29
  • 179
  • 1
  • 2
  • 12
  • 1
    The resolution array is indexed by zoom level, if you use push the loop should start at zoomMin - or you could use `resolutions[i] = 1 / Math.pow(2, i);` – Mike Aug 29 '20 at 13:32
  • Hi @Mike thanks for your response! Sorry, I am a little confused, what values should the resolution array contain? – Gecko29 Aug 29 '20 at 13:52
  • 1
    If level 4 is the original large image at native resolution (and your extent is based on that size) and at zoom 0 you have compressed it into a single 256 x 256 tile you would need resolutions [16, 8, 4, 2, 1] – Mike Aug 29 '20 at 14:14
  • Ah ok I see. So my resolutions array is now containing [16,8,4,2,1] for this example image. However, the tiles are still not correctly displayed, is there something else I am missing? thanks again – Gecko29 Aug 29 '20 at 14:23
  • Hi @Mike coming back to this, I have managed to get this working now! I was just wondering if you had knowledge, or could explain the link between zoom level and magnification of a displayed image? – Gecko29 Sep 20 '20 at 12:42
  • @Mike for example if I know the original image at level 4 is 20x magnification, how do I work out the magnifications at levels 0,1,2,3 etc. – Gecko29 Sep 20 '20 at 13:13
  • 1
    Each zoom level doubles the magnification so you would have magnifications of 1.25, 2.5, 5, 10, 20, etc. Note that resolution is the inverse of magnification (each zoom level halves the resolution). – Mike Sep 20 '20 at 13:36
  • Many thanks this has helped a lot! So knowing the image magnification say 20, to display the magnification at any point I should be using the getResolution method and dividing the image magnification by this value to get the current magnification? – Gecko29 Sep 20 '20 at 14:40

0 Answers0