# Image tiling math

I've been looking at MapTiler for the logic on how to render an image as tiles on a (google) map. Instead of storing the single tiles locally in a folder structure I want to use Djatoka. I'm able to create single tiles with Djatoka, but I'm still trying to figure out on how to render these tiles on a map. In the html file MapTiler creates I see some math to do this, but I dont fully understand yet.

``````var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
``````

Do all these values represent pixels? How should I read the resolution (res) value?

``````bounds.left = -8900327.232731644
this.maxExtent.left = -20037508
res = 2.388657133483887
this.tileSize.w = 256
``````

How do I loop over these tiles to render an image only if it's represented within the view frame?

EDIT: I guess I'm trying to convert the Open Layers logic for image tiling (TMS?) to a google solution?

-
Have you seen maptiler.org/google-maps-coordinates-tile-bounds-projection? An excellent resource that goes a long way to explaining the tiling scheme and how it works, with python code included. – Kelso Mar 30 '12 at 2:52

When rendering a TMS layer, OpenLayers cuts the area you are currently viewing into rectangles of the size tilewidth x tileheight, so you should set the tilewidth and tileheight to the actual size of your tiles when you create the TMS layer.

Now, for every such rectangle in your viewport, it calls a function (usually named `getTileUrl(bounds)`), which receives a `bounds` object (specifying the rectangle bounds) as an argument and should return the corresponding tile's url (you are going to write that function and pass it as an argument when creating the TMS layer).

So, suppose your TMS layer is covering the map in such a way that the first tile is positioned exactly in the lower left corner of the map (its lower left corner is identical to the lower left corner of the map). Unless specified otherwise, OpenLayers supposes this is true (i.e. the tileOrigin point is identical to the lower left point of mapExtent). Furthermore, let's assume that the tiles are named for example R0C0.png, R0C1.png, R0C2.png for the first row of tiles, then R1C0.png, R1C2.png, R2C2.png for the second row etc.

Now, for a given `bounds` object that specifies the rectangle OpenLayers is asking about, how do you compute the name of the tile which should be there? You just need to find out what row is it in (let it be y), what column is it in (let it be x) and then you just return the name RyCx.png.

So, how to find out the x? The first tile should begin at the leftmost (westernmost) border of the map. The x coordinate (or longitude, according to your projection) of the leftmost border of your map is stored in `this.mapExtent.left`. This tile is `this.tileSize.w` wide in pixels, and if the resolution is `res`, it is `this.tileSize.w * res` geographic units wide on the map. By geographic units I mean degrees for example, or any other unit your projection uses. The resolution is the ratio `geographic units on the map / pixels on the screen`.

So, if the first tile starts at `this.mapExtent.left` and it is `this.tileSize.w * res` wide, then the next tile starts at `this.mapExtent.left + this.tileSize.w * res`, the next one at `this.mapExtent.left + 2 * this.tileSize.w * res`, another one at `this.mapExtent.left + 3 * this.tileSize.w * res` etc.

So, apparently, if you get the bounds of an area which corresponds to a tile and you want to know the `x`, i.e. in which column of the TMS grid the tile is, you use the formula

`x = (bounds.left - this.maxExtent.left) / (res * this.tileSize.w)`

Similarily, you use

`y = (bounds.top - this.maxExtent.top) / (res * this.tileSize.h)`

(or you can negate the difference in the numerator - it depends on whether the first row is the top row or the bottom row).

Eh... It's 2am here, so this could be far from comprehensible. Well... I just hope it will.

-
That's an amazing reply! Thanks Imp. I realize my question was very broad (google, open layers, djatoka, etc), but this helped me quite a bit in understanding tiling in open layers and how it handles tiling. – Danny_Joris Mar 31 '12 at 2:20

i dont totally understand what you want but if you want to get resolution for given zoom level you can use this code:

``````import math

tileSize = 256
initialResolution = 2 * math.pi * 6378137 / tileSize

def Resolution( zoom ):
"Resolution (meters/pixel) for given zoom level (measured at Equator)"

# return (2 * math.pi * 6378137) / (tileSize * 2**zoom)
return initialResolution / (2 ** zoom)
``````

you can find lots of thing in gdal2tiles.py

i hope it helps you

-
Thanks for your reply. Unfortunately this is a bit over my head. I'm not even sure why I need resolution for my tile calculations and how I should understand the value for resolution (2.388657133483887). – Danny_Joris Mar 29 '12 at 14:47
for calculating tile bounds you need resolution for zoom level. if you dont consider this in calculation you will get wrong tile for tms scheme... – Aragon Mar 29 '12 at 15:41
I still don't understand what resolution really means in this context. Also are numbers like this (-8900327.232731644) pixels relative to the map bounds? I can't find any information on how an image grid overlay should look like or how it should be calculated. – Danny_Joris Mar 29 '12 at 16:12