diff --git a/web/src/harmonie/DrawView.tsx b/web/src/harmonie/DrawView.tsx index 8466c5b..3e0d1de 100644 --- a/web/src/harmonie/DrawView.tsx +++ b/web/src/harmonie/DrawView.tsx @@ -4,23 +4,23 @@ import { LoadingSpinner } from '../components/LoadingSpinner' import { DrawOptions, GribMessage } from './interfaces' import { drawGrib } from './draw/drawGrib' -const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380 } +export const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380 } export const DrawView: Component<{ isLoadingSignal: Signal, options: DrawOptions; + canvasSignal: Signal, cachedMessagesSignal: Signal, cachedBuffersSignal: Signal, cachedBitmasksSignal: Signal, }> = ({ isLoadingSignal: [getIsLoading, setIsLoading], options, + canvasSignal: [getCanvas, setCanvas], cachedMessagesSignal: [getCachedMessages], cachedBuffersSignal: [getCachedBuffers], cachedBitmasksSignal: [getCachedBitmasks], }) => { - const [getCanvas, setCanvas] = createSignal() - createEffect(async () => { setIsLoading(true) const canvas = getCanvas()! diff --git a/web/src/harmonie/GribFile.tsx b/web/src/harmonie/GribFile.tsx index 1188c2d..f08f62a 100644 --- a/web/src/harmonie/GribFile.tsx +++ b/web/src/harmonie/GribFile.tsx @@ -32,8 +32,8 @@ export const GribFile: Component<{ fetchGribBinaries(grib, getAllGribLists()).then(([messages, binaryBuffers, bitmasks]) => { batch(() => { setCachedMessages(messages) - setCachedBuffers(binaryBuffers.map(b => new Uint8Array(b))) - setCachedBitmasks(bitmasks.map(b => new Uint8Array(b))) + setCachedBuffers(binaryBuffers) + setCachedBitmasks(bitmasks) }) }) .catch(err => console.warn(err.message)) diff --git a/web/src/harmonie/Harmonie.tsx b/web/src/harmonie/Harmonie.tsx index cf1d24c..632f543 100644 --- a/web/src/harmonie/Harmonie.tsx +++ b/web/src/harmonie/Harmonie.tsx @@ -7,6 +7,7 @@ import { ReferenceTimes } from './ReferenceTimes' import { fetchGribList, fetchGribListStructure } from './fetchGrib' import styles from './harmonie.module.css' +import { SlideShow } from './SlideShow' export const Harmonie: Component<{}> = () => { const [getFileList, setFileList] = createSignal([]) @@ -15,6 +16,8 @@ export const Harmonie: Component<{}> = () => { const [getIsContour, setIsContour] = createSignal(true) const [getIsInterpolated, setIsInterpolated] = createSignal(true) const [getGribList, setGribList] = createSignal([]) + const [getCanvas, setCanvas] = createSignal() + const [getImgList, setImgList] = createSignal<[string, ImageBitmap][]>([]) const cachedMessagesSignal = createSignal([]) const cachedBuffersSignal = createSignal([]) @@ -62,8 +65,12 @@ export const Harmonie: Component<{}> = () => { setIsInterpolated(!getIsInterpolated())} />
    @@ -82,9 +89,14 @@ export const Harmonie: Component<{}> = () => {
+ , getFileList: Accessor, getGribList: Accessor, + getCanvas: Accessor, + options: DrawOptions, + setImgList: Setter<[string, ImageBitmap][]>, onClick: () => void, }> = ({ + setIsLoading, getFileList, getGribList, + getCanvas, + options, + setImgList, onClick, }) => { const [getActiveDate, setActiveDate] = createSignal('') @@ -24,13 +36,50 @@ export const ReferenceTimes: Component<{ setActiveDate(newValue) } + async function getImgList(dateStr: string) { + setIsLoading(true) + const canvas = getCanvas()! + const cropBounds = options.getIsCrop() ? CROP_BOUNDS : undefined + const contour = options.getIsContour() + const isInterpolated = options.getIsInterpolated() + const forecastList = getGribList() + .filter(g => g.time.referenceTime === dateStr) + .filter(g => g.meteo.discipline === 0 && g.meteo.category === 1 && g.meteo.product === 192) + // .slice(0, 5) // TODO remove this + const promiseList = forecastList.map(async (grib): Promise<[string, ImageBitmap]> => { + const [messages, buffers, bitmasks] = await fetchGribBinaries(grib, getGribList()) + drawGrib(canvas, messages, buffers, bitmasks, cropBounds, contour, isInterpolated) + // just to be sure that draws + await new Promise(resolve => setTimeout(resolve)) + const img = await createImageBitmap(canvas) + return [grib.time.forecastTime, img] + }) + + Promise.all(promiseList) + .then(imgList => { + imgList.sort((a, b) => a[0] > b[0] ? 1 : -1) + console.log(imgList) + setImgList(imgList) + }) + .finally(() => { + const ctx = canvas.getContext('2d')! + ctx.clearRect(0, 0, canvas.width, canvas.height) + setIsLoading(false) + }) + + } + return
    { dateList().map(dateStr =>
  • onActiveDate(dateStr)}> { dateStr }
    -
    +
    getImgList(dateStr)} + > { getGribList().some(g => g.time.referenceTime === dateStr) && <>TODO: download all forecasts diff --git a/web/src/harmonie/SlideShow.tsx b/web/src/harmonie/SlideShow.tsx new file mode 100644 index 0000000..46b569d --- /dev/null +++ b/web/src/harmonie/SlideShow.tsx @@ -0,0 +1,30 @@ +import { Accessor, Component } from 'solid-js' + +import styles from './harmonie.module.css' + +export const SlideShow: Component<{ + getCanvas: Accessor, + getImgList: Accessor<[string, ImageBitmap][]>, +}> = ({ + getCanvas, + getImgList +}) => { + function draw(img: ImageBitmap) { + const canvas = getCanvas()! + const ctx = canvas.getContext('2d')! + ctx.clearRect(0, 0, canvas.width, canvas.height) + ctx.drawImage(img, 0, 0) + } + + return
      + { getImgList().map(([forecastDate, img]) => +
    • draw(img)}> + { format(forecastDate) } +
    • )} +
    +} + +function format(date: string) { + return date.slice(11, 13) + // return date +} \ No newline at end of file diff --git a/web/src/harmonie/fetchGrib.ts b/web/src/harmonie/fetchGrib.ts index 39b6729..91781a3 100644 --- a/web/src/harmonie/fetchGrib.ts +++ b/web/src/harmonie/fetchGrib.ts @@ -27,7 +27,7 @@ export function fetchGribListStructure(): Promise { export function fetchGribBinaries( grib: GribMessage, gribList: GribMessage[], -) { +): Promise<[GribMessage[], Uint8Array[], Uint8Array[]]> { 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) @@ -51,4 +51,9 @@ export function fetchGribBinaries( if(isCalculatedHourPrecipitation(grib)) fetchPromise = fetchHourPrecipitationData(grib, gribList) return fetchPromise + .then(([messages, buffers, bitmasks]) => [ + messages, + buffers.map(b => new Uint8Array(b)), + bitmasks.map(b => new Uint8Array(b)), + ]) } diff --git a/web/src/harmonie/harmonie.module.css b/web/src/harmonie/harmonie.module.css index 64d4028..49c5294 100644 --- a/web/src/harmonie/harmonie.module.css +++ b/web/src/harmonie/harmonie.module.css @@ -68,4 +68,9 @@ .dateList li .controls { padding: 10px 3px; +} + +.slideShow li { + display: inline; + padding: 3px 5px; } \ No newline at end of file