Openlayers 5服务于本地MBTiles

时间:2019-03-22 08:49:10

标签: typescript openlayers-5 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中检索切片时,它停止了工作。我尝试了各种代码组合,但均未按预期工作。

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

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

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

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

1 个答案:

答案 0 :(得分:0)

这是我发现可以使其工作的解决方案。

显然,问题不在于对异步函数的调用,而是我为将正确的参数传递给异步函数而对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'
});