Add per-circuit distance radius support (near: {lat, lon, miles})
Prep for a new circuit that should only show events within 500 miles of St. Louis, MO — the ID given (OlkMrRfxrN) 404s against the leagues endpoint (every other circuit ID is 12 chars, this one is 10, so it's likely missing characters from a copy/paste), so adding the actual circuit entry once that's confirmed. This part is independent and verified against known distances (Collinsville IL ~10mi, Ashland MO ~111mi, PA ~748mi from St. Louis) — a no-op for every existing circuit since `near` is optional and withinRadius() passes everything through when it's unset. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SBzcNkW7JcYipnAX6HfgmK
This commit is contained in:
@@ -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/<id>/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 };
|
||||
|
||||
Reference in New Issue
Block a user