ADSB updates

This commit is contained in:
2026-06-25 17:11:18 -04:00
parent 29ccc7aba9
commit a38098e3b7
2 changed files with 48 additions and 33 deletions

Binary file not shown.

View File

@@ -13,56 +13,72 @@ const SHAPES_PATH = resolve(DATA, 'shapes.json');
const history = new Map(); const history = new Map();
const MAX_HISTORY = 500; const MAX_HISTORY = 500;
const CSV_URL = 'https://s3.opensky-network.org/data-samples/metadata/aircraft-database-complete-2024-06.csv'; const CSV_URL = 'https://s3.opensky-network.org/data-samples/metadata/aircraft-database-complete-2024-06.csv';
const MIL_RANGES_URL = ':8080/db-3.14.1707/ranges.js'; const MIL_RANGES_URL = ':8080/db-3.14.1708/ranges.js';
const MILITARY_OPERATORS = ['air force', 'army', 'navy', 'marine', 'coast guard', 'military', 'defence', 'defense', 'luftwaffe', 'RAF', 'USAF', 'USN', 'USMC']; const MILITARY_OPERATORS = ['air force', 'army', 'navy', 'marine', 'coast guard', 'military', 'defence', 'defense', 'luftwaffe', 'RAF', 'USAF', 'USN', 'USMC'];
const CARGO_OPERATORS = ['fedex', 'ups', 'dhl', 'cargo', 'freight', 'logistic', 'atlas air', 'kalitta', 'air freight']; const CARGO_OPERATORS = ['fedex', 'ups', 'dhl', 'cargo', 'freight', 'logistic', 'atlas air', 'kalitta', 'air freight'];
const PASSENGER_OPERATORS = ['airlines', 'airways', 'air ', 'jet', 'easyjet', 'ryanair', 'delta', 'united', 'american', 'southwest', 'lufthansa', 'emirates', 'british']; const PASSENGER_OPERATORS = ['airlines', 'airways', 'air ', 'jet', 'easyjet', 'ryanair', 'delta', 'united', 'american', 'southwest', 'lufthansa', 'emirates', 'british'];
const MILITARY_CLASSES = ['H1M', 'H2M', 'L1M', 'L2M', 'L4M', 'A0']; const MILITARY_CLASSES = ['H1M', 'H2M', 'L1M', 'L2M', 'L4M', 'A0'];
const milRanges = [];
let db; let db;
async function syncMilitaryRanges() {
const { ADSB_URL } = cfg();
try {
const res = await fetch(ADSB_URL + MIL_RANGES_URL);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { military } = await res.json();
db.exec('DELETE FROM military_ranges');
const insert = db.prepare('INSERT INTO military_ranges (start, end) VALUES (?, ?)');
const insertMany = db.transaction(ranges => {
for (const [s, e] of ranges) insert.run(s.toUpperCase(), e.toUpperCase());
});
insertMany(military);
milRanges.length = 0;
milRanges.push(...military.map(([s, e]) => [s.toUpperCase(), e.toUpperCase()]));
} catch (e) {
const rows = db.prepare('SELECT start, end FROM military_ranges').all();
milRanges.length = 0;
milRanges.push(...rows.map(r => [r.start, r.end]));
}
}
export async function initAircraftDb() { export async function initAircraftDb() {
if (!fs.existsSync(DATA)) fs.mkdirSync(DATA, { recursive: true }); if (!fs.existsSync(DATA)) fs.mkdirSync(DATA, { recursive: true });
const missing = !fs.existsSync(DB_PATH); const missing = !fs.existsSync(DB_PATH);
if(missing) console.log(`✈️ Building database`); if (missing) console.log(`✈️ Building database`);
db = new Database(DB_PATH); db = new Database(DB_PATH);
db.exec(` db.exec(`
CREATE TABLE IF NOT EXISTS aircraft ( CREATE TABLE IF NOT EXISTS aircraft (
icao24 TEXT PRIMARY KEY, icao24 TEXT PRIMARY KEY,
built TEXT, built TEXT,
categoryDescription TEXT, categoryDescription TEXT,
country TEXT, country TEXT,
engines TEXT, engines TEXT,
class TEXT, class TEXT,
manufacturer TEXT, manufacturer TEXT,
model TEXT, model TEXT,
modes TEXT, modes TEXT,
operator TEXT, operator TEXT,
operatorCallsign TEXT, operatorCallsign TEXT,
owner TEXT, owner TEXT,
registration TEXT, registration TEXT,
serialNumber TEXT, serialNumber TEXT,
aircraft TEXT aircraft TEXT
); );
CREATE TABLE IF NOT EXISTS military_ranges ( CREATE TABLE IF NOT EXISTS military_ranges (
start TEXT NOT NULL, start TEXT NOT NULL,
end TEXT NOT NULL end TEXT NOT NULL
); );
`); `);
// Always refresh military ranges on startup await syncMilitaryRanges();
const { ADSB_URL } = cfg();
const res = await fetch(ADSB_URL + MIL_RANGES_URL);
if (!res.ok) throw new Error(`Failed to fetch military ranges: HTTP ${res.status}`);
const { military } = await res.json();
db.exec('DELETE FROM military_ranges');
const insertRange = db.prepare('INSERT INTO military_ranges (start, end) VALUES (?, ?)');
const insertRanges = db.transaction(ranges => { for (const [s, e] of ranges) insertRange.run(s.toUpperCase(), e.toUpperCase()); });
insertRanges(military);
if (missing) { if (missing) {
const res = await fetch(CSV_URL); const res = await fetch(CSV_URL);
@@ -77,7 +93,7 @@ export async function initAircraftDb() {
@class, @manufacturer, @model, @modes, @operator, @class, @manufacturer, @model, @modes, @operator,
@operatorCallsign, @owner, @registration, @serialNumber, @aircraft @operatorCallsign, @owner, @registration, @serialNumber, @aircraft
) )
`); `);
const insertMany = db.transaction(rows => { const insertMany = db.transaction(rows => {
for (const row of rows) insert.run(row); for (const row of rows) insert.run(row);
@@ -112,8 +128,7 @@ export async function initAircraftDb() {
function isIcaoInMilitaryRange(icao) { function isIcaoInMilitaryRange(icao) {
if (!icao) return false; if (!icao) return false;
const hex = icao.toUpperCase(); const hex = icao.toUpperCase();
const match = db.prepare('SELECT 1 FROM military_ranges WHERE start <= ? AND end >= ? LIMIT 1').get(hex, hex); return milRanges.some(([s, e]) => hex >= s && hex <= e);
return !!match;
} }
function wordMatch(text, keyword) { function wordMatch(text, keyword) {