如何从Google Maps xy和缩放参数获取纬度和经度界限

Dou*_*sar 5 javascript google-maps google-maps-api-3

我已经看到了类似的标题了一些问题,但他们似乎是指xy像素坐标.

我问的实际片号xy从谷歌地图getTile()功能:

澄清问题......

给定getTile()函数中的x,y和zoom参数,如何找到tile的纬度和经度范围?

CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {

    var x = coord.x,
    y = coord.y,
    url = "http://mt1.google.com/vt/lyrs=y&x="+x+"&y="+y+"&z="+zoom;
    //other stuff   
}
Run Code Online (Sandbox Code Playgroud)

目前我需要这个的唯一原因是我想确定此图块投影的最大缩放级别.从这个链接:最大缩放,它指出,为了找到最大缩放,我将需要使用纬度和经度值getMaxZoomAtLatLng().因此,如果我可以获得边界,那么我可以使用边界内的任何纬度和经度点来找到我的最大缩放.

我想到的替代品是创建一个图像并检查src url是否有错误(这对我来说似乎是一个可怕的想法,因为我会做出很多不好的请求只是为了检查图像是否存在).

var img = new Image;
img.onload = function() {/*imagery exists*/ }
img.onerror = function() {/*past maximum zoom*/ }
img.src = url;
Run Code Online (Sandbox Code Playgroud)

编辑:

经过进一步调查,我发现该getMaxZoomAtLatLng()函数正在使用ajax调用,这不适合我的计划.但我仍然对如何找到给定图块的纬度和经度边界感兴趣(这可能对其他应用程序有用).

Dr.*_*lle 11

假设使用mercator-projection和tilexize为256x256的基本google-map:

每个(x轴和y轴)上的平铺数量是Math.pow(2,zoom),因此在缩放时0,地图使用1个平铺,放大14个平铺,放大216个平铺等等.

首先计算瓷砖的西南/东北点.

瓷砖的大小(以磅为单位)是 256/Math.pow(2,zoom)

西南点:

x = tile.x * tileSizeInPoints
y = (tile.y * tileSizeInPoints) + tileSizeInPoints
Run Code Online (Sandbox Code Playgroud)

东北点:

x = (tile.x * tileSizeInPoints) + tileSizeInPoints
y = tile.y * tileSizeInPoints
Run Code Online (Sandbox Code Playgroud)

这些点必须转换为LatLngs.使用地图时,您可以使用地图投影的fromLatLngToPoint方法.

有关自定义实施,请查看https://developers.google.com/maps/documentation/javascript/examples/map-coordinates.

可能的API独立实现:

MERCATOR={

  fromLatLngToPoint:function(latLng){
     var siny =  Math.min(Math.max(Math.sin(latLng.lat* (Math.PI / 180)), 
                                   -.9999),
                          .9999);
     return {
      x: 128 + latLng.lng * (256/360),
      y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI))
     };
  },

  fromPointToLatLng: function(point){

     return {
      lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) -
             Math.PI / 2)/ (Math.PI / 180),
      lng:  (point.x - 128) / (256 / 360)
     };

  },

  getTileAtLatLng:function(latLng,zoom){
    var t=Math.pow(2,zoom),
        s=256/t,
        p=this.fromLatLngToPoint(latLng);
        return {x:Math.floor(p.x/s),y:Math.floor(p.y/s),z:zoom};
  },

  getTileBounds:function(tile){
    tile=this.normalizeTile(tile);
    var t=Math.pow(2,tile.z),
        s=256/t,
        sw={x:tile.x*s,
            y:(tile.y*s)+s},
        ne={x:tile.x*s+s,
            y:(tile.y*s)};
        return{sw:this.fromPointToLatLng(sw),
               ne:this.fromPointToLatLng(ne)
              }
  },
  normalizeTile:function(tile){
    var t=Math.pow(2,tile.z);
    tile.x=((tile.x%t)+t)%t;
    tile.y=((tile.y%t)+t)%t;
    return tile;
  }

}
Run Code Online (Sandbox Code Playgroud)

MERCATOR.getTileBounds()通过使用以下格式提供单个对象作为参数进行调用:

{
 x:tileIndexX,
 y:tileIndexY,
 z:zoom 
}
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/doktormolle/55Nke/