Calibrate Brīdinājumi projection to validated city pixel positions

This commit is contained in:
b0txec
2026-08-22 21:04:39 +03:00
parent 13115f014d
commit 4395935788
2 changed files with 13 additions and 7 deletions
+2 -2
View File
@@ -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,
};
}
+11 -5
View File
@@ -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<WarningOutput, WarningTemplate> = {
'1920x1080': {
width: 1920,
@@ -25,7 +31,7 @@ export const warningTemplates: Record<WarningOutput, WarningTemplate> = {
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<WarningOutput, WarningTemplate> = {
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 },
},