Map rendering with OSM and HTML5 canvas

Posted July 31, 2012 by Dave Griffiths

This week I'm trying to get as much code done on the borrowed scenery game as possible - today, fixing the map rendering. I decided to load map tiles from OpenStreetMaps directly rather than using OpenLayers. This is done quite simply, accessing the millions of pre-rendered png files with URLs in this form: a.tile.openstreetmaps.org/z/x/y.png Where x and y are the tile coordinates and z is the zoom level. The question is, given a GPS coordinate - how do you find the right tiles? Luckily the OSM siteis very helpful. This is what I'm using, where lat and lon are specified in degrees:

function latlon_to_tile(lat,lon,zoom) {
    with(Math){
        var m=pow(2,zoom);
        var lat_rad=lat*PI/180;
        return [floor((lon+180)/360*m),
                floor((1-Math.log(tan(lat_rad) + 
                       1/cos(lat_rad))/PI)/2*m)];
    }
}

I'm then doing quite a bit of work chopping the images up to create a 4x4 grid of game tiles for each map tile on the fly before the perspective transform. This brought up an issue with processing images loaded from domains other than the current server - try and do anything with the data you've loaded other than display it and this happens: Unable to get image data from canvas because the canvas has been tainted by cross-origin data.The answer is quite simple, as presumably it's quite rare for this to actually cause vulnerabilities (perhaps if executing image data in some way?) you can simple add this property to the image:

image.crossOrigin = "anonymous";

And everything works as normal, cross origin data can be treated as if you've loaded it locally. I've also spent quite a bit of time fiddling around with the scaling to make the street names visible. There will probably be some more image processing to come. I also found another MMO game that used OSM data: Monopoly City Streets.