54 рядки
1.7 KiB
TypeScript
54 рядки
1.7 KiB
TypeScript
import { Angle } from './angle';
|
|
|
|
const EarthRadius = 6371000;
|
|
|
|
export class WGS84 {
|
|
/// @brief Calculates the Haversine distance
|
|
/// @param coordinate0 The first coordinate
|
|
/// @param coordinate1 The second coordinate
|
|
/// @return The haversine distance in metres
|
|
static distance(
|
|
coordinate0: { lat: number; lon: number },
|
|
coordinate1: { lat: number; lon: number },
|
|
): number {
|
|
const lat0 = Angle.deg2rad(coordinate0.lat);
|
|
const lon0 = Angle.deg2rad(coordinate0.lon);
|
|
const lat1 = Angle.deg2rad(coordinate1.lat);
|
|
const lon1 = Angle.deg2rad(coordinate1.lon);
|
|
|
|
const a =
|
|
0.5 -
|
|
Math.cos(lat1 - lat0) * 0.5 +
|
|
Math.cos(lat0) * Math.cos(lat1) * (1 - Math.cos(lon1 - lon0) * 0.5);
|
|
|
|
return 2 * EarthRadius * Math.asin(Math.sqrt(a));
|
|
}
|
|
|
|
/// @brief Projects coordinate based on the distance and bearing
|
|
/// @param coordinate The root coordinate
|
|
/// @param distance The distance in metres
|
|
/// @param bearing The bearing in degree
|
|
static project(
|
|
coordinate: { lat: number; lon: number },
|
|
distance: number,
|
|
bearing: number,
|
|
): { lat: number; lon: number } {
|
|
const lat0 = Angle.deg2rad(coordinate.lat);
|
|
const lon0 = Angle.deg2rad(coordinate.lon);
|
|
const radians = Angle.deg2rad(bearing);
|
|
|
|
const lat1 = Math.asin(
|
|
Math.sin(lat0) * Math.cos(distance / EarthRadius) +
|
|
Math.cos(lat0) * Math.sin(distance / EarthRadius) * Math.cos(radians),
|
|
);
|
|
const lon1 =
|
|
lon0 +
|
|
Math.atan2(
|
|
Math.sin(radians) * Math.sin(distance / EarthRadius) * Math.cos(lat0),
|
|
Math.cos(distance / EarthRadius) - Math.sin(lat0) * Math.sin(lat1),
|
|
);
|
|
|
|
return { lat: Angle.rad2deg(lat1), lon: Angle.rad2deg(lon1) };
|
|
}
|
|
}
|