|
@@ -0,0 +1,75 @@
|
|
|
+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<void> {
|
|
|
+ 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<void> {
|
|
|
+ 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<boolean> {
|
|
|
+ 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<void> {
|
|
|
+ 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<void> {
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+}
|