37 lines
1.3 KiB
JavaScript
37 lines
1.3 KiB
JavaScript
const EARTH_RADIUS_M = 6_371_000;
|
|
const radians = degrees => degrees * Math.PI / 180;
|
|
|
|
export function distanceMeters(a, b) {
|
|
const dLat = radians(b.lat - a.lat);
|
|
const dLon = radians(b.lon - a.lon);
|
|
const lat1 = radians(a.lat);
|
|
const lat2 = radians(b.lat);
|
|
const h = Math.sin(dLat / 2) ** 2 + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) ** 2;
|
|
return 2 * EARTH_RADIUS_M * Math.asin(Math.sqrt(h));
|
|
}
|
|
|
|
export function routeMetrics(points) {
|
|
if (!points.length) throw new Error('Die GPX-Datei enthält keine Trackpunkte.');
|
|
let distance = 0;
|
|
let gain = 0;
|
|
for (let i = 1; i < points.length; i += 1) {
|
|
distance += distanceMeters(points[i - 1], points[i]);
|
|
const previous = points[i - 1].elevation;
|
|
const current = points[i].elevation;
|
|
if (Number.isFinite(previous) && Number.isFinite(current) && current > previous) gain += current - previous;
|
|
}
|
|
const lats = points.map(point => point.lat);
|
|
const lons = points.map(point => point.lon);
|
|
return {
|
|
startLat: points[0].lat,
|
|
startLon: points[0].lon,
|
|
centerLat: (Math.min(...lats) + Math.max(...lats)) / 2,
|
|
centerLon: (Math.min(...lons) + Math.max(...lons)) / 2,
|
|
minLat: Math.min(...lats), minLon: Math.min(...lons),
|
|
maxLat: Math.max(...lats), maxLon: Math.max(...lons),
|
|
distanceM: distance,
|
|
elevationGainM: gain,
|
|
pointCount: points.length
|
|
};
|
|
}
|