@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
186 lines (185 loc) • 7.87 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Route = void 0;
const creator_1 = require("../creators/creator");
const data_latitude_degrees_1 = require("../data/data.latitude-degrees");
const data_longitude_degrees_1 = require("../data/data.longitude-degrees");
const data_altitude_1 = require("../data/data.altitude");
const helpers_1 = require("../events/utilities/helpers");
const stats_class_abstract_1 = require("../stats/stats.class.abstract");
const route_parsing_options_1 = require("./route-parsing-options");
const route_stream_1 = require("./route-stream");
class Route extends stats_class_abstract_1.StatsClassAbstract {
constructor(creator = new creator_1.Creator('Unknown Device'), options = route_parsing_options_1.RouteParsingOptions.DEFAULT, name = null, activityType = null, points = [], metadata = {}) {
var _a;
super();
this.streams = [];
this.points = [];
this.creator = creator;
this.parseOptions = options;
this.name = name;
this.activityType = activityType;
this.points = points;
this.comment = metadata.comment || null;
this.description = metadata.description || null;
this.number = (_a = metadata.number) !== null && _a !== void 0 ? _a : null;
this.links = metadata.links || [];
this.extensions = metadata.extensions;
}
createStream(type, length = this.getPointCount()) {
return new route_stream_1.RouteStream(type, Array(length).fill(null));
}
addDataToStream(type, index, value) {
this.getStreamData(type)[index] = value;
return this;
}
addStream(stream) {
if (this.streams.find(routeStream => routeStream.type === stream.type)) {
throw new Error(`Duplicate type of stream when adding ${stream.type} to route ${this.getID()}`);
}
this.streams.push(stream);
return this;
}
addStreams(streams) {
const existingTypes = new Set(this.streams.map(stream => stream.type));
streams.forEach(stream => {
if (existingTypes.has(stream.type)) {
return;
}
this.streams.push(stream);
existingTypes.add(stream.type);
});
return this;
}
clearStreams() {
this.streams = [];
return this;
}
removeStream(streamType) {
const stream = streamType instanceof route_stream_1.RouteStream ? streamType : this.getStream(streamType);
this.streams = this.streams.filter(routeStream => stream !== routeStream);
return this;
}
replaceStreamData(streamType, data) {
this.removeStream(streamType);
this.addStream(this.createStream(streamType, data.length).setData(data));
return this;
}
getAllStreams() {
return this.streams;
}
getAllExportableStreams() {
return this.getAllStreams().filter(stream => stream.isExportable());
}
getStream(streamType) {
const find = this.streams.find(stream => stream.type === streamType);
if (!find) {
throw Error(`No route stream found with type ${streamType}`);
}
return find;
}
hasStreamData(streamType) {
try {
this.getStreamData(streamType);
}
catch (_e) {
return false;
}
return true;
}
getStreamData(streamType) {
const stream = streamType instanceof route_stream_1.RouteStream ? streamType : this.getStream(streamType);
return stream.getData();
}
getSquashedStreamData(streamType) {
return this.getStreamData(streamType).filter(data => (0, helpers_1.isNumber)(data));
}
hasPositionData() {
return this.hasStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type) && this.hasStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type);
}
getPositionData() {
const latitudeStreamData = this.hasStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type)
? this.getStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type)
: [];
const longitudeStreamData = this.hasStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type)
? this.getStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type)
: [];
return Array.from({ length: this.getPointCount() }).reduce((positionArray, _value, index) => {
const currentLatitude = latitudeStreamData[index];
const currentLongitude = longitudeStreamData[index];
if (!(0, helpers_1.isNumber)(currentLatitude) || !(0, helpers_1.isNumber)(currentLongitude)) {
positionArray.push(null);
return positionArray;
}
positionArray.push({
latitudeDegrees: currentLatitude,
longitudeDegrees: currentLongitude
});
return positionArray;
}, []);
}
getSquashedPositionData() {
return this.getPositionData().filter(data => data !== null);
}
getPointData() {
const latitudeStreamData = this.hasStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type)
? this.getStreamData(data_latitude_degrees_1.DataLatitudeDegrees.type)
: [];
const longitudeStreamData = this.hasStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type)
? this.getStreamData(data_longitude_degrees_1.DataLongitudeDegrees.type)
: [];
const altitudeStreamData = this.hasStreamData(data_altitude_1.DataAltitude.type) ? this.getStreamData(data_altitude_1.DataAltitude.type) : [];
return Array.from({ length: this.getPointCount() }).reduce((pointData, _value, index) => {
var _a;
const sourcePoint = this.points[index] || {};
const latitude = (0, helpers_1.isNumber)(latitudeStreamData[index])
? latitudeStreamData[index]
: sourcePoint.latitudeDegrees;
const longitude = (0, helpers_1.isNumber)(longitudeStreamData[index])
? longitudeStreamData[index]
: sourcePoint.longitudeDegrees;
if (!(0, helpers_1.isNumber)(latitude) || !(0, helpers_1.isNumber)(longitude)) {
return pointData;
}
pointData.push(Object.assign(Object.assign({}, sourcePoint), { latitudeDegrees: latitude, longitudeDegrees: longitude, altitude: (0, helpers_1.isNumber)(altitudeStreamData[index])
? altitudeStreamData[index]
: ((_a = sourcePoint.altitude) !== null && _a !== void 0 ? _a : null) }));
return pointData;
}, []);
}
setPoints(points) {
this.points = points;
return this;
}
getPointCount() {
return Math.max(this.points.length, this.streams.reduce((length, stream) => Math.max(length, stream.getData().length), 0));
}
toJSON() {
const stats = {};
this.stats.forEach((value) => {
Object.assign(stats, value.toJSON());
});
const routeJSON = {
name: this.name || null,
activityType: this.activityType,
comment: this.comment,
description: this.description,
number: this.number,
links: this.links,
extensions: this.extensions,
creator: this.creator.toJSON(),
stats,
streams: this.getAllStreams().reduce((streams, stream) => {
streams.push(stream.toJSON());
return streams;
}, []),
points: this.getPointData()
};
const id = this.getID();
if (id) {
routeJSON.id = id;
}
return routeJSON;
}
}
exports.Route = Route;