UNPKG

@sports-alliance/sports-lib

Version:

A Library to for importing / exporting and processing GPX, TCX, FIT and JSON files from services such as Strava, Movescount, Garmin, Polar etc

175 lines (174 loc) 11.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventImporterTCX = void 0; var event_1 = require("../../../event"); var activity_1 = require("../../../../activities/activity"); var creator_1 = require("../../../../creators/creator"); var lap_1 = require("../../../../laps/lap"); var data_energy_1 = require("../../../../data/data.energy"); var data_duration_1 = require("../../../../data/data.duration"); var data_distance_1 = require("../../../../data/data.distance"); var data_pause_1 = require("../../../../data/data.pause"); var data_speed_max_1 = require("../../../../data/data.speed-max"); var data_heart_rate_avg_1 = require("../../../../data/data.heart-rate-avg"); var data_heart_rate_max_1 = require("../../../../data/data.heart-rate-max"); var activity_types_1 = require("../../../../activities/activity.types"); var data_speed_avg_1 = require("../../../../data/data.speed-avg"); var lap_types_1 = require("../../../../laps/lap.types"); var importer_suunto_device_names_1 = require("../suunto/importer.suunto.device.names"); var importer_tcx_mapper_1 = require("./importer.tcx.mapper"); var event_utilities_1 = require("../../../utilities/event.utilities"); var helpers_1 = require("../../../utilities/helpers"); var EventImporterTCX = /** @class */ (function () { function EventImporterTCX() { } EventImporterTCX.getFromXML = function (xml, name) { var _this = this; if (name === void 0) { name = 'New Event'; } return new Promise(function (resolve, reject) { // debugger; // Activities var activities = Array.from(xml.getElementsByTagName('TrainingCenterDatabase')[0].getElementsByTagName('Activity')).map(function (activityElement) { // TCX begins with laps, get them var laps = _this.getLaps(activityElement.getElementsByTagName('Lap')); var activity = new activity_1.Activity(new Date(activityElement.getElementsByTagName('Lap')[0].getAttribute('StartTime')), laps[laps.length - 1].endDate, activity_types_1.ActivityTypes[activityElement.getAttribute('Sport') || 'unknown'], _this.getCreator(activityElement.getElementsByTagName('Creator')[0])); // Go over the laps and start filling up the stats and creating the points // @todo activity.setDuration(new data_duration_1.DataDuration(0)); activity.setDistance(new data_distance_1.DataDistance(0)); activity.setPause(new data_pause_1.DataPause(0)); activity.addStat(new data_energy_1.DataEnergy(0)); // Get the laps and add the total distance to the activity laps.forEach(function (lap) { if (lap.getDuration().getValue() === 0) { return; } activity.addLap(lap); // Increment wrapper stats activity.getDistance().setValue(activity.getDistance().getValue() + lap.getDistance().getValue()); activity.getDuration().setValue(activity.getDuration().getValue() + lap.getDuration().getValue()); activity.getPause().setValue(activity.getPause().getValue() + lap.getPause().getValue()); if (lap.getStat(data_energy_1.DataEnergy.type)) { activity.addStat(new data_energy_1.DataEnergy(activity.getStat(data_energy_1.DataEnergy.type).getValue() + lap.getStat(data_energy_1.DataEnergy.type).getValue())); } // Todo perhaps think about distance if 0 to add the lap as pause }); // @todo reduce laps to trackpoints var trackPointElements = Array.from(activityElement.getElementsByTagName('Lap')).reduce(function (trackPointElementArray, lapElement) { Array.from(lapElement.getElementsByTagName('Trackpoint')).forEach(function (trackPointElement) { trackPointElementArray.push(trackPointElement); }); return trackPointElementArray; }, []); // If the distance from laps is 0 and there is a last trackpoint with distance use that if (activity.getDistance().getValue() === 0 && trackPointElements.length && trackPointElements[trackPointElements.length - 1].getElementsByTagName('DistanceMeters')[0]) { activity.setDistance(new data_distance_1.DataDistance(Number(trackPointElements[trackPointElements.length - 1].getElementsByTagName('DistanceMeters')[0].textContent))); } importer_tcx_mapper_1.TCXSampleMapper.forEach(function (sampleMapping) { // Should check the children var subjectTrackPointElements = trackPointElements.filter(function (element) { return helpers_1.isNumber(sampleMapping.getSampleValue(element)); }); if (subjectTrackPointElements.length) { if (activity.hasStreamData(sampleMapping.dataType)) { return; } activity.addStream(activity.createStream(sampleMapping.dataType)); subjectTrackPointElements.forEach(function (subjectTrackPointElement) { activity.addDataToStream(sampleMapping.dataType, new Date(subjectTrackPointElement.getElementsByTagName('Time')[0].textContent), sampleMapping.getSampleValue(subjectTrackPointElement)); }); } }); return activity; }); // Init the event var event = new event_1.Event(name, activities[0].startDate, activities[activities.length - 1].endDate); activities.forEach(function (activity) { return event.addActivity(activity); }); event_utilities_1.EventUtilities.generateStatsForAll(event); resolve(event); }); }; EventImporterTCX.getCreator = function (creatorElement) { var creator; creator = new creator_1.Creator('Unknown device'); if (!creatorElement) { return creator; } // Try to see if its a listed Suunto Device name if (creatorElement.getElementsByTagName('Name')[0]) { creator.name = importer_suunto_device_names_1.ImporterSuuntoDeviceNames[creatorElement.getElementsByTagName('Name')[0].textContent] || creatorElement.getElementsByTagName('Name')[0].textContent || creator.name; } if (creatorElement.getElementsByTagName('Version')[0]) { creator.swInfo = creatorElement.getElementsByTagName('Version')[0].textContent; } return creator; }; EventImporterTCX.getLaps = function (lapElements) { return Array.from(lapElements).reduce(function (lapArray, lapElement) { // Create the lap var lap = new lap_1.Lap(new Date(lapElement.getAttribute('StartTime')), new Date(+new Date(lapElement.getAttribute('StartTime')) + 1000 * Number(lapElement.getElementsByTagName('TotalTimeSeconds')[0].textContent)), lap_types_1.LapTypes.AutoLap); if (lapElement.getElementsByTagName('TriggerMethod')[0]) { lap.type = lap_types_1.LapTypes[lapElement.getElementsByTagName('TriggerMethod')[0].textContent]; } if (lapElement.getElementsByTagName('Calories')[0]) { lap.addStat(new data_energy_1.DataEnergy(Number(lapElement.getElementsByTagName('Calories')[0].textContent))); } // Create a stats (required TCX fields) lap.addStat(new data_duration_1.DataDuration(Number(lapElement.getElementsByTagName('TotalTimeSeconds')[0].textContent))); lap.addStat(new data_distance_1.DataDistance(0)); if (lapElement.getElementsByTagName('DistanceMeters')[0]) { lap.addStat(new data_distance_1.DataDistance(Number(lapElement.getElementsByTagName('DistanceMeters')[0].textContent))); } lap.setPause(new data_pause_1.DataPause(0)); // Optionals if (lapElement.getElementsByTagName('MaximumSpeed')[0]) { lap.addStat(new data_speed_max_1.DataSpeedMax(Number(lapElement.getElementsByTagName('MaximumSpeed')[0].textContent))); } if (lapElement.getElementsByTagName('AverageHeartRateBpm')[0]) { lap.addStat(new data_heart_rate_avg_1.DataHeartRateAvg(Number(lapElement.getElementsByTagName('AverageHeartRateBpm')[0].getElementsByTagName('Value')[0].textContent))); } if (lapElement.getElementsByTagName('MaximumHeartRateBpm')[0]) { lap.addStat(new data_heart_rate_max_1.DataHeartRateMax(Number(lapElement.getElementsByTagName('MaximumHeartRateBpm')[0].getElementsByTagName('Value')[0].textContent))); } if (lapElement.getElementsByTagName('Extensions')[0] && lapElement.getElementsByTagName('Extensions')[0].getElementsByTagName('AvgSpeed')[0]) { lap.addStat(new data_speed_avg_1.DataSpeedAvg(Number(lapElement.getElementsByTagName('Extensions')[0].getElementsByTagName('AvgSpeed')[0].textContent))); } // Should check the track var lastPointFromPreviousTrack; // Get all the tracks and find the lap pause for this one Array.from(lapElement.getElementsByTagName('Track')).forEach(function (trackElement) { // Get the last var firstPointFromCurrentTrack = trackElement.getElementsByTagName('Trackpoint')[0]; // If there is no first point then no need to iterate it's empty if (!firstPointFromCurrentTrack) { return; } // if we do not have a last point of a previous parsed track set it to this one if (!lastPointFromPreviousTrack) { lastPointFromPreviousTrack = trackElement.getElementsByTagName('Trackpoint')[trackElement.getElementsByTagName('Trackpoint').length - 1]; return; } // Here we should have the current first point and the last point from the previous track var lastPointTime = new Date(lastPointFromPreviousTrack.getElementsByTagName('Time')[0].textContent).getTime(); var firstPointTime = new Date(firstPointFromCurrentTrack.getElementsByTagName('Time')[0].textContent).getTime(); lap.setPause(new data_pause_1.DataPause(lap.getPause().getValue() + (firstPointTime - lastPointTime) / 1000)); // Set the last to this one (will become the previous track on next track) lastPointFromPreviousTrack = trackElement.getElementsByTagName('Trackpoint')[trackElement.getElementsByTagName('Trackpoint').length - 1]; }); lapArray.push(lap); return lapArray; }, []); }; return EventImporterTCX; }()); exports.EventImporterTCX = EventImporterTCX;