UNPKG

eatc-airlines

Version:

A command-line tool and API for retrieving scheduled and historical flight data and generating Endless ATC airline configurations.

240 lines 11.8 kB
/* * Copyright © 2025 Zefir Kirilov. * * This file is part of eatc-airlines. * * eatc-airlines is free software: you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * eatc-airlines is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along with eatc-airlines. * If not, see <https://www.gnu.org/licenses/>. */ export class LatLon { /** * Latitude in decimal degrees */ lat; /** * Longitude in decimal degrees */ lon; /** * @param lat Latitude in decimal degrees * @param lon Longitude in decimal degrees */ constructor(lat, lon) { this.lat = lat; this.lon = lon; } /** * Calculate initial bearing to another {@link LatLon} * @param to * @returns Bearing in decimal degrees */ bearing(to) { const φ1 = this.lat * Math.PI / 180; const φ2 = to.lat * Math.PI / 180; const λ1 = this.lon * Math.PI / 180; const λ2 = to.lon * Math.PI / 180; const Δλ = λ2 - λ1; const y = Math.sin(Δλ) * Math.cos(φ2); const x = Math.cos(φ1) * Math.sin(φ2) - Math.sin(φ1) * Math.cos(φ2) * Math.cos(Δλ); const θ = Math.atan2(y, x); return (θ * 180 / Math.PI + 360) % 360; } /** * Calculate initial direction to another {@link LatLon} * @param to */ direction(to) { return Direction.fromBearing(this.bearing(to)); } toString() { return `${this.lat >= 0 ? Direction.N : Direction.S}, ${this.lon >= 0 ? Direction.E : Direction.W}`; } toJSON() { return { lat: this.lat, lon: this.lon, }; } } export class Location extends LatLon { /** * The name of this location */ name; /** * @param name The name of this location * @param lat Latitude in decimal degrees * @param lon Longitude in decimal degrees */ constructor(name, lat, lon) { super(lat, lon); this.name = name; } toString() { return this.name + ", " + super.toString(); } toJSON() { return { name: this.name, lat: this.lat, lon: this.lon, }; } } export class Direction { name; /** * North */ static N = new Direction("N"); /** * East */ static E = new Direction("E"); /** * South */ static S = new Direction("S"); /** * West */ static W = new Direction("W"); constructor(name) { this.name = name; } /** * Get direction from bearing * @param bearing Bearing in decimal degrees */ static fromBearing(bearing) { const normalisedBearing = (bearing + 360) % 360; if (normalisedBearing >= 225 && normalisedBearing < 315) return Direction.W; if (normalisedBearing >= 135 && normalisedBearing < 225) return Direction.S; if (normalisedBearing >= 45 && normalisedBearing < 135) return Direction.E; return Direction.N; } toString() { return this.name; } toJSON() { return this.name; } } export class Flight { /** * Unique ID */ id; /** * Flight arrival time (or estimate) */ time; /** * Tail number (aircraft registration) */ tail; /** * Aircraft ICAO type designator */ type; /** * Airline ICAO code (unique 3-letter identifier) */ airline; /** * Flight callsign */ callsign; /** * Flight destination */ to; /** * Flight origin */ from; /** * @param id Unique ID * @param time Flight arrival time (or estimate) * @param tail Tail number (aircraft registration) * @param type Aircraft ICAO type designator * @param airline Airline ICAO code (unique 3-letter identifier) * @param callsign Flight callsign * @param to Flight destination * @param from Flight origin */ constructor(id, time, tail, type, airline, callsign, to, from) { this.id = id; this.time = time; this.tail = tail; this.type = type; this.airline = airline; this.callsign = callsign; this.to = to; this.from = from; } toJSON() { return { id: this.id, time: this.time?.getTime() ?? null, tail: this.tail, type: this.type, airline: this.airline, callsign: this.callsign, to: this.to, from: this.from, }; } } export const PHONETIC = { A: "Alpha", B: "Bravo", C: "Charlie", D: "Delta", E: "Echo", F: "Foxtrot", G: "Golf", H: "Hotel", I: "India", J: "Juliet", K: "Kilo", L: "Lima", M: "Mike", N: "November", O: "Oscar", P: "Papa", Q: "Quebec", R: "Romeo", S: "Sierra", T: "Tango", U: "Uniform", V: "Victor", W: "Whisky", X: "X-Ray", Y: "Yankee", Z: "Zulu", }; export const NUMBERS = { 0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Niner", }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLE9BQU8sTUFBTTtJQUNmOztPQUVHO0lBQ2EsR0FBRyxDQUFTO0lBRTVCOztPQUVHO0lBQ2EsR0FBRyxDQUFTO0lBRTVCOzs7T0FHRztJQUNILFlBQ0ksR0FBVyxFQUNYLEdBQVc7UUFFWCxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ25CLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksT0FBTyxDQUFDLEVBQVU7UUFDckIsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUNwQyxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1FBQ2xDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUM7UUFDcEMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQztRQUVsQyxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBRW5CLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsR0FB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