From cb9e6a88a04383d06f7271d85c22c3257feec0db Mon Sep 17 00:00:00 2001 From: Guntis Smaukstelis Date: Tue, 18 Feb 2025 15:37:17 +0200 Subject: [PATCH] Draw latvia contour, rescale canvas --- src/main/scala/Main.scala | 2 +- web/src/harmonie/GribFile.tsx | 12 ++++++- web/src/harmonie/Harmonie.tsx | 5 ++- web/src/harmonie/draw/drawGrib.ts | 52 ++++++++++++++++++++++++++----- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/main/scala/Main.scala b/src/main/scala/Main.scala index d8045d1..bdca802 100644 --- a/src/main/scala/Main.scala +++ b/src/main/scala/Main.scala @@ -22,7 +22,7 @@ object Main extends IOApp { .flatMap(fetchService.fetchSingleFile) .flatMap { case Right((name, content)) => postgresService.save(name, content) - case Left(error) => IO.raiseError(error) + case Left(_) => IO.unit // ignore error } fetchCsvTask = scheduler.scheduleTask("Fetch CSV", List(31), fetchCsvList).compile.drain diff --git a/web/src/harmonie/GribFile.tsx b/web/src/harmonie/GribFile.tsx index e3f107d..5acf191 100644 --- a/web/src/harmonie/GribFile.tsx +++ b/web/src/harmonie/GribFile.tsx @@ -8,7 +8,7 @@ import { drawGrib } from './draw/drawGrib' import { fetchWindData, isCalculatedWindDirection } from './draw/windDirection' import { fetchHourPrecipitationData, isCalculatedHourPrecipitation } from './draw/precipitation' -const CROP_BOUNDS = { x: 1906-1-400, y: 950, width: 400, height: 300 } +const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380 } export const GribFile: Component<{ name: string, @@ -81,6 +81,16 @@ export const GribFile: Component<{ .finally(() => setIsLoading(false)) } + ///// HACK - delete this + // createEffect(() => { + // if ( + // getFileGribList().length + // && name === 'harmonie_2025-02-18T0900Z_2025-02-18T1900Z.grib' + // ) { + // onParamClick(5) + // } + // }) + return
  • onClick(name)} diff --git a/web/src/harmonie/Harmonie.tsx b/web/src/harmonie/Harmonie.tsx index 8e08e47..16ffd65 100644 --- a/web/src/harmonie/Harmonie.tsx +++ b/web/src/harmonie/Harmonie.tsx @@ -14,13 +14,16 @@ export const Harmonie: Component<{}> = () => { const [getCanvas, setCanvas] = createSignal() const [getIsLoading, setIsLoading] = createSignal(true) const [getIsCrop, setIsCrop] = createSignal(true) - const [getIsContour, setIsContour] = createSignal(false) + const [getIsContour, setIsContour] = createSignal(true) const [getGribList, setGribList] = 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') }) .finally(() => setIsLoading(false)) diff --git a/web/src/harmonie/draw/drawGrib.ts b/web/src/harmonie/draw/drawGrib.ts index e5ee46c..e19e9d5 100644 --- a/web/src/harmonie/draw/drawGrib.ts +++ b/web/src/harmonie/draw/drawGrib.ts @@ -14,6 +14,11 @@ latviaBoderImg.src = latvia_border export type CropBounds = { x: number, y: number, width: number, height: number } +/* +* final cropped size should be 1365x576px - divided by 3 (455x192) or 3.5 (390x165) +* image should be rotade 26 degrees +* currently image is 400x300px +*/ export function drawGrib( canvas: HTMLCanvasElement, messages: GribMessage[], @@ -41,8 +46,9 @@ export function drawGrib( canvas.width = cols canvas.height = rows - canvas.style.width = '100%' - canvas.style.minWidth = '1280px' + // canvas.style.width = '100%' + // canvas.style.minWidth = '1365px' + // canvas.style.border = '1px solid red' const ctx = canvas.getContext('2d')! let imgData = ctx.createImageData(cols, rows) @@ -60,10 +66,13 @@ export function drawGrib( ctx.save() ctx.scale(1, -1) ctx.drawImage(tempCanvas, 0, -canvas.height) - // ctx.drawImage(tempCanvas, 0, 0) ctx.restore() - if (isContour && !!cropBounds) { + if (cropBounds) { + drawRotate(canvas, ctx) + } + + if (isContour && cropBounds) { drawContour(canvas, ctx) // draw latvia contour only on cropped image } } @@ -147,15 +156,42 @@ function fillImageData( } } +function drawRotate( + canvas: HTMLCanvasElement, + ctx: CanvasRenderingContext2D, + angleDegrees = 26, + // angleDegrees = 0, +) { + const tempCanvas = document.createElement('canvas') + tempCanvas.width = canvas.width + tempCanvas.height = canvas.height + const tempCtx = tempCanvas.getContext('2d')! + tempCtx.save() + tempCtx.translate(tempCanvas.width/2, tempCanvas.height/2) + tempCtx.rotate(angleDegrees * Math.PI/180) + tempCtx.drawImage(canvas, -canvas.width/2, -canvas.height/2) + tempCtx.restore() + + ctx.clearRect(0, 0, canvas.width, canvas.height) + // canvas.width = 390 + // canvas.height = 165 + canvas.width = 1365 + canvas.height = 576 + ctx.save() + ctx.translate(canvas.width/2, canvas.height/2) + ctx.scale(3.5, 3.5) + ctx.drawImage(tempCanvas, -tempCanvas.width/2, -tempCanvas.height/2) + ctx.restore() +} + function drawContour( canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D, ): void { ctx.save() - ctx.translate(canvas.width/2 + 8, canvas.height/2 - 5) - const angle = -26 - ctx.rotate(angle * Math.PI / 180) - const scale = 5.3 + ctx.translate(canvas.width/2 +120, canvas.height/2 -20) + // TODO create contour image exact scale when sizes will be accepted + const scale = 5.3/3.5 const scaledWidth = latviaBoderImg.width/scale const scaledHeight = latviaBoderImg.height/scale ctx.drawImage(latviaBoderImg,