index.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import * as FileSystem from 'expo-file-system';
  2. const baseTilesDir = `${FileSystem.cacheDirectory}tiles/`;
  3. const MAP_HOST = 'https://maps.nomadmania.eu';
  4. interface TileType {
  5. url: string;
  6. type: string;
  7. maxZoom: number;
  8. }
  9. async function ensureDirExists(dirPath: string): Promise<void> {
  10. const dirInfo = await FileSystem.getInfoAsync(dirPath);
  11. if (!dirInfo.exists) {
  12. await FileSystem.makeDirectoryAsync(dirPath, { intermediates: true });
  13. }
  14. }
  15. async function downloadTile(z: number, x: number, y: number, tile: TileType): Promise<void> {
  16. try {
  17. const tileUrl = `${MAP_HOST}${tile.url}/${z}/${x}/${y}`;
  18. const filePath = `${baseTilesDir}${tile.type}/${z}/${x}/${y}`;
  19. await FileSystem.downloadAsync(tileUrl, filePath);
  20. } catch (error) {
  21. console.error(`Error downloading tile ${z}/${x}/${y} for ${tile.type}:`, error);
  22. }
  23. }
  24. async function checkTilesExistence(tileType: TileType): Promise<boolean> {
  25. const dirPath = `${baseTilesDir}${tileType.type}/`;
  26. const MIN_SIZE_BYTES = 1024 * 512;
  27. try {
  28. const fileInfo = await FileSystem.getInfoAsync(dirPath, { size: true });
  29. return fileInfo.exists && fileInfo.size < MIN_SIZE_BYTES;
  30. } catch (error) {
  31. console.error(`Error fetching directory size: ${dirPath}:`, error);
  32. return true;
  33. }
  34. }
  35. async function downloadTiles(tileType: TileType): Promise<void> {
  36. await ensureDirExists(`${baseTilesDir}${tileType.type}/`);
  37. const tilesExist = await checkTilesExistence(tileType);
  38. if (tilesExist) {
  39. for (let z = 2; z <= tileType.maxZoom; z++) {
  40. const maxTile = Math.pow(2, z);
  41. for (let x = 0; x < maxTile; x++) {
  42. const dirPath = `${baseTilesDir}${tileType.type}/${z}/${x}`;
  43. await ensureDirExists(dirPath);
  44. for (let y = 0; y <= maxTile; y++) {
  45. await downloadTile(z, x, y, tileType);
  46. }
  47. }
  48. }
  49. }
  50. }
  51. export async function initTilesDownload(userId: string): Promise<void> {
  52. let tileTypes: TileType[] = [
  53. {url: '/tiles_osm', type: 'background', maxZoom: 5},
  54. {url: '/tiles_nm/grid', type: 'grid', maxZoom: 5},
  55. {url: '/tiles_nm/regions_mqp', type: 'regions_mqp', maxZoom: 4},
  56. ];
  57. userId && tileTypes.push({url: `/tiles_nm/user_visited/${userId}`, type: 'user_visited', maxZoom: 3});
  58. for (const type of tileTypes) {
  59. await downloadTiles(type);
  60. }
  61. }