谷歌地图平铺叠加 - 避免调用瓷砖404错误?

时间:2012-06-11 19:02:28

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

当使用图块叠加时,我到目前为止看到的唯一方法是在抓取图块时收听Google,从调用中获取X,Y,Z坐标,并将其与图块集进行比较。 / p>

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

如果X,Y,Z处的图块存在,则会找到并正常调用。如果没有,则会出现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错误。

简而言之,我如何在调用tile时避免404错误?


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


使用索引:正如下面提出的meetamit (如果我理解正确的话),创建一个索引来检查磁贴的存在/不存在而不是调用磁贴并使用404作为检查。但是,使用“Z_X_Y.png”格式的一组切片,我怎样才能轻松创建这些索引?

1 个答案:

答案 0 :(得分:6)

听起来像是在扩展ImageMapType,这需要您实现getTileUrl()方法。如你所说,要“放置”而不是“调用”瓷砖,你需要创建一个Overlay Map Type,这本身就更具参与性,并且当你试图做你做的事情时会更加参与'描述使用404s。

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

如何表示此索引是一个选择问题。它可能是一个简单的JSON,可能会变得非常大(但即使如此,每个客户端都会缓存它以便它一次加载)。或者,您可以获得创意并提出更简洁的格式来表示索引。您甚至可以预先生成一个图像,例如,表示存在或缺少图块的黑白像素。然后,您将此图像绘制到<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 0,等等......”这实际上取决于你的数据是什么样的,以及你愿意/能做多少工作。希望这足够了。