|
411 | 411 | // check track validity after filtering |
412 | 412 | if (!track?.[0]?.Time) return showToast("Error in trackfile (no time or empty).", "error"); |
413 | 413 | let lastTime = 0; |
| 414 | + //const trackType = ... -> `<type>${trackType}</type>` |
414 | 415 | const gpx = `<?xml version="1.0" encoding="UTF-8"?> |
415 | 416 | <gpx creator="Bangle.js" 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 http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"> |
416 | 417 | <metadata><time>${track[0].Time.toISOString()}</time></metadata> |
417 | | - <trk><name>${title}</name><trkseg>${track.map(pt => { |
| 418 | + <metadata> |
| 419 | + <author> |
| 420 | + <name>Bangle.js</name> |
| 421 | + <link href="https://banglejs.com/apps/?id=recorder" /> |
| 422 | + </author> |
| 423 | + </metadata> |
| 424 | + <trk> |
| 425 | + <name>${title}</name> |
| 426 | + <trkseg>${track.map(pt => { |
418 | 427 | // Calculate cadence (steps per minute) from step count |
419 | 428 | // Formula: (steps in interval * 60 seconds * 1000ms) / time elapsed in ms |
420 | 429 | // Simplified to: steps * 30000 / time_ms (since 60 * 1000 / 2 = 30000) |
|
455 | 464 | return o; |
456 | 465 | } |
457 | 466 |
|
458 | | -async function downloadTrack(filename) { |
| 467 | +async function downloadTrack(filename) { // filename: string |
459 | 468 | function parse(data) { |
460 | 469 | const lines = data.trim().split("\n"), headers = lines.shift().split(","); |
461 | 470 | return lines.map(l=>trackLineToObject(headers, l)).filter(t => t.Time); |
|
478 | 487 | return document.getElementById(`track-download-${trackNumber}`).checked; |
479 | 488 | } |
480 | 489 |
|
481 | | -async function downloadTracks(tracks, saveCb) { |
| 490 | +async function downloadTracks(tracks, saveCb) { // tracks: [{ filename: string, number: number }] |
482 | 491 | for(const track of tracks){ |
483 | 492 | const lines = await downloadTrack(track.filename); |
484 | 493 | const title = `Bangle.js Track ${track.number}`; |
|
710 | 719 | if (lIdx >= 0) { |
711 | 720 | var tries = 100; |
712 | 721 | var l = data; |
713 | | - while (l && l.split(",")[lIdx]=="" && tries--) |
| 722 | + while (l && l.split(",")[lIdx]==="" && tries--) |
714 | 723 | l = f.readLine(); |
715 | 724 | if (l) data = l; |
716 | 725 | } |
|
719 | 728 | if (!trackInfo || !("headers" in trackInfo)) { |
720 | 729 | showToast("Error loading track list.", "error"); |
721 | 730 | resolve(); |
| 731 | + return; |
722 | 732 | } |
723 | 733 | trackInfo.headers = trackInfo.headers.split(","); |
724 | 734 | trackList.push({ |
@@ -842,23 +852,21 @@ <h2>Settings</h2> |
842 | 852 | attachTrackButtonListeners(trackContainer); |
843 | 853 |
|
844 | 854 | downloadTrack(track.filename).then(fullTrack => { |
845 | | - if (trackData.Latitude) { |
846 | | - const coordinates = fullTrack |
847 | | - .filter(hasValidGPS) |
848 | | - .map(pt => [parseFloat(pt.Latitude), parseFloat(pt.Longitude)]); |
849 | | - |
850 | | - if (coordinates.length > 0) { |
851 | | - createLeafletMap(`map-${track.number}`, coordinates, fullTrack); |
852 | | - |
853 | | - let distance = 0; |
854 | | - for (let i = 1; i < coordinates.length; i++) distance += L.latLng(coordinates[i-1]).distanceTo(L.latLng(coordinates[i])); |
855 | | - const duration = fullTrack[fullTrack.length-1].Time - fullTrack[0].Time; |
856 | | - const hours = Math.floor(duration / 3600000), minutes = Math.floor((duration % 3600000) / 60000); |
857 | | - const statsEl = document.getElementById(`stats-${track.number}`); |
858 | | - if (statsEl) { |
859 | | - const d = convertDistance(distance/1000); |
860 | | - statsEl.innerHTML = `<strong>Distance:</strong> ${d.value.toFixed(2)} ${d.unit} | <strong>Duration:</strong> ${hours}h ${minutes}m | <strong>Points:</strong> ${coordinates.length}`; |
861 | | - } |
| 855 | + const coordinates = fullTrack |
| 856 | + .filter(hasValidGPS) |
| 857 | + .map(pt => [parseFloat(pt.Latitude), parseFloat(pt.Longitude)]); |
| 858 | + |
| 859 | + if (coordinates.length > 0) { |
| 860 | + createLeafletMap(`map-${track.number}`, coordinates, fullTrack); |
| 861 | + |
| 862 | + let distance = 0; |
| 863 | + for (let i = 1; i < coordinates.length; i++) distance += L.latLng(coordinates[i-1]).distanceTo(L.latLng(coordinates[i])); |
| 864 | + const duration = fullTrack[fullTrack.length-1].Time - fullTrack[0].Time; |
| 865 | + const hours = Math.floor(duration / 3600000), minutes = Math.floor((duration % 3600000) / 60000); |
| 866 | + const statsEl = document.getElementById(`stats-${track.number}`); |
| 867 | + if (statsEl) { |
| 868 | + const d = convertDistance(distance/1000); |
| 869 | + statsEl.innerHTML = `<strong>Distance:</strong> ${d.value.toFixed(2)} ${d.unit} | <strong>Duration:</strong> ${hours}h ${minutes}m | <strong>Points:</strong> ${coordinates.length}`; |
862 | 870 | } |
863 | 871 | } |
864 | 872 |
|
@@ -902,18 +910,19 @@ <h2>Settings</h2> |
902 | 910 |
|
903 | 911 | if (!filename || !trackid) return; |
904 | 912 |
|
| 913 | + const tracks = [{ filename, number: trackid }]; |
905 | 914 | switch(task) { |
906 | 915 | case "delete": |
907 | 916 | await confirmDelete(button, [filename]); |
908 | 917 | break; |
909 | 918 | case "downloadkml": |
910 | | - await downloadTracks([filename], track => saveKML(track, `Bangle.js Track ${trackid}`)); |
| 919 | + await downloadTracks(tracks, track => saveKML(track, `Bangle.js Track ${trackid}`)); |
911 | 920 | break; |
912 | 921 | case "downloadgpx": |
913 | | - await downloadTracks([filename], track => saveGPX(track, `Bangle.js Track ${trackid}`)); |
| 922 | + await downloadTracks(tracks, track => saveGPX(track, `Bangle.js Track ${trackid}`)); |
914 | 923 | break; |
915 | 924 | case "downloadcsv": |
916 | | - await downloadTracks([filename], track => saveCSV(track, `Bangle.js Track ${trackid}`)); |
| 925 | + await downloadTracks(tracks, track => saveCSV(track, `Bangle.js Track ${trackid}`)); |
917 | 926 | break; |
918 | 927 | } |
919 | 928 | }); |
|
0 commit comments