Search code examples
javascriptopenstreetmap

Longitude, Latitude to OSM pixel in 256x256 Tile


OpenStreetMap (OSM) have a Tile server. A tile is a 256x256 image of the world in a specific zoom.

I have longitude and latitude and I can find the correct tile by using this function.

function long2tile(lon,zoom) {return (Math.floor((lon+180)/360*Math.pow(2,zoom))); }
function lat2tile(lat,zoom)  { return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom))); }
var zoom = 4;
var x= long2tile(13.393562,zoom);
var y = lat2tile(52.519582,zoom);
document.getElementById('a').src='https://tile.openstreetmap.org/'+zoom+'/'+ x+'/'+y+'.png';
<img src="" id="a" style="border:1px solid black"/>

My problem is that Id like to know what coordinate in the 256x256 pixel is the location i set.

How to get the x-y coordiaten inside this one tile?


Solution

  • The rounding makes the difference!

    function lo2t(lon,zoom){
        return (lon+180)/360*Math.pow(2,zoom);
    }
    function la2t(lat,zoom){
        return (1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom);
    }
    function long2tile(lon,zoom) {return Math.floor(lo2t(lon,zoom)); }
    function lat2tile(lat,zoom)  {return Math.floor(la2t(lat,zoom)); }
    function long2tfac(lon,zoom) {
        return long2tile(lon,zoom)-lo2t(lon,zoom);
    }
    function lat2tfac(lat,zoom) {
        return lat2tile(lat,zoom)-la2t(lat,zoom);
    }
    var zoom = 4;
    var x= long2tile(13.393562,zoom);
    var y = lat2tile(52.519582,zoom);
    document.getElementById('a').src='https://tile.openstreetmap.org/'+zoom+'/'+ x+'/'+y+'.png';
    var point = document.getElementById('point');
    var pos=";"; pos+="left:"+long2tfac(13.393562,zoom)*-256;
     pos+="px;top:"+lat2tfac(52.519582,zoom)*-256;
     point.setAttribute('style',point.getAttribute('style')+pos+'px;');
    <img src="" id="a" style="border:1px solid black"/>
    <div id="point" style="display:block; position:absolute; width:30px; height:30px; border:1px solid black; border-radius:15px;">&nbsp;</div>