Wind direction arrows draw after background scale rotate

This commit is contained in:
Guntis Smaukstelis
2025-02-28 22:45:01 +02:00
parent 38a3d1ccc3
commit 4bd3733781
2 changed files with 55 additions and 34 deletions
+29 -17
View File
@@ -52,23 +52,16 @@ export function drawGrib(
let imgData = ctx.createImageData(cols, rows) let imgData = ctx.createImageData(cols, rows)
fillImageData(imgData, messages, modifiedBuffers, isInterpolated) fillImageData(imgData, messages, modifiedBuffers, isInterpolated)
if (isCalculatedWindDirection(grib)) { ctx.putImageData(imgData, 0, 0)
imgData = windDirectionArrows(imgData, messages, modifiedBuffers) flipCanvasV(canvas, ctx)
}
const tempCanvas = document.createElement('canvas')
const tempCtx = tempCanvas.getContext('2d')!
tempCanvas.width = imgData.width
tempCanvas.height = imgData.height
tempCtx.putImageData(imgData, 0, 0)
ctx.save()
ctx.scale(1, -1)
ctx.drawImage(tempCanvas, 0, -canvas.height)
ctx.restore()
if (cropBounds) { if (cropBounds) {
drawRotate(canvas, ctx, cropBounds.angle, isInterpolated) drawRotate(canvas, ctx, cropBounds.angle, isInterpolated, 3.5)
}
if (isCalculatedWindDirection(grib)) {
const directionArrows = windDirectionArrows(messages, modifiedBuffers, cols, rows, cropBounds)
ctx.drawImage(directionArrows, 0, 0)
} }
if (isContour && cropBounds) { if (isContour && cropBounds) {
@@ -156,11 +149,30 @@ function fillImageData(
} }
} }
function drawRotate( export function flipCanvasV(
canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D,
) {
const tmpCanvas = document.createElement('canvas')!
const tmpCtx = tmpCanvas.getContext('2d')!
tmpCanvas.width = canvas.width
tmpCanvas.height = canvas.height
tmpCtx.save()
tmpCtx.scale(1, -1)
tmpCtx.drawImage(canvas, 0, -canvas.height)
tmpCtx.restore()
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(tmpCanvas, 0, 0)
}
export function drawRotate(
canvas: HTMLCanvasElement, canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
angleDegrees: number, angleDegrees: number,
isInterpolated = false, isInterpolated = false,
scale = 1,
) { ) {
const tempCanvas = document.createElement('canvas') const tempCanvas = document.createElement('canvas')
tempCanvas.width = canvas.width tempCanvas.width = canvas.width
@@ -186,7 +198,7 @@ function drawRotate(
} }
ctx.save() ctx.save()
ctx.translate(canvas.width/2, canvas.height/2) ctx.translate(canvas.width/2, canvas.height/2)
ctx.scale(3.5, 3.5) ctx.scale(scale, scale)
ctx.drawImage(tempCanvas, -tempCanvas.width/2, -tempCanvas.height/2) ctx.drawImage(tempCanvas, -tempCanvas.width/2, -tempCanvas.height/2)
ctx.restore() ctx.restore()
} }
+26 -17
View File
@@ -1,27 +1,26 @@
import { apiHost } from '../../consts' import { apiHost } from '../../consts'
import { fetchBuffer } from '../../helpers/fetch' import { fetchBuffer } from '../../helpers/fetch'
import { valueToColorInterpolated, valueToColorThreshold } from '../../helpers/interpolateColors' import { valueToColorInterpolated, valueToColorThreshold } from '../../helpers/interpolateColors'
import { GribMessage, MeteoConversion } from '../interfaces' import { CropBounds, GribMessage, MeteoConversion } from '../interfaces'
import { WIND_SPEED } from './constants' import { WIND_SPEED } from './constants'
import { drawRotate, flipCanvasV } from './drawGrib'
import { rotateWind } from './windRotate' import { rotateWind } from './windRotate'
export function windDirectionArrows( export function windDirectionArrows(
imgData: ImageData,
messages: GribMessage[], messages: GribMessage[],
buffers: Uint8Array[], buffers: Uint8Array[],
cellSize = 16, cols: number,
) { rows: number,
cropBounds: CropBounds | undefined,
): HTMLCanvasElement {
const cellSize = cropBounds ? 21 : 16
const scale = cropBounds ? 3.5 : 1
// const scale = 1
const [, metaU, metaV] = messages const [, metaU, metaV] = messages
const { conversion: convU } = metaU const { conversion: convU } = metaU
const { conversion: convV } = metaV const { conversion: convV } = metaV
const [, bufferU, bufferV] = buffers const [, bufferU, bufferV] = buffers
const cols = imgData.width
const rows = imgData.height
const canvas = document.createElement('canvas')
canvas.width = imgData.width
canvas.height = imgData.height
const ctx = canvas.getContext('2d')!
ctx.putImageData(imgData, 0, 0) // draw wind speed color below direction
const directions: number[][] = [] const directions: number[][] = []
const bytesPerPoint = metaU.bitsPerDataPoint/8 const bytesPerPoint = metaU.bitsPerDataPoint/8
@@ -51,13 +50,20 @@ export function windDirectionArrows(
} }
} }
const gridH = Math.floor(directions.length/cellSize) const canvas = document.createElement('canvas')!
const gridW = Math.floor(directions[0].length/cellSize) const ctx = canvas.getContext('2d')!
canvas.width = cols * scale
canvas.height = rows * scale
const gridH = Math.floor(scale * directions.length/cellSize)
const gridW = Math.floor(scale * directions[0].length/cellSize)
for (let row = 0; row < gridH; row++) { for (let row = 0; row < gridH; row++) {
for (let col = 0; col < gridW; col++) { for (let col = 0; col < gridW; col++) {
const directionCol = Math.floor(col/scale)
const directionRow = Math.floor(row/scale)
const directionAvg = true const directionAvg = true
? getAvgDirection(directions, row, col, cellSize) ? getAvgDirection(directions, directionRow, directionCol, cellSize)
: getDirection(directions, row, col, cellSize) : getDirection(directions, directionRow, directionCol, cellSize)
const centerX = col * cellSize + cellSize/2 const centerX = col * cellSize + cellSize/2
const centerY = row * cellSize + cellSize/2 const centerY = row * cellSize + cellSize/2
@@ -83,8 +89,11 @@ export function windDirectionArrows(
ctx.restore() ctx.restore()
} }
} }
flipCanvasV(canvas, ctx)
return ctx.getImageData(0, 0, imgData.width, imgData.height) if (cropBounds) {
drawRotate(canvas, ctx, cropBounds.angle, true)
}
return canvas
} }
function getDirection(directions: number[][], gridRow: number, gridCol: number, cellSize: number) { function getDirection(directions: number[][], gridRow: number, gridCol: number, cellSize: number) {