Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting longitude latitude to tile coordinates

I want to get a map tile from a server by typing in the longitude and latitude. Since map tiles are arranged like a grid, i need to convert my longitude and latitude to an x and y position.

The algorithm is explained here: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29

I correctly implemented this algorithm, but unfortunately these are not the correct coordinates for the tileservers. As you can see here http://tools.geofabrik.de/map/#12/52.5106/13.3989&type=Geofabrik_Standard&grid=1 the correct tilecoordinates for Berlin are (2200, 1343) on zoomlevel 12, while the algorithm gives me (2645, 1894).

Where is the mistake in the algorithm or my misunderstanding of how this conversion works?

like image 503
jmlr Avatar asked May 26 '16 15:05

jmlr


People also ask

What is tile coordinate?

Pixel coordinates, which reference a specific pixel on the map at a specific zoom level. Tile coordinates, which reference a specific tile on the map at a specific zoom level.


Video Answer


2 Answers

Tilesname WebCalc seems to use the same code as presented on the slippy map tilenames wiki page and outputs the same tile names as the Geofabrik tool. So the algorithm must be correct and the error seems to be in your implementation which you didn't show us.

Oh, I'm pretty sure you just mixed up lat and lon. If I enter the coordinates in the wrong order into Tilesname WebCalc then it also returns the "wrong" tile names given in your question. So your code is fine, you just call it the wrong way.

like image 168
scai Avatar answered Sep 22 '22 11:09

scai


The following code is takes lng, lat & zoom and return X & Y values and Z is the zoom. you need to put it in url and voila you get the tile

const  EARTH_RADIUS = 6378137;
const  MAX_LATITUDE = 85.0511287798;

    function project (lat, lng)
    {
        var d = Math.PI / 180,
                max = MAX_LATITUDE,
                lat = Math.max(Math.min(max, lat), -max),
                sin = Math.sin(lat * d);
    
        return {x: EARTH_RADIUS * lng * d,
                y: EARTH_RADIUS * Math.log((1 + sin) / (1 - sin)) / 2
            };
    }
    
    
    function zoomScale (zoom)
    {
      return 256 * Math.pow(2, zoom);
    }
    
    
    function transform (point, scale) {
      scale = scale || 1;
      point.x = scale * (2.495320233665337e-8    * point.x + 0.5);
      point.y = scale * (-2.495320233665337e-8 * point.y + 0.5);
      return point;
    }
    
    var point1 = project (lat1, lng1);
    var scaledZoom = zoomScale (zoom);
    point1 = transform (point1, scaledZoom);

point1 is what you need the X & Y

like image 31
M.Hefny Avatar answered Sep 23 '22 11:09

M.Hefny