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

103 lines (102 loc) 5.02 kB
"use strict"; 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, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&apos;'); } } exports.RouteExporterGPX = RouteExporterGPX;