将经度纬度转换为瓦片坐标

问题描述 投票:0回答:3

我想通过输入经度和纬度从服务器获取地图图块。 由于地图图块像网格一样排列,因此我需要将经度和纬度转换为 x 和 y 位置。

该算法的解释如下:http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29

我正确地实现了这个算法,但不幸的是这些不是瓦片服务器的正确坐标。 正如您在这里看到的http://tools.geofabrik.de/map/#12/52.5106/13.3989&type=Geofabrik_Standard&grid=1 柏林的正确图块坐标是缩放级别 12 上的 (2200, 1343),而算法给出的是 (2645, 1894)。

算法中的错误在哪里,或者我对这种转换如何工作的误解?

javascript dictionary coordinates openstreetmap tile
3个回答
7
投票

Tilesname WebCalc似乎使用与slippy maptilenames wiki页面上提供的相同代码,并输出与Geofabrik工具相同的图块名称。所以算法一定是正确的,错误似乎出在你的实现中,但你没有向我们展示。

哦,我很确定你只是混淆了经纬度。如果我以错误的顺序在 Tilesname WebCalc 中输入坐标,那么它也会返回您问题中给出的“错误”图块名称。所以你的代码没问题,只是你调用方式不对而已。


1
投票

以下代码采用 lng、lat 和缩放并返回 X 和 Y 值,Z 是缩放。你需要把它放在 url 中,瞧你就得到了图块

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 就是你需要的 X 和 Y


0
投票

@ wiki.openstreetmap.org提供了一些代码。

使用示例:

let lon2tile = (lon,zoom) => {  return (Math.floor((lon+180)/360*Math.pow(2,zoom)));  }
let 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))); }
 
let zoom = 12,
    latitude =  48.858,
    longitude = 2.295,
    x = lon2tile(longitude, zoom),
    y = lat2tile(latitude, zoom);

console.log( 
  zoom, x, y 
)

img.src = `https://a.tile.openstreetmap.org/${zoom}/${x}/${y}.png`
<img id="img"></img>

https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_(JavaScript/ActionScript,_etc.)

© www.soinside.com 2019 - 2024. All rights reserved.