【问题标题】:How to get Latitude and Longitude Bounds from Google Maps x y and zoom parameters如何从谷歌地图 x y 和缩放参数中获取纬度和经度界限
【发布时间】:2014-06-20 21:29:39
【问题描述】:

我见过一些标题相似的问题,但它们似乎指的是xy 像素坐标。

我从谷歌地图getTile() 函数中询问xy 的实际图块编号:

澄清问题...

给定 getTile() 函数中的 x、y 和缩放参数,我如何找到图块的纬度和经度边界?

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   
}

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

我想到的替代方案是创建图像并检查 src url 是否有错误(这对我来说似乎是一个糟糕的主意,因为我会提出许多错误的请求来检查图像是否存在)。

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

编辑:

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

【问题讨论】:

  • 为什么投反对票?我在措辞和准备这个问题方面非常努力。

标签: javascript google-maps google-maps-api-3


【解决方案1】:

我认为 Google 地图平铺系统类似于 Bings 地图平铺系统。瓦片从左上角到右下角开始,每个瓦片是 256x256:http://msdn.microsoft.com/en-us/library/bb259689.aspx

【讨论】:

    【解决方案2】:

    假设使用墨卡托投影的基本谷歌地图和 256x256 的 tileSize:

    每个(x 轴和 y 轴)上的图块数为 Math.pow(2,zoom),因此缩放时 0 地图使用 1 个图块,缩放时 1 4 个图块,缩放时 2 16瓷砖等等。

    首先计算图块的西南/东北点。

    图块的大小(以磅为单位)为256/Math.pow(2,zoom)

    西南点:

    x = tile.x * tileSizeInPoints
    y = (tile.y * tileSizeInPoints) + tileSizeInPoints
    

    北东点:

    x = (tile.x * tileSizeInPoints) + tileSizeInPoints
    y = tile.y * tileSizeInPoints
    

    这些点必须转换为 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;
      }
    
    }
    

    通过提供具有以下格式的单个对象作为参数来调用MERCATOR.getTileBounds()

    {
     x:tileIndexX,
     y:tileIndexY,
     z:zoom 
    }
    

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

    【讨论】:

    • 谢谢,我很欣赏所有这些信息。
    • 传单瓷砖怎么样?
    猜你喜欢
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多