commit 9d3c908e4737c9e60b71e73b37078ef4f710cc05
parent 309c261f0a86bb4c7fea32a29c196c09c2d0c37c
Author: Sergey Orlov <wladimirych@gmail.com>
Date: Fri, 22 May 2020 09:43:29 +0200
track list: add feature: save GPX with added elevations, fixes #298
Diffstat:
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/src/lib/leaflet.control.track-list/lib/geo_file_exporters.js b/src/lib/leaflet.control.track-list/lib/geo_file_exporters.js
@@ -2,7 +2,7 @@ import utf8 from 'utf8';
import escapeHtml from 'escape-html';
import {saveNktk} from './parsers/nktk';
-function saveGpx(segments, name, points, withElevations=false) {
+function saveGpx(segments, name, points, withElevations = false) {
const gpx = [];
const fakeTime = '1970-01-01T00:00:01.000Z';
@@ -18,7 +18,7 @@ function saveGpx(segments, name, points, withElevations=false) {
label = utf8.encode(label);
gpx.push(`\t<wpt lat="${marker.latlng.lat.toFixed(6)}" lon="${marker.latlng.lng.toFixed(6)}">`);
gpx.push(`\t\t<name>${label}</name>`);
- if (withElevations) {
+ if (withElevations && marker.latlng.alt !== null) {
gpx.push(`\t\t<ele>${marker.latlng.alt.toFixed(1)}</ele>`);
}
gpx.push('\t</wpt>');
@@ -36,7 +36,8 @@ function saveGpx(segments, name, points, withElevations=false) {
for (let point of segment) {
let x = point.lng.toFixed(6);
let y = point.lat.toFixed(6);
- const elevation = withElevations ? `<ele>${point.alt.toFixed(1)}</ele>ele>` : '';
+ const elevation = (withElevations && point.alt !== null)
+ ? `<ele>${point.alt.toFixed(1)}</ele>` : '';
// time element is not necessary, added for compatibility to Garmin Connect only
gpx.push(`\t\t\t<trkpt lat="${y}" lon="${x}"><time>${fakeTime}</time>${elevation}</trkpt>`);
}
@@ -48,6 +49,10 @@ function saveGpx(segments, name, points, withElevations=false) {
return gpx.join('\n');
}
+function saveGpxWithElevations(segments, name, points) {
+ return saveGpx(segments, name, points, true);
+}
+
function saveKml(segments, name, points) {
const kml = [];
@@ -99,5 +104,5 @@ function saveKml(segments, name, points) {
return kml.join('\n');
}
-export default {saveGpx, saveKml, saveToString: saveNktk};
+export default {saveGpx, saveGpxWithElevations, saveKml, saveToString: saveNktk};
diff --git a/src/lib/leaflet.control.track-list/track-list.js b/src/lib/leaflet.control.track-list/track-list.js
@@ -25,6 +25,7 @@ import config from '~/config';
import md5 from 'blueimp-md5';
import {wrapLatLngToTarget, wrapLatLngBoundsToTarget} from '~/lib/leaflet.fixes/fixWorldCopyJump';
import {splitLinesAt180Meridian} from "./lib/meridian180";
+import {ElevationProvider} from '~/lib/elevations';
const TRACKLIST_TRACK_COLORS = ['#77f', '#f95', '#0ff', '#f77', '#f7f', '#ee5'];
@@ -454,6 +455,11 @@ L.Control.TrackList = L.Control.extend({
{text: 'Save as GPX', callback: this.saveTrackAsFile.bind(this, track, geoExporters.saveGpx, '.gpx')},
{text: 'Save as KML', callback: this.saveTrackAsFile.bind(this, track, geoExporters.saveKml, '.kml')},
{text: 'Copy link for track', callback: this.copyTrackLinkToClipboard.bind(this, track)},
+ {text: 'Extra', separator: true},
+ {
+ text: 'Save as GPX with added elevation (SRTM)',
+ callback: this.saveTrackAsFile.bind(this, track, geoExporters.saveGpxWithElevations, '.gpx', true),
+ },
];
track._actionsMenu = new Contextmenu(items);
},
@@ -533,7 +539,7 @@ L.Control.TrackList = L.Control.extend({
this.copyTracksLinkToClipboard([track], mouseEvent);
},
- saveTrackAsFile: function(track, exporter, extension) {
+ saveTrackAsFile: async function(track, exporter, extension, addElevations = false) {
this.stopActiveDraw();
var lines = this.getTrackPolylines(track)
.map(function(line) {
@@ -553,6 +559,36 @@ L.Control.TrackList = L.Control.extend({
return;
}
+ if (addElevations) {
+ const request = [
+ ...points.map((p) => p.latlng),
+ ...lines.reduce((acc, cur) => {
+ acc.push(...cur);
+ return acc;
+ }, [])
+ ];
+ let elevations;
+ try {
+ elevations = await new ElevationProvider().get(request);
+ } catch (e) {
+ logging.captureException(e, 'error getting elevation for gpx');
+ notify(`Failed to get elevation data: ${e.message}`);
+ }
+ let n = 0;
+ for (let p of points) {
+ // we make copy of latlng as we are changing it
+ p.latlng = L.latLng(p.latlng.lat, p.latlng.lng, elevations[n]);
+ n += 1;
+ }
+ for (let line of lines) {
+ for (let p of line) {
+ // we do not need to create new LatLng since splitLinesAt180Meridian() have already done it
+ p.alt = elevations[n];
+ n += 1;
+ }
+ }
+ }
+
var fileText = exporter(lines, name, points);
var filename = name + extension;
saveAs(blobFromString(fileText), filename, true);