如何使用OpenLayers预处理磁贴以获取日期动画

时间:2016-08-24 18:25:43

标签: javascript openlayers-3

我正在制作一段时间内具有多个图层的OpenLayers地图动画。我想预先缓存ol.layer.tile瓦片,使日期之间有平滑的过渡。有关如何预先缓存/预加载这些瓷砖的任何建议吗?

2 个答案:

答案 0 :(得分:2)

您需要依赖浏览器缓存。并且它要求您的服务器发送适当的缓存标头,因此浏览器不会在每次请求时重新获取图像。考虑到这些先决条件,请按以下步骤操作:

  1. 在您的来源上调用ol.source.TileImage#getTileUrlFunction,以便您可以计算要缓存的图块的网址。

  2. 在您的来源上调用ol.source.TileImage#getTileGrid,以便获取要缓存的范围和缩放级别的切片坐标

  3. 使用计算每个图块的网址的函数调用ol.tilegrid.TileGrid#forEachTileCoord,并将其设置为图像对象上的src。这样做时,请跟踪加载图块的数量,以便您知道何时完成。

  4. 对相应的尺寸更改后,对所有尺寸重复上述操作。

  5. 最后,您预加载单个维度的代码可能如下所示:

    var loadingCount = 0;
    var myTileUrlFunction = mySource.getTileUrlFunction();
    var myTileGrid = mySource.getTileGrid();
    myTileGrid.forEachTileCoord(myExtent, myZoom, function(tileCoord) {
      var url = myTileUrlFunction.call(mySource, tileCoord, ol.has.DEVICE_PIXEL_RATIO, myProjection);
      var img = new Image();
      img.onload = function() {
        --loadingCount;
        if (loadingCount == 0) {
          // ready to animate
        }
      }
      ++loadingCount;
      img.src = url;
    }
    

答案 1 :(得分:1)

解决缓存阻止标头的解决方案。

var i = 0;
var renderer = new ol.renderer.canvas.TileLayer(layer);
var tileSource = layer.getSource();
var datePromise = new Promise(function(resolve, reject) {
    tileGrid.forEachTileCoord(extent, currentZ, function(tileCoord) {
        tile = tileSource.getTile(tileCoord[0], tileCoord[1], tileCoord[2], pixelRatio, projection);
        tile.load();
        var loader = function(e) {
            if(e.type === 'tileloadend') {
                --i;
                if(i === 0) {
                    resolve();
                }
            } else {
                 reject(new Error('No response at this URL'));
            }
            /* remove listeners */
            this.un('tileloadend', loader);
            this.un('tileloaderror', loader);
        };
        tileSource.on('tileloadend', loader);
        tileSource.on('tileloaderror', loader);
        ++i;
    });
});