import { IDirectionFinding, IPosition, IPowerHeightGain, ISymbol } from "./frame.types"; export class Symbol implements ISymbol { table: string; // Symbol table identifier code: string; // Symbol code constructor(table: string, code?: string) { if (code === undefined) { if (table.length === 2) { this.code = table[1]; this.table = table[0]; } else { throw new Error(`Invalid symbol format: '${table}' (expected 2 characters if code is not provided)`); } } else { this.table = table; this.code = code; } } public toString(): string { return `${this.table}${this.code}`; } } export class Position implements IPosition { latitude: number; // Decimal degrees longitude: number; // Decimal degrees ambiguity?: number; // Position ambiguity (0-4) altitude?: number; // Meters speed?: number; // Speed in knots/kmh depending on source course?: number; // Course in degrees symbol?: Symbol; comment?: string; range?: number; phg?: IPowerHeightGain; dfs?: IDirectionFinding; constructor(data: Partial) { this.latitude = data.latitude ?? 0; this.longitude = data.longitude ?? 0; this.ambiguity = data.ambiguity; this.altitude = data.altitude; this.speed = data.speed; this.course = data.course; if (typeof data.symbol === "string") { this.symbol = new Symbol(data.symbol); } else if (data.symbol) { this.symbol = new Symbol(data.symbol.table, data.symbol.code); } this.comment = data.comment; this.range = data.range; this.phg = data.phg; this.dfs = data.dfs; } public toString(): string { const latStr = this.latitude.toFixed(5); const lonStr = this.longitude.toFixed(5); const altStr = this.altitude !== undefined ? `,${this.altitude}m` : ""; return `${latStr},${lonStr}${altStr}`; } public distanceTo(other: IPosition): number { const R = 6371e3; // Earth radius in meters const lat1 = (this.latitude * Math.PI) / 180; const lat2 = (other.latitude * Math.PI) / 180; const dLat = ((other.latitude - this.latitude) * Math.PI) / 180; const dLon = ((other.longitude - this.longitude) * Math.PI) / 180; const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) * Math.sin(dLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; // Distance in meters } }