Misc recorder/openstmap tweaks
parent
e143dce26a
commit
c7d60250a6
|
|
@ -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
|
||||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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 = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}};
|
||||
|
|
|
|||
Loading…
Reference in New Issue