/** * One-time script: geocodes the existing KNOWN_SCHOOLS list to create * an initial src/data/schools.json. Run once, then use fetch-schools.ts * with Airtable for ongoing updates. */ import { readFileSync, writeFileSync, mkdirSync } from "fs"; import { join, dirname } from "path"; import { fileURLToPath } from "url"; const __dirname = dirname(fileURLToPath(import.meta.url)); // Parse the school names from schools.ts const schoolsTs = readFileSync(join(__dirname, "..", "src", "data", "schools.ts"), "utf-8"); const match = schoolsTs.match(/\[([^\]]+)\]/s); const schools = match ? match[1] .split(",") .map((s) => s.trim().replace(/^"|"$/g, "").replace(/^'|'$/g, "")) .filter(Boolean) : []; console.log(`Found ${schools.length} schools to geocode`); async function geocode(query) { const params = new URLSearchParams({ q: query + ", Australia", format: "json", limit: "1", countrycodes: "au", }); const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, { headers: { "User-Agent": "micromelon-website-seed/1.0" }, }); if (!res.ok) return null; const data = await res.json(); if (!data.length) return null; return { lat: parseFloat(data[0].lat), lng: parseFloat(data[0].lon) }; } async function main() { const pins = []; for (let i = 0; i < schools.length; i++) { await new Promise((r) => setTimeout(r, 1100)); const coords = await geocode(schools[i]); if (coords) { pins.push(coords); process.stdout.write(` ${i + 1}/${schools.length} — ${pins.length} geocoded\r`); } else { console.log(` MISS: ${schools[i]}`); } } console.log(`\nDone: ${pins.length} geocoded out of ${schools.length}`); const outDir = join(__dirname, "..", "src", "data"); mkdirSync(outDir, { recursive: true }); writeFileSync(join(outDir, "schools.json"), JSON.stringify(pins, null, 2) + "\n"); console.log("Wrote src/data/schools.json"); } main().catch(console.error);