Initial release

This commit is contained in:
2026-03-11 17:24:57 +01:00
commit 5d537975e9
17 changed files with 6635 additions and 0 deletions

72
src/position.ts Normal file
View File

@@ -0,0 +1,72 @@
import { IPosition, 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;
constructor(data: Partial<IPosition>) {
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;
}
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 φ1 = this.latitude * Math.PI / 180;
const φ2 = other.latitude * Math.PI / 180;
const Δφ = (other.latitude - this.latitude) * Math.PI / 180;
const Δλ = (other.longitude - this.longitude) * Math.PI / 180;
const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c; // Distance in meters
}
}