Openlayers 5 обслуживают местные MBTiles - PullRequest
0 голосов
/ 22 марта 2019

Я пытаюсь подавать плитки из местного .mbtiles в проекте Ionic 4.

Шаг за шагом мне удалось скачать 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, она перестала работать. Я пробовал разные комбинации кода, но ни один из них не работал так, как ожидалось.

Я мог заметить, что это потому, что tileLoadFunction не ожидает асинхронного вызова базы данных sqlite и не отображает изображение, когда оно еще пусто. Например, если я использую этот код с функцией getTile, возвращающей Promise, он не работает.

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

Дело в том, что он входит в then и выполняет локальный код, и строка base64, которую я получаю, я знаю, является правильной. Очевидно, что openlayers рендерит плитку до того, как разрешится getTile.

Я также узнал, что событие tileloaderror отправляется для каждой плитки, но я не знаю, как я мог бы использовать ее как преимущество.

1 Ответ

0 голосов
/ 22 марта 2019

Это решение, которое я нашел, чтобы заставить его работать.

Очевидно, проблема была не в вызове асинхронной функции, а в вызове функции getTileCoord, которую я делал, чтобы передать правильный параметрасинхронная функция.Я не знаю , почему это произошло, но удаление этого вызова и изменение его путем вычисления координат из параметра url tileLoadFunction решило проблему.

Полученный код выглядит следующим образом

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'
});
...