Misc recorder/openstmap tweaks

master
Gordon Williams 2023-04-25 10:09:07 +01:00
parent e143dce26a
commit c7d60250a6
9 changed files with 97 additions and 26 deletions

View File

@ -17,3 +17,5 @@
Satellite count moved to widget bar to leave more room for the map
0.15: Make track drawing an option (default off)
0.16: Draw waypoints, too.
0.17: With new Recorder app allow track to be drawn in the background
Switch tile layer URL for faster/more reliable map tiles

View File

@ -5,6 +5,7 @@ var fix = {};
var mapVisible = false;
var hasScrolled = false;
var settings = require("Storage").readJSON("openstmap.json",1)||{};
var plotTrack;
// Redraw the whole page
function redraw() {
@ -20,7 +21,9 @@ function redraw() {
}
if (HASWIDGETS && WIDGETS["recorder"] && WIDGETS["recorder"].plotTrack) {
g.setColor("#f00").flip(); // force immediate draw on double-buffered screens - track will update later
WIDGETS["recorder"].plotTrack(m);
plotTrack = WIDGETS["recorder"].plotTrack(m, { async : true, callback : function() {
plotTrack = undefined;
}});
}
}
g.setClipRect(0,0,g.getWidth()-1,g.getHeight()-1);
@ -79,6 +82,7 @@ function showMap() {
g.reset().clearRect(R);
redraw();
Bangle.setUI({mode:"custom",drag:e=>{
if (plotTrack && plotTrack.stop) plotTrack.stop();
if (e.b) {
g.setClipRect(R.x,R.y,R.x2,R.y2);
g.scroll(e.dx,e.dy);
@ -90,6 +94,7 @@ function showMap() {
redraw();
}
}, btn: btn=>{
if (plotTrack && plotTrack.stop) plotTrack.stop();
mapVisible = false;
var menu = {"":{title:"Map"},
"< Back": ()=> showMap(),

View File

@ -87,8 +87,8 @@ TODO:
However some don't allow cross-origin use */
//var TILELAYER = 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png'; // simple, high contrast, TOO SLOW
//var TILELAYER = 'http://a.tile.stamen.com/toner/{z}/{x}/{y}.png'; // black and white
var TILELAYER = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var PREVIEWTILELAYER = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var TILELAYER = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
var PREVIEWTILELAYER = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
var loadedMaps = [];

View File

@ -2,7 +2,7 @@
"id": "openstmap",
"name": "OpenStreetMap",
"shortName": "OpenStMap",
"version": "0.16",
"version": "0.17",
"description": "Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are. Once installed this also adds map functionality to `GPS Recorder` and `Recorder` apps",
"readme": "README.md",
"icon": "app.png",

View File

@ -26,3 +26,6 @@
0.20: Automatic translation of some more strings.
0.21: Speed report now uses speed units from locale
0.22: Convert Yes/No On/Off in settings to checkboxes
0.23: Add graphing for HRM, fix some other graphs
Altitude graphing now uses barometer altitude if it exists
plotTrack in widget allows track to be drawn in the background (doesn't block execution)

View File

@ -20,10 +20,29 @@ You can record
* **BAT** Battery percentage and voltage
* **Core** CoreTemp body temperature
You can then start/stop recording from the Recorder app itself (and as long as widgets are
enabled in the app you're using, you can move to another app and continue recording).
Some apps like the [Run app](https://banglejs.com/apps/?id=run) are able to automatically start/stop the Recorder too.
**Note:** It is possible for other apps to record information using this app
as well. They need to define a `foobar.recorder.js` file - see the `getRecorders`
function in `widget.js` for more information.
## Graphing
You can download the information to the PC using [the App Loader](https://banglejs.com/apps/?id=recorder). Connect
to your Bangle, then in `My Apps` click the disk icon next to the `Recorder` app to download data.
You can also view some information on the watch.
* Tap `View Tracks`
* Tap on the Track number you're interested in, and you'll see a page with information about that track...
* `Plot Map` plots a map using GPS coordinates
* `Plot OpenStMap` plots a map using GPS coordinates on top of an OpenStreetMap map (if the app is installed)
* `Plot Alt` plots altitude over time
* `Plot Speed` plots speed over time
* `Plot HRM` plots heart rate over time
## Tips
When recording GPS, it usually takes several minutes for the watch to get a [GPS fix](https://en.wikipedia.org/wiki/Time_to_first_fix). There is a red satellite symbol, which you will see turn green when you get an actual GPS Fix. You can [upload assistant files](https://banglejs.com/apps/#assisted%20gps%20update) to speed up the time spent on getting a GPS fix.

View File

@ -60,9 +60,9 @@ function showMainMenu() {
setTimeout(function() {
E.showMenu();
WIDGETS["recorder"].setRecording(v).then(function() {
print(/*LANG*/"Complete");
//print("Record start Complete");
loadSettings();
print(settings.recording);
print("Recording: "+settings.recording);
showMainMenu();
});
}, 1);
@ -185,7 +185,7 @@ function viewTrack(filename, info) {
'': { 'title': /*LANG*/'Track '+info.fn }
};
if (info.time)
menu[info.time.toISOString().substr(0,16).replace("T"," ")] = function(){};
menu[info.time.toISOString().substr(0,16).replace("T"," ")] = {};
menu["Duration"] = { value : asTime(info.duration)};
menu["Records"] = { value : ""+info.records };
if (info.fields.includes("Latitude"))
@ -198,7 +198,8 @@ function viewTrack(filename, info) {
info.qOSTM = true;
plotTrack(info);
}
if (info.fields.includes("Altitude"))
if (info.fields.includes("Altitude") ||
info.fields.includes("Barometer Altitude"))
menu[/*LANG*/'Plot Alt.'] = function() {
plotGraph(info, "Altitude");
};
@ -206,6 +207,10 @@ function viewTrack(filename, info) {
menu[/*LANG*/'Plot Speed'] = function() {
plotGraph(info, "Speed");
};
if (info.fields.includes("Heartrate"))
menu[/*LANG*/'Plot HRM'] = function() {
plotGraph(info, "Heartrate");
};
// TODO: steps, heart rate?
menu[/*LANG*/'Erase'] = function() {
E.showPrompt(/*LANG*/"Delete Track?").then(function(v) {
@ -331,14 +336,26 @@ function viewTrack(filename, info) {
var l = f.readLine(f);
l = f.readLine(f); // skip headers
var nl = 0, c, i;
var factor = 1; // multiplier used for values when graphing
var timeIdx = info.fields.indexOf("Time");
if (l!==undefined) {
c = l.split(",");
strt = c[timeIdx];
}
if (style=="Altitude") {
title = /*LANG*/"Altitude (m)";
var altIdx = info.fields.indexOf("Altitude");
if (style=="Heartrate") {
title = /*LANG*/"Heartrate (bpm)";
var hrmIdx = info.fields.indexOf("Heartrate");
while(l!==undefined) {
++nl;c=l.split(",");l = f.readLine(f);
if (c[hrmIdx]=="") continue;
i = Math.round(80*(c[timeIdx] - strt)/dur);
infn[i]+=+c[hrmIdx];
infc[i]++;
}
} else if (style=="Altitude") {
title = /*LANG*/"Altitude (m)";
var altIdx = info.fields.indexOf("Barometer Altitude");
if (altIdx<0) altIdx = info.fields.indexOf("Altitude");
while(l!==undefined) {
++nl;c=l.split(",");l = f.readLine(f);
if (c[altIdx]=="") continue;
@ -350,7 +367,7 @@ function viewTrack(filename, info) {
// use locate to work out units
var localeStr = require("locale").speed(1,5); // get what 1kph equates to
let units = localeStr.replace(/[0-9.]*/,"");
var factor = parseFloat(localeStr)*3.6; // m/sec to whatever out units are
factor = parseFloat(localeStr)*3.6; // m/sec to whatever out units are
// title
title = /*LANG*/"Speed"+` (${units})`;
var latIdx = info.fields.indexOf("Latitude");
@ -386,6 +403,10 @@ function viewTrack(filename, info) {
var min=100000,max=-100000;
for (var i=0;i<infn.length;i++) {
if (infc[i]>0) infn[i]=factor*infn[i]/infc[i];
else { // no data - search back and see if we can find something
for (var j=i-1;j>=0;j--)
if (infc[j]) { infn[i]=infn[j]; break; }
}
var n = infn[i];
if (n>max) max=n;
if (n<min) min=n;

View File

@ -2,7 +2,7 @@
"id": "recorder",
"name": "Recorder",
"shortName": "Recorder",
"version": "0.22",
"version": "0.23",
"description": "Record GPS position, heart rate and more in the background, then download to your PC.",
"icon": "app.png",
"tags": "tool,outdoors,gps,widget",

View File

@ -265,8 +265,14 @@
updateSettings(settings);
WIDGETS["recorder"].reload();
return Promise.resolve(settings.recording);
},plotTrack:function(m) { // m=instance of openstmap module
// Plots the current track in the currently set color
},plotTrack:function(m, options) { // m=instance of openstmap module
/* Plots the current track in the currently set color.
options can be {
async: if true, plots the path a bit at a time - returns an object with a 'stop' function to stop
callback: a function to call back when plotting is finished
}
*/
options = options||{};
if (!activeRecorders.length) return; // not recording
var settings = loadSettings();
// keep function to draw track in RAM
@ -282,19 +288,34 @@
c = l.split(",");
l = f.readLine(f);
}
if (l===undefined) return; // empty file?
mp = m.latLonToXY(+c[la], +c[lo]);
g.moveTo(mp.x,mp.y);
l = f.readLine(f);
var n = 200; // only plot first 200 points to keep things fast(ish)
while(l && n--) {
c = l.split(",");
if (c[la]) {
mp = m.latLonToXY(+c[la], +c[lo]);
g.lineTo(mp.x,mp.y);
}
var asyncTimeout;
function plotPartial() {
asyncTimeout = undefined;
if (l===undefined) return; // empty file?
mp = m.latLonToXY(+c[la], +c[lo]);
g.moveTo(mp.x,mp.y);
l = f.readLine(f);
var n = options.async ? 50 : 200; // only plot first 200 points to keep things fast(ish)
while(l && n--) {
c = l.split(",");
if (c[la]) {
mp = m.latLonToXY(+c[la], +c[lo]);
g.lineTo(mp.x,mp.y);
}
l = f.readLine(f);
}
if (options.async && n<0)
asyncTimeout = setTimeout(plotPartial, 20);
else if (options.callback) options.callback();
}
plotPartial();
if (options.async) return {
stop : function() {
if (asyncTimeout) clearTimeout(asyncTimeout);
asyncTimeout = undefined;
if (options.callback) options.callback();
}
};
}
plot(g);
}};