4

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

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

如果 X,Y,Z 处的图块存在,则正常找到并调用它。如果没有,则出现 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 语句的堆栈并将它们转换为对图块的更动态检查,如果存在图块,则使用“返回”来实际调用它;但是,这似乎仍然导致相同的 404 错误,但来自不同的功能。


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

4

1 回答 1

6

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

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

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

在细化问题后添加到答案

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 个零,等等……”这实际上取决于您的数据是什么样的,以及您的工作量'愿意/能够做。希望这有足够的帮助。

于 2012-06-11T19:38:48.180 回答