radar code cleanup #74 #111

This commit is contained in:
Matt Walsh
2025-06-16 15:45:43 -05:00
parent 9eb192146a
commit bb0ad8ff32
4 changed files with 24 additions and 98 deletions

View File

@@ -3,4 +3,3 @@ export const TILE_COUNT = { x: 10, y: 11 };
export const TILE_FULL_SIZE = { x: 6800, y: 4255 };
export const RADAR_FULL_SIZE = { width: 2550, height: 1600 };
export const RADAR_FINAL_SIZE = { width: 640, height: 367 };
export const RADAR_SOURCE_SIZE = { width: 480, height: 276 };

View File

@@ -1,14 +1,25 @@
import {
pixelToFile, modTile,
} from './radar-utils.mjs';
import { RADAR_FINAL_SIZE, TILE_SIZE } from './radar-constants.mjs';
import { RADAR_FINAL_SIZE, TILE_SIZE, TILE_COUNT } from './radar-constants.mjs';
import { elemForEach } from './utils/elem.mjs';
// convert a pixel location to a file/tile combination
const pixelToFile = (xPixel, yPixel) => {
const xTile = Math.floor(xPixel / TILE_SIZE.x);
const yTile = Math.floor(yPixel / TILE_SIZE.y);
if (xTile < 0 || xTile > TILE_COUNT.x || yTile < 0 || yTile > TILE_COUNT.y) return false;
return `${yTile}-${xTile}`;
};
// convert a pixel location in the overall map to a pixel location on the tile
const modTile = (xPixel, yPixel) => {
const x = Math.round(xPixel) % TILE_SIZE.x;
const y = Math.round(yPixel) % TILE_SIZE.y;
return { x, y };
};
// creates the radar background map image and overlay transparency
// which remain fixed on the page as the radar image changes in layered divs
// it returns 4 ImageBitmaps that represent the base map, and 4 ImageBitmaps that are the overlay
// the main thread pushes these ImageBitmaps into the image placeholders on the page
const setTiles = (data) => {
const {
sourceXY,
@@ -115,6 +126,7 @@ const setTiles = (data) => {
const mapTileContainer = document.querySelector(`#${elemIdFull} .map-tiles`);
mapTileContainer.style.top = `${-tileShift.y}px`;
mapTileContainer.style.left = `${-tileShift.x}px`;
// and the same for the overlay
const overlayTileContainer = document.querySelector(`#${elemIdFull} .overlay-tiles`);
overlayTileContainer.style.top = `${-tileShift.y}px`;
overlayTileContainer.style.left = `${-tileShift.x}px`;

View File

@@ -1,6 +1,4 @@
import {
RADAR_FINAL_SIZE, RADAR_SOURCE_SIZE, TILE_SIZE, TILE_COUNT, TILE_FULL_SIZE,
} from './radar-constants.mjs';
import { TILE_SIZE, TILE_FULL_SIZE } from './radar-constants.mjs';
// limit a value to within a range
const coerce = (low, value, high) => Math.max(Math.min(value, high), low);
@@ -21,32 +19,15 @@ const getXYFromLatitudeLongitudeMap = (pos) => {
};
const getXYFromLatitudeLongitudeDoppler = (pos, offsetX, offsetY) => {
let y = 0;
let x = 0;
const imgHeight = 6000;
const imgWidth = 2800;
y = (51 - pos.latitude) * 61.4481;
// center map
y -= offsetY;
// map position is calculated as a regresion
// then shifted by half of the tile size (to center the map)
// then they are limited to values between 0 and the width or height of the map
// Do not allow the map to exceed the max/min coordinates.
if (y > (imgHeight - (offsetY * 2))) {
y = imgHeight - (offsetY * 2);
} else if (y < 0) {
y = 0;
}
x = ((-129.138 - pos.longitude) * 42.1768) * -1;
// center map
x -= offsetX;
// Do not allow the map to exceed the max/min coordinates.
if (x > (imgWidth - (offsetX * 2))) {
x = imgWidth - (offsetX * 2);
} else if (x < 0) {
x = 0;
}
const y = coerce(0, (51 - pos.latitude) * 61.4481 - offsetY, imgHeight);
const x = coerce(0, ((-129.138 - pos.longitude) * 42.1768) * -1 - offsetX, imgWidth);
return { x: x * 2, y: y * 2 };
};
@@ -139,72 +120,8 @@ const removeDopplerRadarImageNoise = (RadarContext) => {
RadarContext.putImageData(RadarImageData, 0, 0);
};
const mergeDopplerRadarImage = (mapContext, radarContext) => {
const mapImageData = mapContext.getImageData(0, 0, mapContext.canvas.width, mapContext.canvas.height);
const radarImageData = radarContext.getImageData(0, 0, radarContext.canvas.width, radarContext.canvas.height);
// examine every pixel,
// change any old rgb to the new-rgb
for (let i = 0; i < radarImageData.data.length; i += 4) {
// i + 0 = red
// i + 1 = green
// i + 2 = blue
// i + 3 = alpha (0 = transparent, 255 = opaque)
// is this pixel the old rgb?
if ((mapImageData.data[i] < 116 && mapImageData.data[i + 1] < 116 && mapImageData.data[i + 2] < 116)) {
// change to your new rgb
// Transparent
radarImageData.data[i] = 0;
radarImageData.data[i + 1] = 0;
radarImageData.data[i + 2] = 0;
radarImageData.data[i + 3] = 0;
}
}
radarContext.putImageData(radarImageData, 0, 0);
mapContext.drawImage(radarContext.canvas, 0, 0);
};
const scaling = {
width: RADAR_FINAL_SIZE.width / RADAR_SOURCE_SIZE.width,
height: RADAR_FINAL_SIZE.height / RADAR_SOURCE_SIZE.height,
};
// convert a pixel location to a file/tile combination
const pixelToFile = (xPixel, yPixel) => {
const xTile = Math.floor(xPixel / TILE_SIZE.x);
const yTile = Math.floor(yPixel / TILE_SIZE.y);
if (xTile < 0 || xTile > TILE_COUNT.x || yTile < 0 || yTile > TILE_COUNT.y) return false;
return `${yTile}-${xTile}`;
};
// convert a pixel location in the overall map to a pixel location on the tile
const modTile = (xPixel, yPixel) => {
const x = Math.round(xPixel) % TILE_SIZE.x;
const y = Math.round(yPixel) % TILE_SIZE.y;
return { x, y };
};
const mapSizeToFinalSize = (x, y) => ({
x: Math.round(x * scaling.height),
y: Math.round(y * scaling.width),
});
const fetchAsBlob = async (url) => {
const response = await fetch(url);
return response.blob();
};
export {
getXYFromLatitudeLongitudeDoppler,
getXYFromLatitudeLongitudeMap,
removeDopplerRadarImageNoise,
mergeDopplerRadarImage,
pixelToFile,
modTile,
mapSizeToFinalSize,
fetchAsBlob,
};

View File

@@ -1,6 +1,4 @@
import {
removeDopplerRadarImageNoise,
} from './radar-utils.mjs';
import { removeDopplerRadarImageNoise } from './radar-utils.mjs';
import { RADAR_FULL_SIZE, RADAR_FINAL_SIZE } from './radar-constants.mjs';
onmessage = async (e) => {