import * as FileSystem from 'expo-file-system'; const baseTilesDir = `${FileSystem.cacheDirectory}tiles/`; const MAP_HOST = 'https://maps.nomadmania.eu'; interface TileType { url: string; type: string; maxZoom: number; } async function ensureDirExists(dirPath: string): Promise { const dirInfo = await FileSystem.getInfoAsync(dirPath); if (!dirInfo.exists) { await FileSystem.makeDirectoryAsync(dirPath, { intermediates: true }); } } async function downloadTile(z: number, x: number, y: number, tile: TileType): Promise { try { const tileUrl = `${MAP_HOST}${tile.url}/${z}/${x}/${y}`; const filePath = `${baseTilesDir}${tile.type}/${z}/${x}/${y}`; await FileSystem.downloadAsync(tileUrl, filePath); } catch (error) { console.error(`Error downloading tile ${z}/${x}/${y} for ${tile.type}:`, error); } } async function checkTilesExistence(tileType: TileType): Promise { const dirPath = `${baseTilesDir}${tileType.type}/`; const MIN_SIZE_BYTES = 1024 * 512; try { const fileInfo = await FileSystem.getInfoAsync(dirPath, { size: true }); return fileInfo.exists && fileInfo.size < MIN_SIZE_BYTES; } catch (error) { console.error(`Error fetching directory size: ${dirPath}:`, error); return true; } } async function downloadTiles(tileType: TileType): Promise { await ensureDirExists(`${baseTilesDir}${tileType.type}/`); const tilesExist = await checkTilesExistence(tileType); if (tilesExist) { for (let z = 2; z <= tileType.maxZoom; z++) { const maxTile = Math.pow(2, z); for (let x = 0; x < maxTile; x++) { const dirPath = `${baseTilesDir}${tileType.type}/${z}/${x}`; await ensureDirExists(dirPath); for (let y = 0; y <= maxTile; y++) { await downloadTile(z, x, y, tileType); } } } } } export async function initTilesDownload(userId: string): Promise { let tileTypes: TileType[] = [ {url: '/tiles_osm', type: 'background', maxZoom: 5}, {url: '/tiles_nm/grid', type: 'grid', maxZoom: 5}, {url: '/tiles_nm/regions_mqp', type: 'regions_mqp', maxZoom: 4}, ]; userId && tileTypes.push({url: `/tiles_nm/user_visited/${userId}`, type: 'user_visited', maxZoom: 3}); for (const type of tileTypes) { await downloadTiles(type); } }