mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
52 lines
1.7 KiB
JavaScript
52 lines
1.7 KiB
JavaScript
/** Lazy shared ecCodes WASM instance, created only for an active wind request. */
|
|
let eccodesPromise = null;
|
|
function loadEccodes() {
|
|
eccodesPromise ??= import('@meri-imperiumi/eccodes-wasm')
|
|
.then((module) => module.createEccodes())
|
|
.catch((error) => {
|
|
eccodesPromise = null;
|
|
throw error;
|
|
});
|
|
return eccodesPromise;
|
|
}
|
|
|
|
/** Decode one bounded message in WASM memory without mounting the host filesystem. */
|
|
export async function decodeWindGribMessage(buffer, { eccodesModule } = {}) {
|
|
if (buffer.byteLength > 8 * 1024 * 1024)
|
|
throw new Error('Wind GRIB exceeds byte budget');
|
|
const eccodes = eccodesModule ?? (await loadEccodes());
|
|
// Everything after this await is synchronous. A shared virtual file is safe
|
|
// across U/V and model requests and its storage is released after each decode.
|
|
const file = '/gev-wind.grib2';
|
|
let handle = null;
|
|
try {
|
|
eccodes.writeFile(file, buffer);
|
|
handle = eccodes.openGrib(file);
|
|
const ni = handle.getLong('Ni');
|
|
const nj = handle.getLong('Nj');
|
|
if (
|
|
!Number.isInteger(ni) ||
|
|
!Number.isInteger(nj) ||
|
|
ni < 1 ||
|
|
nj < 1 ||
|
|
ni * nj > 2_000_000
|
|
)
|
|
throw new Error('Invalid wind GRIB geometry');
|
|
return {
|
|
ni,
|
|
nj,
|
|
lo1: handle.getDouble('longitudeOfFirstGridPointInDegrees'),
|
|
la1: handle.getDouble('latitudeOfFirstGridPointInDegrees'),
|
|
di: handle.getDouble('iDirectionIncrementInDegrees'),
|
|
dj: handle.getDouble('jDirectionIncrementInDegrees'),
|
|
values: handle.getDoubleArray('values'),
|
|
shortName: handle.getString('shortName'),
|
|
level: handle.getLong('level'),
|
|
units: handle.getString('units'),
|
|
};
|
|
} finally {
|
|
handle?.delete();
|
|
eccodes.writeFile(file, new Uint8Array(0));
|
|
}
|
|
}
|