Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retrieve LayerPoint (X, Y) from Latitude and Longitude coordinates using Leaflet API

If I use the following code to get the LayerPoint from a specified Lat/Lng:

var latLng = new L.latLng(-37.81303878836989, 144.97421264648438);
var point = map.latLngToLayerPoint(latLng);

The output is the following:

o.Point
  x: 86042
  y: 77065

Then when I try to access the layer tile using the following URL:

http://a.tile.osm.org/10/86042/77065.png

I get a 404 because it's an invalid X, Y.

Now, if I use the following code:

map.on("click", function (e) {
    console.log(e);
});

I can retrieve the LayerPoint in the console alongside the latitude and longitude.

latlng: o.LatLng
  lat: -37.81303878836989
  lng: 144.97421264648438
layerPoint: o.Point
  x: 950
  y: 303

Then accessing the following URL returns this layer tile:

http://a.tile.osm.org/10/950/303.png

enter image description here

The problem is that it doesn't even seem to be the correct tile for that latitude longitude nor does my original code to convert lat lng to LayerPoint actually return a valid X, Y in the first place.

I'm very confused as to why I'm getting these results. Any help would be greatly appreciated. Perhaps I'm doing something wrong.

I'm not sure whether there's another way of retrieving tile layers based on a list of latitude and longitudes?

The reason why I'm after this is because I want to be able to use cached tile data for an Offline application and the only data I have are geometry/coordinates via a GeoJSON payload that is generated for the client-side application.

UPDATE:

Ended up going with this function (thanks to @scai).

According to this link.

var getSlippyTileLayerPoints = function (lat_deg, lng_deg, zoom) {
    var x = (Math.floor((lng_deg + 180) / 360 * Math.pow(2, zoom)));
    var y = (Math.floor((1 - Math.log(Math.tan(lat_deg * Math.PI / 180) + 1 / Math.cos(lat_deg * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom)));

    var layerPoint = {
        x: x,
        y: y
    };

    return layerPoint;
};

OUTPUT:

Object {x: 924, y: 628}

http://a.tile.osm.org/10/924/628.png

enter image description here

UPDATE 2:

After further research, it turns out what I was after is the following function:

var layerPoint = map.project(latlng).divideBy(256).floor();
console.log(layerPoint.x, layerPoint.y);
like image 927
fulvio Avatar asked Feb 26 '14 05:02

fulvio


2 Answers

After further research, it turns out what I was after is the following function:

var layerPoint = map.project(latlng).divideBy(256).floor();
console.log(layerPoint.x, layerPoint.y);
like image 180
fulvio Avatar answered Oct 11 '22 11:10

fulvio


OSM's tile URLs are based on a different scheme. You should read about slippy map tile names in the OSM wiki. It contains implementations for lon/lat to tile numbers and vice versa for various programming/scripting languages.

like image 43
scai Avatar answered Oct 11 '22 10:10

scai