import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; import { getBoundaryFromGpkg } from '../src/gpkg-reader.js'; import { readFileSync, existsSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const continentData = JSON.parse( readFileSync(join(__dirname, '../data/gadm_continent.json'), 'utf-8') ); async function processCountry(country: string, level: number | undefined) { if (level !== undefined) { console.log(`Processing ${country} at level ${level}...`); await doProcess(country, level); } else { console.log(`Processing ${country} for all levels (0-5)...`); for (let l = 0; l <= 5; l++) { await doProcess(country, l); } } } async function doProcess(country: string, level: number | undefined) { const levelStr = level !== undefined ? level.toString() : 'auto'; const safeCountry = country.replace(/[^a-zA-Z0-9\.\-_]/g, '_').substring(0, 50); const expectedFile = join(__dirname, '../cache/gadm', `boundary_${safeCountry}_${levelStr}.json`); if (existsSync(expectedFile)) { console.log(`⏭️ ${country} (L${level ?? 0}): Skipped, already cached.`); return; } try { const start = Date.now(); const res = await getBoundaryFromGpkg(country, level); const duration = Date.now() - start; if (res && res.features && res.features.length > 0) { console.log(`✅ ${country} (L${level ?? 0}): Successfully cached in ${duration}ms (${res.features.length} features).`); } else { console.log(`❌ ${country} (L${level ?? 0}): No boundary found.`); } } catch (e: any) { console.error(`❌ ${country} (L${level ?? 0}): Failed - ${e.message}`); } } async function main() { const argv = await yargs(hideBin(process.argv)) .option('country', { type: 'string', description: 'ISO 3 code of the country (e.g. DEU, ESP), or "all" for all countries', demandOption: true, alias: 'c' }) .option('level', { type: 'number', description: 'The administrative level to calculate. Omit for the outer boundary.', alias: 'l' }) .help() .argv; const country = argv.country as string; const level = argv.level as number | undefined; if (country.toLowerCase() === 'all') { // Collect all countries const allCountries = new Set(); for (const codes of Object.values(continentData)) { for (const code of codes as string[]) { allCountries.add(code); } } console.log(`Starting precalculation for ${allCountries.size} countries at level ${level ?? 'outer'}...`); let current = 1; for (const code of allCountries) { console.log(`\n[${current}/${allCountries.size}]`); await processCountry(code, level); current++; } console.log('\n🎉 Finished precalculating all countries.'); } else { await processCountry(country.toUpperCase(), level); } } main().catch(console.error);