diff --git a/web/src/harmonie/GribFile.tsx b/web/src/harmonie/GribFile.tsx index 6efca86..1188c2d 100644 --- a/web/src/harmonie/GribFile.tsx +++ b/web/src/harmonie/GribFile.tsx @@ -1,11 +1,8 @@ import { Accessor, batch, Component, createSignal, Setter, Signal } from 'solid-js' import styles from './harmonie.module.css' -import { apiHost } from '../consts' import { GribMessage } from './interfaces' -import { fetchBuffer } from '../helpers/fetch' -import { fetchWindData, isCalculatedWindDirection } from './draw/windDirection' -import { fetchHourPrecipitationData, isCalculatedHourPrecipitation } from './draw/precipitation' +import { fetchGribBinaries } from './fetchGrib' export const GribFile: Component<{ name: string, @@ -31,28 +28,8 @@ export const GribFile: Component<{ function onParamClick(paramId: number) { setIsLoading(true); const grib = getFileGribList()[paramId] - const bitmaskSection = grib.sections.find(section => section.id === 6) - const binarySection = grib.sections.find(section => section.id === 7) - if (!bitmaskSection || !binarySection) return; - const bitmaskOffset = bitmaskSection.offset + 6 - const bitmaskLength = bitmaskSection.size - 6 - const bitmaskPromise = bitmaskSection.size > 6 - ? fetchBuffer(`${apiHost}/api/grib/binary-chunk/${bitmaskOffset}/${bitmaskLength}/${name}`).then(b=>[b]) - : Promise.resolve([]) - - const binaryOffset = binarySection.offset + 5 - const binaryLength = binarySection.size - 5 - let fetchPromise: Promise<[GribMessage[], ArrayBuffer[], ArrayBuffer[]]> = Promise.all([ - Promise.resolve([grib]), - fetchBuffer(`${apiHost}/api/grib/binary-chunk/${binaryOffset}/${binaryLength}/${name}`).then(b=>[b]), - bitmaskPromise, - ]) - - if(isCalculatedWindDirection(grib)) fetchPromise = fetchWindData(grib, getFileGribList(), name) - if(isCalculatedHourPrecipitation(grib)) fetchPromise = fetchHourPrecipitationData(grib, getAllGribLists()) - - fetchPromise.then(([messages, binaryBuffers, bitmasks]) => { + fetchGribBinaries(grib, getAllGribLists()).then(([messages, binaryBuffers, bitmasks]) => { batch(() => { setCachedMessages(messages) setCachedBuffers(binaryBuffers.map(b => new Uint8Array(b))) diff --git a/web/src/harmonie/Harmonie.tsx b/web/src/harmonie/Harmonie.tsx index ebee446..cf1d24c 100644 --- a/web/src/harmonie/Harmonie.tsx +++ b/web/src/harmonie/Harmonie.tsx @@ -1,13 +1,10 @@ import { Component, createSignal } from 'solid-js' -import { apiHost } from '../consts' import { GribFile } from './GribFile' import { GribMessage } from './interfaces' -import { fetchJson } from '../helpers/fetch' -import { getFakeWindDirection, isWindSpeed } from './draw/windDirection' -import { getFakeHourPrecipitation, isPrecipitation } from './draw/precipitation' import { DrawView } from './DrawView' import { ReferenceTimes } from './ReferenceTimes' +import { fetchGribList, fetchGribListStructure } from './fetchGrib' import styles from './harmonie.module.css' @@ -23,28 +20,16 @@ export const Harmonie: Component<{}> = () => { const cachedBuffersSignal = createSignal([]) const cachedBitmasksSignal = createSignal([]) - fetchJson(`${apiHost}/api/show/grib-list`) - .then(fileList => { - fileList.sort((a: string, b: string) => a < b ? 1 : -1) - setFileList(fileList) - - // HACK - remove this - // onGribMessageClick('teeest') - }) + fetchGribList() + .then(setFileList) .finally(() => setIsLoading(false)) function getAllGribStructure() { if(!getGribList().length) { setIsLoading(true) - fetchJson(`${apiHost}/api/show/grib-all-structure`) - .then((gribList: GribMessage[]) => { - setGribList([ - ...gribList, - ...gribList.filter(isWindSpeed).map(getFakeWindDirection), - ...gribList.filter(isPrecipitation).map(getFakeHourPrecipitation), - ].sort((a, b) => a.title > b.title ? 1 : -1)) - }) - .finally(() => setIsLoading(false)) + fetchGribListStructure() + .then(setGribList) + .finally(() => setIsLoading(false)) } } diff --git a/web/src/harmonie/draw/windDirection.ts b/web/src/harmonie/draw/windDirection.ts index b0ab0b1..be1dc9d 100644 --- a/web/src/harmonie/draw/windDirection.ts +++ b/web/src/harmonie/draw/windDirection.ts @@ -145,12 +145,13 @@ export function windSpeedColors( } export function fetchWindData( - customMessage: GribMessage, - gribArr: GribMessage[], - fileName: string, + grib: GribMessage, + gribList: GribMessage[], ): Promise<[GribMessage[], ArrayBuffer[], ArrayBuffer[]]> { - const windU = gribArr.find(m => m.meteo.discipline===0 && m.meteo.category===2 && m.meteo.product===2 && m.meteo.levelType===103 && m.meteo.levelValue===10) - const windV = gribArr.find(m => m.meteo.discipline===0 && m.meteo.category===2 && m.meteo.product===3 && m.meteo.levelType===103 && m.meteo.levelValue===10) + const fileName = `harmonie_${grib.time.referenceTime}_${grib.time.forecastTime}.grib` + const sameDateGribList = gribList.filter(g => g.time.referenceTime === grib.time.referenceTime && g.time.forecastTime === grib.time.forecastTime) + const windU = sameDateGribList.find(m => m.meteo.discipline===0 && m.meteo.category===2 && m.meteo.product===2 && m.meteo.levelType===103 && m.meteo.levelValue===10) + const windV = sameDateGribList.find(m => m.meteo.discipline===0 && m.meteo.category===2 && m.meteo.product===3 && m.meteo.levelType===103 && m.meteo.levelValue===10) if (!windU || !windV) throw new Error('Didnt found u/v components of wind') const section7u = windU.sections.find(section => section.id === 7) @@ -167,7 +168,7 @@ export function fetchWindData( fetchBuffer(`${apiHost}/api/grib/binary-chunk/${uBinaryOffset}/${uBinaryLength}/${fileName}`), fetchBuffer(`${apiHost}/api/grib/binary-chunk/${vBinaryOffset}/${vBinaryLength}/${fileName}`), ]).then(([bufferU, bufferV]) => { - const messages = [customMessage, windU, windV] + const messages = [grib, windU, windV] const buffers = [bufferU, bufferU, bufferV] return [messages, buffers, []] }) diff --git a/web/src/harmonie/fetchGrib.ts b/web/src/harmonie/fetchGrib.ts new file mode 100644 index 0000000..39b6729 --- /dev/null +++ b/web/src/harmonie/fetchGrib.ts @@ -0,0 +1,54 @@ +import { apiHost } from '../consts' +import { fetchBuffer, fetchJson } from '../helpers/fetch' +import { getFakeHourPrecipitation, isPrecipitation } from './draw/precipitation' +import { getFakeWindDirection, isWindSpeed } from './draw/windDirection' +import { GribMessage } from './interfaces' +import { fetchWindData, isCalculatedWindDirection } from './draw/windDirection' +import { fetchHourPrecipitationData, isCalculatedHourPrecipitation } from './draw/precipitation' + +export function fetchGribList(): Promise { + return fetchJson(`${apiHost}/api/show/grib-list`) + .then((fileList: string[]) => { + return fileList.sort((a: string, b: string) => a < b ? 1 : -1) + }) +} + +export function fetchGribListStructure(): Promise { + return fetchJson(`${apiHost}/api/show/grib-all-structure`) + .then((gribList: GribMessage[]) => { + return [ + ...gribList, + ...gribList.filter(isWindSpeed).map(getFakeWindDirection), + ...gribList.filter(isPrecipitation).map(getFakeHourPrecipitation), + ].sort((a, b) => a.title > b.title ? 1 : -1) + }) +} + +export function fetchGribBinaries( + grib: GribMessage, + gribList: GribMessage[], +) { + const fileName = `harmonie_${grib.time.referenceTime}_${grib.time.forecastTime}.grib` + const bitmaskSection = grib.sections.find(section => section.id === 6) + const binarySection = grib.sections.find(section => section.id === 7) + if (!bitmaskSection || !binarySection) throw new Error('Grib does not have binary or bitmap section') + + const bitmaskOffset = bitmaskSection.offset + 6 + const bitmaskLength = bitmaskSection.size - 6 + const bitmaskPromise = bitmaskSection.size > 6 + ? fetchBuffer(`${apiHost}/api/grib/binary-chunk/${bitmaskOffset}/${bitmaskLength}/${fileName}`).then(b=>[b]) + : Promise.resolve([]) + + const binaryOffset = binarySection.offset + 5 + const binaryLength = binarySection.size - 5 + let fetchPromise: Promise<[GribMessage[], ArrayBuffer[], ArrayBuffer[]]> = Promise.all([ + Promise.resolve([grib]), + fetchBuffer(`${apiHost}/api/grib/binary-chunk/${binaryOffset}/${binaryLength}/${fileName}`).then(b=>[b]), + bitmaskPromise, + ]) + + if(isCalculatedWindDirection(grib)) fetchPromise = fetchWindData(grib, gribList) + if(isCalculatedHourPrecipitation(grib)) fetchPromise = fetchHourPrecipitationData(grib, gribList) + + return fetchPromise +}