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

274 lines (273 loc) 13 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Activity = exports.MAX_ACTIVITY_DURATION = void 0; var activity_types_1 = require("./activity.types"); var duration_class_abstract_1 = require("../duration/duration.class.abstract"); var data_latitude_degrees_1 = require("../data/data.latitude-degrees"); var data_longitude_degrees_1 = require("../data/data.longitude-degrees"); var stream_1 = require("../streams/stream"); var helpers_1 = require("../events/utilities/helpers"); var data_power_1 = require("../data/data.power"); var data_start_event_1 = require("../data/data.start-event"); var data_stop_event_1 = require("../data/data.stop-event"); var data_stop_all_event_1 = require("../data/data.stop-all-event"); var data_time_1 = require("../data/data.time"); var activity_utilities_1 = require("../events/utilities/activity.utilities"); exports.MAX_ACTIVITY_DURATION = 1 * 1 * 30 * 24 * 60 * 60 * 1000; // 1 month var Activity = /** @class */ (function (_super) { __extends(Activity, _super); function Activity(startDate, endDate, type, creator, name) { if (name === void 0) { name = ''; } var _this = _super.call(this, startDate, endDate) || this; _this.intensityZones = []; // maybe rename _this.laps = []; _this.streams = []; _this.events = []; if (!startDate || !endDate) { throw new Error('Start and end dates are required'); } if (endDate < startDate) { throw new Error('Activity end date is before the start date and that is not acceptable'); } if (+endDate - +startDate > exports.MAX_ACTIVITY_DURATION) { throw new Error('Activity duration is over 1 month and that is not supported'); } _this.type = type; _this.creator = creator; _this.name = name; return _this; } Activity.prototype.createStream = function (type) { return new stream_1.Stream(type, Array(activity_utilities_1.ActivityUtilities.getDataLength(this.startDate, this.endDate)).fill(null)); }; Activity.prototype.addDataToStream = function (type, date, value) { this.getStreamData(type)[this.getDateIndex(date)] = value; return this; }; Activity.prototype.addStream = function (stream) { if (this.streams.find(function (activityStream) { return activityStream.type === stream.type; })) { throw new Error("Duplicate type of stream when adding " + stream.type + " to activity " + this.getID()); } this.streams.push(stream); return this; }; Activity.prototype.clearStreams = function () { this.streams = []; return this; }; Activity.prototype.removeStream = function (streamType) { var stream = streamType instanceof stream_1.Stream ? streamType : this.getStream(streamType); this.streams = this.streams.filter(function (activityStream) { return stream !== activityStream; }); return this; }; Activity.prototype.addStreams = function (streams) { var _a; (_a = this.streams).push.apply(_a, streams); return this; }; Activity.prototype.getAllStreams = function () { return this.streams; }; // @todo needs more logic improvement and transparency Activity.prototype.getAllExportableStreams = function () { return this.getAllStreams().filter(function (stream) { return stream.isExportable(); }); }; Activity.prototype.hasStreamData = function (streamType, startDate, endDate) { try { this.getStreamData(streamType, startDate, endDate); } catch (e) { return false; } return true; }; Activity.prototype.hasPositionData = function (startDate, endDate) { return (this.hasStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type, startDate, endDate) && this.hasStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type, startDate, endDate)); }; Activity.prototype.isTrainer = function () { return Activity.TRAINER_TYPES.indexOf(this.type) !== -1; }; Activity.prototype.hasPowerMeter = function () { return this.hasStreamData(data_power_1.DataPower.type); }; Activity.prototype.getStream = function (streamType) { var find = this.streams.find(function (stream) { return stream.type === streamType; }); if (!find) { throw Error("No stream found with type " + streamType); } return find; }; Activity.prototype.getStreamData = function (streamType, startDate, endDate) { var _this = this; var stream = streamType instanceof stream_1.Stream ? streamType : this.getStream(streamType); if (!startDate && !endDate) { return stream.getData(); } if (startDate && endDate) { return stream .getData() .filter(function (value, index) { return new Date(_this.startDate.getTime() + index * 1000) <= endDate; }) .filter(function (value, index) { return new Date(_this.startDate.getTime() + index * 1000) >= startDate; }); } if (startDate) { return stream.getData().filter(function (value, index) { return new Date(_this.startDate.getTime() + index * 1000) > startDate; }); } if (endDate) { return stream.getData().filter(function (value, index) { return new Date(_this.startDate.getTime() + index * 1000) < endDate; }); } return []; }; // @todo see how this fits with the filtering on the stream class /** * Gets the data array of an activity stream excluding the non numeric ones * @todo include strings and all data abstract types * @param streamType * @param startDate * @param endDate */ Activity.prototype.getSquashedStreamData = function (streamType, startDate, endDate) { return this.getStreamData(streamType, startDate, endDate).filter(function (data) { return helpers_1.isNumber(data); }); }; Activity.prototype.getPositionData = function (startDate, endDate) { var latitudeStreamData = this.getStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type, startDate, endDate); var longitudeStreamData = this.getStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type, startDate, endDate); return latitudeStreamData.reduce(function (positionArray, value, index, array) { var currentLatitude = latitudeStreamData[index]; var currentLongitude = longitudeStreamData[index]; if (!helpers_1.isNumber(currentLatitude) || !helpers_1.isNumber(currentLongitude)) { positionArray.push(null); return positionArray; } positionArray.push({ latitudeDegrees: currentLatitude, longitudeDegrees: currentLongitude }); return positionArray; }, []); }; Activity.prototype.getSquashedPositionData = function (startDate, endDate) { return this.getPositionData(startDate, endDate).filter(function (data) { return data !== null; }); }; Activity.prototype.getStreamDataTypesBasedOnDataType = function (streamTypeToBaseOn, streamTypes) { return activity_utilities_1.ActivityUtilities.getStreamDataTypesBasedOnDataType(this.getStream(streamTypeToBaseOn), this.getAllStreams() .filter(function (stream) { return stream.type !== streamTypeToBaseOn; }) .filter(function (stream) { return streamTypes.indexOf(stream.type) !== -1; })); }; Activity.prototype.getStreamDataTypesBasedOnTime = function (streamTypes) { return activity_utilities_1.ActivityUtilities.getStreamDataTypesBasedOnTime(this.startDate, this.endDate, !streamTypes ? this.getAllStreams() : this.getAllStreams().filter(function (stream) { return streamTypes.indexOf(stream.type) !== -1; })); }; Activity.prototype.getStreamDataByTime = function (streamType, filterNull, filterInfinity) { if (filterNull === void 0) { filterNull = false; } if (filterInfinity === void 0) { filterInfinity = false; } return this.getStream(streamType).getStreamDataByTime(this.startDate, filterNull, filterInfinity); }; Activity.prototype.getStreamDataByDuration = function (streamType, filterNull, filterInfinity) { if (filterNull === void 0) { filterNull = false; } if (filterInfinity === void 0) { filterInfinity = false; } return this.getStream(streamType).getStreamDataByDuration(0, filterNull, filterInfinity); }; Activity.prototype.addLap = function (lap) { this.laps.push(lap); return this; }; Activity.prototype.getLaps = function (activity) { return this.laps; }; Activity.prototype.getAllEvents = function () { return this.events; }; Activity.prototype.getStartEvents = function () { return this.events.filter(function (event) { return event instanceof data_start_event_1.DataStartEvent; }); }; Activity.prototype.getStopEvents = function () { return this.events.filter(function (event) { return event instanceof data_stop_event_1.DataStopEvent; }); }; Activity.prototype.getStopAllEvents = function () { return this.events.filter(function (event) { return event instanceof data_stop_all_event_1.DataStopAllEvent; }); }; Activity.prototype.addEvent = function (event) { this.events.push(event); return this; }; Activity.prototype.setAllEvents = function (events) { this.events = events; return this; }; Activity.prototype.generateTimeStream = function (streamTypes) { var _this = this; if (streamTypes === void 0) { streamTypes = []; } var timeStream = this.createStream(data_time_1.DataTime.type); var streams = this.getAllStreams(); if (streamTypes.length) { streams = streams.filter(function (stream) { return streamTypes.indexOf(stream.type) !== -1; }); } streams.forEach(function (stream) { _this.getStreamDataByDuration(stream.type, true, false).forEach(function (data) { timeStream.getData()[data.time / 1000] = data.time / 1000; }); }); return timeStream; }; Activity.prototype.getDateIndex = function (date) { // @todo ceil vs floor (still debatable) return Math.round((+date - +this.startDate) / 1000); }; Activity.prototype.toJSON = function () { var intensityZones = []; this.intensityZones.forEach(function (value) { intensityZones.push(value.toJSON()); }); var stats = {}; this.stats.forEach(function (value, key) { Object.assign(stats, value.toJSON()); }); return { startDate: this.startDate.getTime(), endDate: this.endDate.getTime(), type: this.type, creator: this.creator.toJSON(), intensityZones: intensityZones, stats: stats, events: this.getAllEvents().reduce(function (eventsArray, event) { eventsArray.push(event.toJSON()); return eventsArray; }, []), laps: this.getLaps().reduce(function (jsonLapsArray, lap) { jsonLapsArray.push(lap.toJSON()); return jsonLapsArray; }, []) }; }; Activity.TRAINER_TYPES = [ activity_types_1.ActivityTypes.VirtualRun, activity_types_1.ActivityTypes.VirtualCycling, activity_types_1.ActivityTypes.Treadmill, activity_types_1.ActivityTypes.IndoorCycling, activity_types_1.ActivityTypes.IndoorRunning, activity_types_1.ActivityTypes.IndoorRowing, activity_types_1.ActivityTypes.Crosstrainer, activity_types_1.ActivityTypes.EllipticalTrainer, activity_types_1.ActivityTypes.FitnessEquipment, activity_types_1.ActivityTypes.StairStepper ]; return Activity; }(duration_class_abstract_1.DurationClassAbstract)); exports.Activity = Activity;