Openlayers 5 服务本地 MBTiles

Openlayers 5 serve local MBTiles

我正在尝试在 Ionic 4 项目中提供来自本地 .mbtiles 的图块。

一步一步,我设法下载了 mbtiles 并使用 XYZ

成功创建了源
new XYZ({
  tileLoadFunction: (tile: ImageTile, url) => {
    //stuff
  },
  tileUrlFunction: (c) => {
    return c[0] + '/' + c[1] + '/' + c[2];
  },
  projection: 'EPSG:3857'
});

基本上,如果我将以下行添加到 //stuff 它会起作用(我以表示绿色方块的基本 base64 字符串为例)

tile.getImage().setAttribute('src', 'base 64 string here');

但是当我尝试使用 SQLite 从 mbtiles 中检索图块时,它停止工作了。我尝试了各种代码组合,但 none 按预期工作。

我注意到这是因为 tileLoadFunction 不等待对 SQLite 数据库的异步调用并在图像仍然为空时渲染图像。例如,如果我将此代码与返回 Promise 的 getTile 函数一起使用,则它不起作用。

getTile(tile.getTileCoord()).then((base64) => {
  tile.getImage().setAttribute('src', base64);
})

事实是它进入then并执行本地代码和我知道的base64字符串是正确的。显然 OpenLayers 正在 getTile 解析之前渲染图块。

我还发现 tileloaderror 事件是为每个图块调度的,但我不知道如何利用它作为优势。

这是我找到的解决方案。

显然问题不在于对异步函数的调用,而是对 getTileCoord 函数的调用,我正在这样做以将正确的参数传递给异步函数。我不知道为什么会发生这种情况,但删除该调用并更改它计算 tileLoadFunction 的 url 参数的坐标解决了问题。

生成的代码如下所示

new XYZ({
  tileLoadFunction: (tile: any, url) => {
    let coords: [number, number, number] = [0, 0, 0];
    let tmp: string[] = url.split('/');
    for (let i in tmp) {
      coords[i] = parseInt(tmp[i]);
    }
    coords[2] = -coords[2]; // the y coordinates is negative
    this.storageService.getTile(coords).then(function (tileBase64: string) {
      tile.getImage().src = tileBase64;
    });
  },
  tileUrlFunction: (c) => {
    return c[0] + '/' + c[1] + '/' + c[2];
  },
  projection: 'EPSG:3857'
});