@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
103 lines (102 loc) • 5.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RouteExporterGPX = void 0;
const activity_types_1 = require("../../../activities/activity.types");
class RouteExporterGPX {
constructor() {
this.fileType = 'application/gpx+xml';
this.fileExtension = 'gpx';
}
static getAsString(routeFile) {
return new RouteExporterGPX().getAsString(routeFile);
}
getAsString(routeFile) {
return new Promise(resolve => {
resolve(this.export(routeFile));
});
}
export(routeFile) {
const metadataTime = routeFile.createdAt ? `<time>${this.escapeXml(routeFile.createdAt.toISOString())}</time>` : '';
const waypoints = routeFile
.getWaypoints()
.map(waypoint => this.getWaypointXml(waypoint, 'wpt'))
.join('');
const routes = routeFile
.getRoutes()
.map(route => {
const name = route.name ? `<name>${this.escapeXml(route.name)}</name>` : '';
const comment = route.comment ? `<cmt>${this.escapeXml(route.comment)}</cmt>` : '';
const description = route.description ? `<desc>${this.escapeXml(route.description)}</desc>` : '';
const number = route.number !== null ? `<number>${route.number}</number>` : '';
const links = route.links.map(link => this.getLinkXml(link)).join('');
const type = route.activityType && route.activityType !== activity_types_1.ActivityTypes.route
? `<type>${this.escapeXml(route.activityType)}</type>`
: '';
const extensions = this.getExtensionsXml(route.extensions);
const points = route
.getPointData()
.map(point => this.getWaypointXml(point, 'rtept'))
.join('');
return `<rte>${name}${comment}${description}${number}${links}${type}${extensions}${points}</rte>`;
})
.join('');
return [
'<?xml version="1.0" encoding="UTF-8"?>',
`<gpx creator="${this.escapeXml(routeFile.creator.name)}" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">`,
`<metadata><name>${this.escapeXml(routeFile.name)}</name>${metadataTime}</metadata>`,
waypoints,
routes,
'</gpx>'
].join('');
}
getWaypointXml(point, tagName) {
const altitude = Number.isFinite(point.altitude) ? `<ele>${point.altitude}</ele>` : '';
const name = point.name ? `<name>${this.escapeXml(point.name)}</name>` : '';
const comment = point.comment ? `<cmt>${this.escapeXml(point.comment)}</cmt>` : '';
const description = point.description ? `<desc>${this.escapeXml(point.description)}</desc>` : '';
const symbol = point.symbol ? `<sym>${this.escapeXml(point.symbol)}</sym>` : '';
const type = point.type ? `<type>${this.escapeXml(point.type)}</type>` : '';
const links = (point.links || []).map(link => this.getLinkXml(link)).join('');
const extensions = this.getExtensionsXml(point.extensions);
return `<${tagName} lat="${point.latitudeDegrees}" lon="${point.longitudeDegrees}">${altitude}${name}${comment}${description}${symbol}${type}${links}${extensions}</${tagName}>`;
}
getLinkXml(link) {
const text = link.text ? `<text>${this.escapeXml(link.text)}</text>` : '';
const type = link.type ? `<type>${this.escapeXml(link.type)}</type>` : '';
return `<link href="${this.escapeXml(link.href)}">${text}${type}</link>`;
}
getExtensionsXml(extensions) {
const innerXml = this.getUnknownExtensionXml(extensions);
return innerXml ? `<extensions>${innerXml}</extensions>` : '';
}
getUnknownExtensionXml(value, tagName) {
if (value === null || value === undefined) {
return '';
}
if (Array.isArray(value)) {
return value.map(item => this.getUnknownExtensionXml(item, tagName)).join('');
}
if (typeof value !== 'object') {
return tagName ? `<${tagName}>${this.escapeXml(String(value))}</${tagName}>` : '';
}
const children = Object.keys(value)
.map(key => {
const childValue = value[key];
if (!Array.isArray(childValue)) {
return '';
}
return childValue.map(item => this.getUnknownExtensionXml(item, key)).join('');
})
.join('');
return tagName ? `<${tagName}>${children}</${tagName}>` : children;
}
escapeXml(value) {
return value
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
}
exports.RouteExporterGPX = RouteExporterGPX;