Refactor crop bounds

This commit is contained in:
Guntis Smaukstelis
2025-02-28 13:01:08 +02:00
parent f98537b2d6
commit 38a3d1ccc3
6 changed files with 27 additions and 31 deletions
+2 -4
View File
@@ -1,11 +1,9 @@
import { Component, createEffect, createSignal, Signal } from 'solid-js' import { Component, createEffect, Signal } from 'solid-js'
import { LoadingSpinner } from '../components/LoadingSpinner' import { LoadingSpinner } from '../components/LoadingSpinner'
import { DrawOptions, GribMessage } from './interfaces' import { CROP_BOUNDS, DrawOptions, GribMessage } from './interfaces'
import { drawGrib } from './draw/drawGrib' import { drawGrib } from './draw/drawGrib'
export const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380 }
export const DrawView: Component<{ export const DrawView: Component<{
isLoadingSignal: Signal<boolean>, isLoadingSignal: Signal<boolean>,
options: DrawOptions; options: DrawOptions;
+1 -2
View File
@@ -1,9 +1,8 @@
import { Accessor, Component, createSignal, Setter, Signal } from 'solid-js' import { Accessor, Component, createSignal, Setter, Signal } from 'solid-js'
import { DrawOptions, GribMessage, MeteoParam } from './interfaces' import { CROP_BOUNDS, DrawOptions, GribMessage, MeteoParam } from './interfaces'
import { fetchGribBinaries } from './fetchGrib' import { fetchGribBinaries } from './fetchGrib'
import { drawGrib } from './draw/drawGrib' import { drawGrib } from './draw/drawGrib'
import { CROP_BOUNDS } from './DrawView'
import styles from './harmonie.module.css' import styles from './harmonie.module.css'
import { processPromisesInBatches } from '../helpers/progressivePromises' import { processPromisesInBatches } from '../helpers/progressivePromises'
+1 -2
View File
@@ -1,5 +1,4 @@
import { GribMessage } from '../interfaces' import { CropBounds, GribMessage } from '../interfaces'
import { CropBounds } from './drawGrib'
export function extractFromBounds( export function extractFromBounds(
grib: GribMessage, grib: GribMessage,
+3 -5
View File
@@ -1,5 +1,5 @@
import { interpolateColors } from '../../helpers/interpolateColors' import { interpolateColors } from '../../helpers/interpolateColors'
import { GribMessage, MeteoParam } from '../interfaces' import { CropBounds, GribMessage, MeteoParam } from '../interfaces'
import { applyBitmask } from './bitmask' import { applyBitmask } from './bitmask'
import { extractFromBounds } from './bounds' import { extractFromBounds } from './bounds'
import { categoricalRainColors } from './categoricalRain' import { categoricalRainColors } from './categoricalRain'
@@ -12,8 +12,6 @@ const latviaBoderImg = new Image()
latviaBoderImg.onload = () => console.log('latvia_contour loaded...') latviaBoderImg.onload = () => console.log('latvia_contour loaded...')
latviaBoderImg.src = latvia_border 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) * final cropped size should be 1365x576px - divided by 3 (455x192) or 3.5 (390x165)
* image should be rotade 26 degrees * image should be rotade 26 degrees
@@ -70,7 +68,7 @@ export function drawGrib(
ctx.restore() ctx.restore()
if (cropBounds) { if (cropBounds) {
drawRotate(canvas, ctx, isInterpolated) drawRotate(canvas, ctx, cropBounds.angle, isInterpolated)
} }
if (isContour && cropBounds) { if (isContour && cropBounds) {
@@ -161,8 +159,8 @@ function fillImageData(
function drawRotate( function drawRotate(
canvas: HTMLCanvasElement, canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
angleDegrees: number,
isInterpolated = false, isInterpolated = false,
angleDegrees = 26,
) { ) {
const tempCanvas = document.createElement('canvas') const tempCanvas = document.createElement('canvas')
tempCanvas.width = canvas.width tempCanvas.width = canvas.width
+17 -18
View File
@@ -5,12 +5,11 @@ import { GribMessage, MeteoConversion } from '../interfaces'
import { WIND_SPEED } from './constants' import { WIND_SPEED } from './constants'
import { rotateWind } from './windRotate' import { rotateWind } from './windRotate'
const CELL_SIZE = 12
export function windDirectionArrows( export function windDirectionArrows(
imgData: ImageData, imgData: ImageData,
messages: GribMessage[], messages: GribMessage[],
buffers: Uint8Array[], buffers: Uint8Array[],
cellSize = 16,
) { ) {
const [, metaU, metaV] = messages const [, metaU, metaV] = messages
const { conversion: convU } = metaU const { conversion: convU } = metaU
@@ -52,17 +51,17 @@ export function windDirectionArrows(
} }
} }
const gridH = Math.floor(directions.length/CELL_SIZE) const gridH = Math.floor(directions.length/cellSize)
const gridW = Math.floor(directions[0].length/CELL_SIZE) const gridW = Math.floor(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 directionAvg = true const directionAvg = true
? getAvgDirection(directions, row, col) ? getAvgDirection(directions, row, col, cellSize)
: getDirection(directions, row, col) : getDirection(directions, row, col, cellSize)
const centerX = col * CELL_SIZE + CELL_SIZE/2 const centerX = col * cellSize + cellSize/2
const centerY = row * CELL_SIZE + CELL_SIZE/2 const centerY = row * cellSize + cellSize/2
const arrowLength = CELL_SIZE*0.9 const arrowLength = cellSize*0.9
ctx.save() ctx.save()
ctx.translate(centerX, centerY) ctx.translate(centerX, centerY)
@@ -73,7 +72,7 @@ export function windDirectionArrows(
ctx.lineTo(arrowLength / 2, 0) ctx.lineTo(arrowLength / 2, 0)
ctx.stroke() ctx.stroke()
const arrowheadSize = CELL_SIZE/4 const arrowheadSize = cellSize/3.5
ctx.beginPath() ctx.beginPath()
ctx.moveTo(arrowLength / 2, 0) ctx.moveTo(arrowLength / 2, 0)
ctx.lineTo(arrowLength / 2 - arrowheadSize, -arrowheadSize / 2) ctx.lineTo(arrowLength / 2 - arrowheadSize, -arrowheadSize / 2)
@@ -88,21 +87,21 @@ export function windDirectionArrows(
return ctx.getImageData(0, 0, imgData.width, imgData.height) return ctx.getImageData(0, 0, imgData.width, imgData.height)
} }
function getDirection(directions: number[][], gridRow: number, gridCol: number) { function getDirection(directions: number[][], gridRow: number, gridCol: number, cellSize: number) {
const directionRow = gridRow * CELL_SIZE + Math.round(CELL_SIZE/2) const directionRow = gridRow * cellSize + Math.round(cellSize/2)
const directionCol = gridCol * CELL_SIZE + Math.round(CELL_SIZE/2) const directionCol = gridCol * cellSize + Math.round(cellSize/2)
return directions[directionRow][directionCol] return directions[directionRow][directionCol]
} }
// in radians // in radians
function getAvgDirection(directions: number[][], gridRow: number, gridCol: number) { function getAvgDirection(directions: number[][], gridRow: number, gridCol: number, cellSize: number) {
let sumSin = 0; // Sum of sine components let sumSin = 0; // Sum of sine components
let sumCos = 0; // Sum of cosine components let sumCos = 0; // Sum of cosine components
for (let row = 0; row < CELL_SIZE; row++) { for (let row = 0; row < cellSize; row++) {
for (let col = 0; col < CELL_SIZE; col++) { for (let col = 0; col < cellSize; col++) {
const directionRow = gridRow * CELL_SIZE + row; const directionRow = gridRow * cellSize + row;
const directionCol = gridCol * CELL_SIZE + col; const directionCol = gridCol * cellSize + col;
const directionRad = directions[directionRow][directionCol] const directionRad = directions[directionRow][directionCol]
+3
View File
@@ -51,3 +51,6 @@ export type DrawOptions = {
getIsContour: Accessor<boolean>, getIsContour: Accessor<boolean>,
getIsInterpolated: Accessor<boolean>, getIsInterpolated: Accessor<boolean>,
} }
export const CROP_BOUNDS = { x: 1906-1-440, y: 895, width: 440, height: 380, angle: 26 }
export type CropBounds = typeof CROP_BOUNDS