【问题标题】:Google Maps Tile Overlays - Avoiding 404 errors in calling tiles?Google Maps Tile Overlays - 在调用瓷砖时避免 404 错误?
【发布时间】:2012-06-11 19:02:28
【问题描述】:

当使用瓦片覆盖时,到目前为止我看到的唯一方法是在抓取瓦片时听 Google,从调用中获取 X、Y、Z 坐标,并将其与瓦片集进行比较。

var tileOptions = {
    getTileUrl: function(coord, zoom) {
        return "/tiles/" + zoom + "_" + coord.x + "_" + coord.y + ".png";
    }
}

如果 X,Y,Z 处的 tile 存在,则正常找到并调用它。如果没有,则出现 404 错误。就我而言,我有六组可能同时处于活动状态的图块,创建图块的脚本会忽略并且不会创建空白图块,这意味着每次地图更改缩放或位置时,都会出现当所有图块都尝试加载时,可能会出现超过一百个 404 错误。

为了尝试在某些方面帮助解决这个问题,我将图块搜索限制在图块覆盖的区域:

var tileOptions = {
    if (zoom>=16 && zoom<=20) {
        if (zoom=16) { if (coord.x>=16000 && coord.x<=16004) { if (coord.y>=24200 && coord.y<=24203) { 
            getTileUrl: function(coord, zoom) {
                //return the tiles
            }}}
        }
        if (zoom=17) //...
        }
        if (zoom=18) //...
        }
        //...
    }
}

但是,该区域跨越 8x10 块的区域,并没有完全被叠加层覆盖。这种方法除了只能在用户试图离开地图时防止错误外,还过于复杂,可能会减慢图块调用过程。

因此,我正在寻找一种“放置”瓷砖而不是“调用”它们的方法:而不是地图询问“你有这个瓷砖”并冒着 404 错误的风险,脚本或函数会说“我有这些图块,放置它们”忽略丢失的图块(空白),理想情况下只加载页面上可见的图块。

另外,我也在寻找一种让函数知道存在哪些图块的方法,以便它只尝试调用这些标题,从而避免 404 错误。

简而言之,如何避免调用磁贴时出现 404 错误?


写完问题后的想法:我认为第一个理想的解决方案是获取 if 语句的堆栈并将它们转换为对图块的更动态检查,如果存在图块,使用“return”来实际调用它;但是,这似乎仍然会导致相同的 404 错误,但来自不同的功能。


使用索引:正如 meetamit 建议的那样(如果我理解正确的话),首先创建一个索引来检查图块的存在/不存在,而不是调用磁贴并使用 404 作为检查。但是,使用一组“Z_X_Y.png”格式的图块,如何轻松创建这些索引?

【问题讨论】:

    标签: javascript google-maps google-maps-api-3 http-status-code-404 tiles


    【解决方案1】:

    听起来您正在扩展 ImageMapType,这需要您实现 getTileUrl() 方法。正如您所说,要“放置”而不是“调用”图块,您需要创建一个 Overlay Map Type,这本质上会更复杂,并且当您尝试做自己的事情时会更加参与描述使用 404s。

    实际上,无论您如何实现这一点,如果您依赖 404 作为图像是否存在的“测试”,您可能会通过捆绑与服务器的不必要连接而严重降低地图的性能。理想情况下(正如您所暗示的),客户端会有一些索引来表示哪些图块可用。如果索引指示磁贴不可用,您的getTileUrl() 将返回null。也就是说,假设 Google Maps API 知道不尝试加载 null url;如果不是这种情况,该方法可以返回一个透明图像的 URL,该 URL 会被缓存一次并重新用于每个丢失的图块。

    如何表示这个索引是一个选择问题。它可能是一个简单的 JSON,它可能会变得非常大(但即使是这样,每个客户端都会缓存它,以便它加载一次)。或者,您可以发挥创意并提出一种更简洁的格式来表示索引。你甚至可以预先生成一个图像,例如,代表存在或缺乏瓦片的黑白像素。然后将此图像绘制到&lt;canvas&gt; 中并从画布中读取适当的像素以确定该图块是否存在。

    在细化问题后添加到答案

    JSON 索引可能如下所示:

    var index = {
      "4": {
        xMin: 10,
        xMax: 31,
        yMin: 4,
        yMax: 11,
        tiles: [1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1 ...]
      },
      "5": {
        xMin: 5,
        xMax: 16,
        yMin: 2,
        yMax: 6,
        tiles: [1,1,1,1,0,0,1,1,1,0,0,1,1 ...]
      }
    }
    

    每个顶级对象对应于缩放级别。这样,index["5"].tiles 为您提供缩放级别 5 的所有图块。1 表示您有图块,0 表示没有图块。最小/最大值xMin, xMax, yMin, yMax 用于定义您关注的区域——因为您已经表明您的图块不会覆盖整个世界。

    要确定一个图块是否存在:

    function tileExists(z, x, y) {
      var obj = index[String(z)],
          tilesPerRow = obj.xMax - obj.xMin,
          // Calculate the index of tile within the sequential array
          iTile = (x - obj.xMin) + ((y - obj.yMin) * tilesPerRow);
    
      return Boolean(obj.tiles[iTile]);
    }
    

    同样,使用 JSON,这个索引可能会变得非常大。这取决于您所覆盖的世界范围以及缩放级别。在缩放级别 10 下,如果您覆盖整个世界,您将拥有大约 100 万个图块,这意味着一个非常大的阵列。然后您可能需要采用更压缩的格式。如何定义它取决于您。您可以将其定义为数组 [14,2,120,1,201,3] 被解释为“14 个 1,然后是 2 个 0,然后是 120 个 1,然后是 1 个零,等等……”这实际上取决于您的数据是什么样的,以及如何你愿意/能够做的很多工作。希望这有足够的帮助。

    【讨论】:

    • 索引?嗯...首先想到的是在数组/地图中定义所有可能的图块(这里不是最了解JS)并使用if层语句来检查 Z,X,Y 而不是实际调用标题来获取它。那么对于这种方法,我如何使用一组“Z_X_Y.png”格式的图块”轻松创建这些索引(复数,因为所有叠加层都略有不同)。添加问题。
    • 我理解您在这里的意思,但在这种情况下尝试手动定义 tiles: [1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1 ...] 看起来并不吸引人,尤其是当我被要求频繁更改这些磁贴时。有没有一种方法可以通过脚本或某种方法离线创建此索引,然后我可以上传并在实际的磁贴检查中参考?
    • 技术含量最低、最直接的方法是编写一些可以在浏览器中运行的 JavaScript 代码。代码将有一个大循环,尝试加载每个图块,确定它是否获得 404,相应地构建“图块定义”索引,然后使用console.log() 输出最终结果。然后,您可以将其复制/粘贴到 JSON 文件中。使用这种方法,您可以使用 jQuery 的 $.ajax 来测试 404,如下所示:$.ajax({url:'/path/to/tile', error:function() { /* add a 0 to array */ }, success:function() { /* add a 1 to array */ }}).
    • 或者,您可以为此使用命令行方法,在这种情况下,您可以使用您喜欢的任何语言/框架。如果您有兴趣,node.js 是一个非常有趣的框架,并且您可以使用 javascript 服务器端,您可能喜欢也可能不喜欢(我喜欢)。使用这种方法,您可能只需要在服务器的文件系统上查找图块 PNG 文件的存在,而不是尝试通过 HTTP 加载图块。
    猜你喜欢
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多