From 439593578875026501e0fd7cb90d90762d1d87a4 Mon Sep 17 00:00:00 2001 From: b0txec Date: Sat, 22 Aug 2026 21:04:39 +0300 Subject: [PATCH] =?UTF-8?q?Calibrate=20Br=C4=ABdin=C4=81jumi=20projection?= =?UTF-8?q?=20to=20validated=20city=20pixel=20positions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/pages/warnings/warningDraw.ts | 4 ++-- web/src/pages/warnings/warningTemplates.ts | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/web/src/pages/warnings/warningDraw.ts b/web/src/pages/warnings/warningDraw.ts index 4e753e4..ddcc992 100644 --- a/web/src/pages/warnings/warningDraw.ts +++ b/web/src/pages/warnings/warningDraw.ts @@ -83,8 +83,8 @@ function drawWarning(ctx: CanvasRenderingContext2D, template: WarningTemplate, w function project(template: WarningTemplate, point: WarningPoint) { const { geo } = template; return { - x: geo.left + (point.lon - geo.west) / (geo.east - geo.west) * (geo.right - geo.left), - y: geo.top + (geo.north - point.lat) / (geo.north - geo.south) * (geo.bottom - geo.top), + x: geo.a * point.lon + geo.b * point.lat + geo.c, + y: geo.d * point.lon + geo.e * point.lat + geo.f, }; } diff --git a/web/src/pages/warnings/warningTemplates.ts b/web/src/pages/warnings/warningTemplates.ts index d41f241..c9efd64 100644 --- a/web/src/pages/warnings/warningTemplates.ts +++ b/web/src/pages/warnings/warningTemplates.ts @@ -11,13 +11,19 @@ export type WarningTemplate = { map: string; border: string; feather: number; - geo: { west: number; east: number; north: number; south: number; left: number; right: number; top: number; bottom: number }; + geo: { a: number; b: number; c: number; d: number; e: number; f: number }; title: { right: number; top: number; height: number; fontSize: number; horizontalPadding: number; maximumWidth: number }; legend: { right: number; bottom: number; swatch: number; gap: number; fontSize: number }; }; -// The two newsroom canvases have independent crops. These pixel bounds align -// Latvia's geographic extent to the white country outline in each source map. +// `geo` maps (lon, lat) to pixel space as x = a*lon + b*lat + c, y = d*lon + e*lat + f. +// The prior release used a 4-corner bounding-box stretch, which cannot represent +// the source artwork's rotation/shear and drifted up to ~200px on the 3840 canvas +// away from the calibration corners. These coefficients are a least-squares affine +// fit of ~17 well-spread cities' real-world coordinates against the pixel positions +// already validated for these same map_1920x1080/map_3840x1440 backgrounds by +// Kartes/Faktiska (see cityCoords.ts + mapConsts.ts), and land within ~35px of +// those validated positions on the 3840 canvas (~15px on 1920). export const warningTemplates: Record = { '1920x1080': { width: 1920, @@ -25,7 +31,7 @@ export const warningTemplates: Record = { map: map1920, border: border1920, feather: 16, - geo: { west: 20.97, east: 28.24, north: 58.09, south: 55.67, left: 360, right: 1655, top: 115, bottom: 864 }, + geo: { a: 171.6971, b: -21.1156, c: -2040.5772, d: -5.3027, e: -306.1028, f: 18050.1672 }, title: { right: 88, top: 38, height: 62, fontSize: 30, horizontalPadding: 24, maximumWidth: 900 }, legend: { right: 88, bottom: 58, swatch: 27, gap: 14, fontSize: 20 }, }, @@ -35,7 +41,7 @@ export const warningTemplates: Record = { map: map3840, border: border3840, feather: 28, - geo: { west: 20.97, east: 28.24, north: 58.09, south: 55.67, left: 985, right: 3150, top: 80, bottom: 1400 }, + geo: { a: 279.8026, b: -34.4106, c: -2997.9777, d: -8.6414, e: -498.8342, f: 29339.5317 }, title: { right: 376, top: 76, height: 124, fontSize: 60, horizontalPadding: 48, maximumWidth: 1700 }, legend: { right: 376, bottom: 76, swatch: 42, gap: 22, fontSize: 30 }, },