diff --git a/sites/events/src/main.js b/sites/events/src/main.js index 46f5fb0..3d4d89f 100644 --- a/sites/events/src/main.js +++ b/sites/events/src/main.js @@ -41,6 +41,12 @@ loadHTML('/footer.html', 'footer'); entries here; the page builds one section per circuit. `id` is the leagueId from a circuit's BCP calendar URL, e.g. bestcoastpairings.com/circuit//calendar + + Optional `near: { lat, lon, miles }` restricts a circuit to only + events within that radius (great-circle distance) — a fixed + property of the circuit itself, unlike the Format/Scope toggles + which the viewer controls. Events with no coordinate data are + excluded rather than assumed to be in range. ============================================================ */ const CONFIG = { circuits: [ @@ -51,6 +57,27 @@ const CONFIG = { ], }; +// St. Louis, MO — reference point for circuits restricted by distance. +const ST_LOUIS = { lat: 38.6270, lon: -90.1994 }; + +// Great-circle distance in miles between two lat/lon points (haversine). +function milesBetween(lat1, lon1, lat2, lon2) { + const R = 3958.8; + const toRad = d => (d * Math.PI) / 180; + const dLat = toRad(lat2 - lat1); + const dLon = toRad(lon2 - lon1); + const a = Math.sin(dLat / 2) ** 2 + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) ** 2; + return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); +} + +function withinRadius(ev, near) { + if (!near) return true; + const coord = ev.coordinate; // BCP gives [lon, lat] + if (!Array.isArray(coord) || coord.length !== 2) return false; + const [lon, lat] = coord; + return milesBetween(lat, lon, near.lat, near.lon) <= near.miles; +} + /* ---- BCP API ---- */ const API = "https://newprod-api.bestcoastpairings.com/v1"; const HEADERS = { "client-id": "web-app", "env": "bcp", "accept": "application/json" }; @@ -265,7 +292,8 @@ async function load() { allResults = await Promise.all( CONFIG.circuits.map(async circuit => { try { - return { circuit, events: await fetchUpcomingEvents(circuit.id) }; + const events = await fetchUpcomingEvents(circuit.id); + return { circuit, events: events.filter(ev => withinRadius(ev, circuit.near)) }; } catch (err) { console.error("Failed to load circuit", circuit.id, err); return { circuit, events: [], error: true };