adds height to route drawing

This commit is contained in:
Christian Beutel
2024-04-23 01:39:20 +02:00
parent 8d7ed16904
commit 8a3894106f
18 changed files with 176 additions and 96 deletions

View File

@@ -1,9 +1,9 @@
import * as xml2js from 'isomorphic-xml2js';
import Metadata from './metadata';
import Waypoint from './waypoint';
import Route from './route';
import Track from './track';
import { removeEmpty, allDatesToISOString } from './utils';
import { allDatesToISOString, calculateDistance, removeEmpty } from './utils';
import Waypoint from './waypoint';
const defaultAttributes = {
version: '1.1',
@@ -72,9 +72,59 @@ export default class GPX {
removeEmpty(this);
}
getTotals() {
let totalElevationGain = 0;
let totalDuration = 0;
let totalDistance = 0;
for (const track of this.trk ?? []) {
for (const segment of track.trkseg ?? []) {
const points = segment.trkpt ?? [];
if (points.length >= 2) {
const startTime = points[0].time;
const endTime = points[points.length - 1].time
if (startTime && endTime) {
totalDuration += endTime.getTime() - startTime.getTime();
}
}
const pointLength = points.length
for (let i = 1; i < pointLength; i++) {
const prevPoint = points[i - 1];
const point = points[i];
const elevation = point.ele ?? 0
const previousElevation = prevPoint.ele ?? 0
const elevationDiff = elevation - previousElevation;
if (elevationDiff > 0) {
totalElevationGain += elevationDiff;
}
const distance = calculateDistance(
prevPoint.$.lat ?? 0,
prevPoint.$.lon ?? 0,
point.$.lat ?? 0,
point.$.lon ?? 0,
);
totalDistance += distance;
}
}
}
return { distance: totalDistance, elevationGain: totalElevationGain, duration: totalDuration }
}
static parse(gpxString: string): Promise<GPX | Error> {
return new Promise<GPX | Error>((resolve, reject) => xml2js.parseString(gpxString, {
explicitArray: false
explicitArray: false,
attrValueProcessors: [(str: string | number) => {
if (!isNaN(Number(str))) {
str = Number.isInteger(Number(str)) ? parseInt(String(str), 10) : parseFloat(String(str));
}
return str;
}
]
}, (err, xml) => {
if (err) {
reject(err);
@@ -98,4 +148,4 @@ export default class GPX {
allDatesToISOString(gpx);
return builder.buildObject(gpx);
}
}
}

View File

@@ -20,4 +20,17 @@ function allDatesToISOString(obj: Record<string, any>) {
});
}
export { removeEmpty, allDatesToISOString };
function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
const R = 6371; // Radius of the Earth in km
const dLat = (lat2 - lat1) * (Math.PI / 180); // Convert degrees to radians
const dLon = (lon2 - lon1) * (Math.PI / 180);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * (Math.PI / 180))) * Math.cos((lat2 * (Math.PI / 180))) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c * 1000; // Distance in km
return distance;
}
export { removeEmpty, allDatesToISOString, calculateDistance };

View File

@@ -1,4 +1,4 @@
interface ValhallaResponse {
interface ValhallaRouteResponse {
trip: {
legs: {
shape: string;
@@ -6,4 +6,8 @@ interface ValhallaResponse {
};
}
export { type ValhallaResponse }
interface ValhallaHeightResponse {
height: number[];
}
export { type ValhallaRouteResponse, type ValhallaHeightResponse }