93 lines
3.2 KiB
TypeScript
93 lines
3.2 KiB
TypeScript
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<string>();
|
|
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);
|