如何使用 Open Layers 下载、存储和加载图块?

Lan*_*rad 5 javascript openlayers ecmascript-6

I'm creating a PWA using Open Layers. The user must have an option to download the Tiles on the Wifi to load them Offline. I read the Open Layers documentation, but, I couldn't find the answer for my problem. The section Tile Cache is empty.

aho*_*var 10

要使其发挥作用,您需要三件事:

  1. 用于存储图块的 IndexedDB
  2. tileLoadFunction为您的图块源定制
  3. 下载给定范围内的切片的组件

对于 (1),您需要建立一家商店,例如tiles。下面的代码片段使用 idb 包(https://npmjs.com/package/idb):

import idb from 'idb';

let indexedDb;

idb.open(this.name, 1, upgradeDb => {
  if (!upgradeDb.objectStoreNames.contains('tiles')) {
    upgradeDb.createObjectStore('tiles');
  }
}).then(db => {
  indexedDb = db;
});
Run Code Online (Sandbox Code Playgroud)

对于 (2),起点可能如下所示:

source.setTileLoadFunction(function(tile, url) {
  const tx = db.transaction('tiles', 'readonly');
  tiles = tx.objectStore('tiles');
  const image = tile.getImage();

  tiles.get(url).then(blob => {
    if (!blob) {
      // use online url
      image.src = url;
      return;
    }
    const objUrl = URL.createObjectURL(blob);
    image.onload = function() {
      URL.revokeObjectURL(objUrl);
    };
    image.src = objUrl;
  }).catch(() => {
    // use online url
    image.src = url;
  });
}
Run Code Online (Sandbox Code Playgroud)

对于 (3),您可能希望将下载限制在较小范围内。然后,对于所选的extent(以地图单位为单位)和zoom要缓存的每个级别,执行如下操作:

const tilegrid = source.getTileGrid();
const projection = map.getView().getProjection();
const getUrl = source.getTileUrlFunction();
tilegrid.forEachTileCoord(extent, zoom, tilecoord => {
  const url = getUrl(tilecoord, devicePixelRatio, projection);
  fetch(url).then(response => {
    if (response.ok) {
      response.blob().then(blob => {
        const tx = db.transaction('tiles', 'readwrite');
        const tiles = tx.objectStore('tiles');
        tiles.put(url, blob);
      });
    }
  });
});
Run Code Online (Sandbox Code Playgroud)