mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-16 00:29:34 -07:00
@@ -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 };
|
||||
|
||||
@@ -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`;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user