mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-12 14:22:21 +00:00
merge: integrate ECMWF IFS PR #464 with bounded model switching
This commit is contained in:
commit
26354d5ae1
16 files changed
+444
-182
No files matched your search
@@ -88,3 +88,34 @@ export async function fetchRange({
|
||||
throw new Error('invalid range length');
|
||||
return buffer;
|
||||
}
|
||||
|
||||
import { GFS_BUCKET, gfsObjectKey, selectLatestGfsCycle, nearestGfsStep } from './catalog.js';
|
||||
import { decodeWindGribMessage } from './decode.js';
|
||||
import { resampleWindGrid } from './grid.js';
|
||||
|
||||
/** Fetch and decode the GFS 10 m wind field valid closest to now. */
|
||||
export async function fetchGfsWind({ fetchImpl = fetch, now = () => Date.now(), targetDx = 1, decodeImpl = decodeWindGribMessage, signal } = {}) {
|
||||
const nowMs = now();
|
||||
const cycle = selectLatestGfsCycle(nowMs);
|
||||
const runMs = Date.UTC(
|
||||
Number(cycle.date.slice(0, 4)),
|
||||
Number(cycle.date.slice(4, 6)) - 1,
|
||||
Number(cycle.date.slice(6, 8)),
|
||||
cycle.hour,
|
||||
);
|
||||
// Pick the forecast step whose valid time is closest to now, so the layer
|
||||
// shows the freshest field the cycle offers instead of the analysis.
|
||||
const forecastHour = nearestGfsStep((nowMs - runMs) / 3600_000);
|
||||
const base = `https://${GFS_BUCKET}.s3.amazonaws.com/${gfsObjectKey({ ...cycle, forecastHour })}`;
|
||||
const index = await fetchText({ url: `${base}.idx`, fetchImpl, signal });
|
||||
const ranges = windMessageRanges(parseGfsIdx(index.toString()));
|
||||
const [uBuffer, vBuffer] = await Promise.all([
|
||||
fetchRange({ url: base, ...ranges.u, fetchImpl, signal }),
|
||||
fetchRange({ url: base, ...ranges.v, fetchImpl, signal }),
|
||||
]);
|
||||
const [u, v] = await Promise.all([decodeImpl(uBuffer), decodeImpl(vBuffer)]);
|
||||
const grid = resampleWindGrid({ u: u.values, v: v.values, ni: u.ni, nj: u.nj, lo1: u.lo1, la1: u.la1, di: u.di, dj: u.dj, dx: targetDx, dy: targetDx });
|
||||
const runIso = new Date(runMs).toISOString();
|
||||
const validIso = new Date(runMs + forecastHour * 3600_000).toISOString();
|
||||
return { cycle: { ...cycle, forecastHour, runIso, validIso }, level: '10 m above ground', units: 'm/s', grid };
|
||||
}
|
||||
Reference in new issue
Block a user