如何使用 Open Layers 下载、存储和加载图块?
How to download, store and load tiles using Open Layers?
我正在使用 Open Layers 创建 PWA。用户必须可以选择在 Wifi 上下载 Tiles 才能离线加载它们。我阅读了 Open Layers 文档,但找不到问题的答案。 Tile Cache 部分为空。
你需要三样东西才能工作:
- 用于存储图块的 IndexedDB
- 您的图块源的自定义
tileLoadFunction
- 为给定范围下载切片的组件
对于 (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;
});
对于 (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;
});
}
对于 (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);
});
}
});
});
我正在使用 Open Layers 创建 PWA。用户必须可以选择在 Wifi 上下载 Tiles 才能离线加载它们。我阅读了 Open Layers 文档,但找不到问题的答案。 Tile Cache 部分为空。
你需要三样东西才能工作:
- 用于存储图块的 IndexedDB
- 您的图块源的自定义
tileLoadFunction
- 为给定范围下载切片的组件
对于 (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;
});
对于 (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;
});
}
对于 (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);
});
}
});
});