Files
us-api/src/adsb-exchange/adsb-exchange.service.ts
2024-09-10 21:02:00 -06:00

82 lines
2.4 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { AdsbExchange, Bearing, ExtendedAircraft } from './types';
import { DDPoint, Haversine, UnitOfDistance } from 'haversine-ts';
import axios from 'axios';
import { ConfigService } from '@nestjs/config';
const ValidRadii = [1, 5, 10, 25, 50, 100, 250] as const;
export type ValidRadius = (typeof ValidRadii)[number];
@Injectable()
export class AdsbExchangeService {
private readonly logger: Logger = new Logger(AdsbExchangeService.name);
constructor(private readonly configService: ConfigService) {}
isValidRadius(radius: number): radius is ValidRadius {
return ValidRadii.includes(radius as ValidRadius);
}
bearingToAircraft(
aircraft: AdsbExchange.Aircraft,
location: AdsbExchange.Location,
): Bearing {
const locationPoint = new DDPoint(location.lat, location.long);
const aircraftPoint = new DDPoint(aircraft.lat, aircraft.lon);
const haversine = new Haversine(UnitOfDistance.Mile);
const bearing = haversine.getBearing(locationPoint, aircraftPoint);
return {
bearing: bearing.start,
distance: haversine.getDistance(locationPoint, aircraftPoint),
};
}
async adsbExchangeAircraftWithinRadius(
radius: ValidRadius,
location: AdsbExchange.Location,
): Promise<AdsbExchange.Aircraft[]> {
this.logger.verbose(
`Requesting aircraft within ${radius} nautical miles of ${location.lat}, ${location.long}`,
);
const options = {
method: 'GET',
url: `https://adsbexchange-com1.p.rapidapi.com/v2/lat/${location.lat}/lon/${location.long}/dist/${radius}/`,
headers: {
'x-rapidapi-key': this.configService.get<string>('rapidApiKey'),
'x-rapidapi-host': 'adsbexchange-com1.p.rapidapi.com',
},
};
try {
const response =
await axios.request<AdsbExchange.AdsbExchangeRadiusResponse>(options);
return response.data.ac;
} catch (error) {
this.logger.error(error);
return [];
}
}
extendAircraft(
aircraft: AdsbExchange.Aircraft[],
location: AdsbExchange.Location,
): ExtendedAircraft[] {
return aircraft.map((a) => ({
...a,
bearing: this.bearingToAircraft(a, location),
}));
}
liteAircraft = (aircraft: ExtendedAircraft[]) =>
aircraft.map((a) => ({
flight: a.flight,
registration: a.r,
type: a.t,
altitude: a.alt_baro,
speed: a.gs,
track: a.track,
bearing: a.bearing,
}));
}