UNPKG

read-tcx

Version:

Read tcx files (supported files exported from Garmin Connect, Polar Flow, Tapiriik) and convert it to Activity Json Oblect

287 lines (262 loc) 9.28 kB
import { iPoint, iGeoPoint } from "./tcxinterfaces"; import Activity from "../activity"; import geoPoint from "./geoPoint"; const secondsInHour = 3600; /** Υπολογίζει το Bmi από το βάρος και το ύψος * @param {number} weightInKG το βάρος σε Κgr * @param {number} heightInMeters το υψος σε μέτρα * @returns number το ΒΜΙ σαν δεδκαδικό αριθμό */ //τεστ ΟΚ const calculateBmi = (weightInKG: number, heightInMeters: number): number => { return weightInKG / (heightInMeters * heightInMeters); }; /** * Mετατρέπει την ταχύτητα από m/s σε δεκαδικό ρυθμό min/km * @param {number} value η ταχύτητα σε m/s * @returns string το ρυθμό σε λεπτά το χιλιόμετρο με τη μορφή Λ,Δ * @example decimalPaceFromSpeedMpS(2.77) = 6 (06:00.00) */ const decimalPaceFromSpeedMpS = (value: number) => { //test ok return 50 / (value * 3); }; /** * Mετατρέπει τον ρυθμο από την δεκαδική του μορφή στη μορφή ΛΛ:ΔΔ.ΕΕ * @param {number} value * @returns string: ο ρυθμός σε μορφή ΛΛ:ΔΔ.ΕΕ */ const decimalPaceToTimePace = (value: number) => { return secsToTime(value * 60, false); }; /** * Μετατρέπει τα μέτρα σε χιλιόμετρα χωρίς να χάσει το δεικαδικό * @param {number} value η απόσταση σε μέτρα * @returns {number} την απόσταση σε ΚΜ */ const distanceFromMtoKM = (value: number): number => { if (value - Math.floor(value) === 0) { return value / 1000; } else { let medium = Math.pow(10, value.toString().split(".")[1].length); return value * medium / (medium * 1000); } }; /** * Mετατρέπει την ταχύτητα από m/s σε Κm/h * @param {number} value η ταχύτητα σε m/s * @returns number η ταχύτητα σε ΧαΩ */ const speedFromMpStoKpH = (value: number) => { //τεστ οκ return value * 3.6; }; /** * Mετατρέπει την ταχύτητα από m/s σε ρυθμό της μορφής ΛΛ:ΔΔ.ΕΕ * @param {number} value η ταχύτητα σε m/s * @returns string ο ρυθμός σε μορφή ΛΛ:ΔΔ.ΕΕ */ const TimePaceFromSpeedMpS = (value: number): string => { //test ok return decimalPaceToTimePace(decimalPaceFromSpeedMpS(value)); }; /** * H secsToTime μετατρέπει τα δευτερόλεπτα value σε χρόνο της μορφής * [ΩΩ:]ΛΛ:ΔΔ.ΕΕ. * * <p>Οι ώρες δεν εμφανίζονται αν τεθεί η τιμή showHours σε false (εξ ορισμού * εμφανίζονται οι ώρες)</p> * @param {number} value ο χρόνος σε secs * @param {boolean} showHours αν θα εμφανίζεται το πεδίο ΩΩ: * @returns string o χρόνος σε μορφή ΩΩ:ΛΛ:ΔΔ.ΕΕ * */ //τεστ οκ const secsToTime = (value: number, showHours?: boolean) => { showHours === undefined ? (showHours = true) : (showHours = false); let result = ""; //βρίσκω τις ώρες let hrs = Math.floor(value / 3600); if (hrs > 0) { value -= hrs * 3600; hrs > 9 ? (result += hrs.toString() + ":") : (result = `0${hrs.toString()}:`); } else { showHours ? (result += `00:`) : (result = result); } //μιν -> λεπτά let min = Math.floor(value / 60); value -= min * 60; min > 9 ? (result += min.toString() + ":") : (result += `0${min.toString()}:`); //sec -> δευτερόλεπτα let secs = Math.floor(value); secs > 9 ? (result += secs.toString()) : (result += `0${secs.toString()}`); value -= secs; if (value === 0) { return `${result}.00`; } //mil -> εκατοστά let mil = Math.floor(value * 100); mil > 9 ? (result += `.${mil.toString()}`) : (result += `.0${mil.toString()}`); return result; }; /** * Μετατρέπει τις Μοίρες σε Ακτίνια * * @param {number} Degrees οι μοίρες * @returns number τις degrees μοίρες σε ακτίνια */ //test ok const degToRads = (Degrees: number): number => { return Degrees * (Math.PI / 180); }; /** * Μετατρέπει τα ακτίνια σε μοίρες * * @param {number} η γωνία angle σε ακτίνια * @returns number τα ακτίνια angle σε μοίρες */ //test ok const radToDegrees = (angle: number): number => { return angle * (180 / Math.PI); }; /** * Υπολογίζει την απόσταση σε ΜΕΤΡΑ από το σημείο FromPoint στο σημείο ToPoint * * @param {geoPoint} FromPoint οι συντεταγμένες του αρχικού σημείου σε ΜΟΙΡΕΣ * @param {geoPoint} ToPoint οι συντεταγμένες του τελικού σημείου σε ΜΟΙΡΕΣ * @returns number η απόσταση ανάμεσα στα σημεία σε ΜΕΤΡΑ */ //test οκ const apostasi = (FromPoint: geoPoint, ToPoint: geoPoint): number => { let lat2 = ToPoint.LatitudeDegrees; let lon2 = ToPoint.LongitudeDegrees; let lat1 = FromPoint.LatitudeDegrees; let lon1 = FromPoint.LongitudeDegrees; let φ1 = degToRads(lat1); let φ2 = degToRads(lat2); let λ1 = degToRads(lon1); let λ2 = degToRads(lon2); let Δλ = degToRads(lon2 - lon1); let Δφ = degToRads(lat2 - lat1); let R = 6371e3; let a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos1) * Math.cos2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2); let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; }; /** * Υπολογίζει το αζιμούθιο σε ΜΟΙΡΕΣ * * @param {geoPoint} FromPoint οι συντεταγμένες του αρχικού σημείου σε ΜΟΙΡΕΣ * @param {geoPoint} ToPoint οι συντεταγμένες του τελικού σημείου σε ΜΟΙΡΕΣ * @returns number το αζιμούθιο από το αρχικό ως το τελικό σημείο */ //test ok const Bearing = (FromPoint: geoPoint, ToPoint: geoPoint): number => { let lat2 = ToPoint.LatitudeDegrees; let lon2 = ToPoint.LongitudeDegrees; let lat1 = FromPoint.LatitudeDegrees; let lon1 = FromPoint.LongitudeDegrees; let φ1 = degToRads(lat1); let φ2 = degToRads(lat2); let λ1 = degToRads(lon1); let λ2 = degToRads(lon2); let Δλ = degToRads(lon2 - lon1); let Δφ = degToRads(lat2 - lat1); let y = Math.sin2 - λ1) * Math.cos2); let x = Math.cos1) * Math.sin2) - Math.sin1) * Math.cos2) * Math.cos2 - λ1); let temp = radToDegrees(Math.atan2(y, x)); if (temp < 0) { temp = temp + 360; } return temp; }; /** * Υπολογίζει τις συντεταγμένες του σημείου που βρίσκεται σε δεδομένα απόσταση και αζιμούθιο από το σημείο που στεκόμαστε * * @param {geoPoint} FromPoint το αρχικό σημείο * @param {number} distance η απόσταση σε μέτρα προς το επόμενο σημείο * @param {number} Bearing το αζιμούθιο προς το τελικό σημείο σε ΜΟΙΡΕΣ * @returns geoPoint αντικείμενο Cordinates */ //test ok const getNextPointCordinatesFromDistanceBearing = ( FromPoint: geoPoint, distance: number, Bearing: number ): geoPoint => { let brng = degToRads(Bearing); let lat1 = FromPoint.LatitudeDegrees; let lon1 = FromPoint.LongitudeDegrees; let d = distance; let R = 6371e3; let φ1 = degToRads(lat1); let λ1 = degToRads(lon1); let temp = new geoPoint(); temp.LatitudeDegrees = Math.asin( Math.sin1) * Math.cos(d / R) + Math.cos1) * Math.sin(d / R) * Math.cos(brng) ); let φ2 = temp.LatitudeDegrees; temp.LongitudeDegrees = λ1 + Math.atan2( Math.sin(brng) * Math.sin(d / R) * Math.cos1), Math.cos(d / R) - Math.sin1) * Math.sin2) ); temp.LatitudeDegrees = radToDegrees(temp.LatitudeDegrees); temp.LongitudeDegrees = radToDegrees(temp.LongitudeDegrees); temp.AltitudeMeters = FromPoint.AltitudeMeters; return temp; }; const isInCurrentWeek = (utcDate: string): boolean => { let curImnia = new Date().setHours(0, 0, 0, 0); let imnia = new Date(utcDate).setHours(0, 0, 0, 0); let d = new Date().getDay(); let interval = Math.floor((curImnia - imnia) / 86400000); return interval > 0 && d > interval; }; const formatDate = (date1: Date) => { return ( date1.getFullYear() + "-" + (date1.getMonth() < 9 ? "0" : "") + (date1.getMonth() + 1) + "-" + (date1.getDate() < 10 ? "0" : "") + date1.getDate() ); }; const putSlashInFront = (str: string) => { if (str.trim().substring(0, 1) !== "/") { return `/${str.trim()}`; } else { return str; } }; export { apostasi, Bearing, calculateBmi, decimalPaceFromSpeedMpS, decimalPaceToTimePace, degToRads, distanceFromMtoKM, formatDate, getNextPointCordinatesFromDistanceBearing, isInCurrentWeek, putSlashInFront, radToDegrees, secsToTime, speedFromMpStoKpH, TimePaceFromSpeedMpS };