BangleApps/apps/waypointer/app.js

296 lines
7.2 KiB
JavaScript
Raw Normal View History

2022-03-23 20:52:26 +00:00
const scale = g.getWidth()/240;
var pal_by = new Uint16Array([g.getBgColor(),0xFFC0],0,1); // black, yellow
var pal_bw = new Uint16Array([g.getBgColor(),g.getColor()],0,1); // black, white
var pal_bb = new Uint16Array([g.getBgColor(),0x07ff],0,1); // black, blue
2021-02-25 19:51:35 +00:00
// having 3 2 color pallette keeps the memory requirement lower
2022-03-23 20:52:26 +00:00
var buf1 = Graphics.createArrayBuffer(160*scale,160*scale,1, {msb:true});
var buf2 = Graphics.createArrayBuffer(g.getWidth()/3,40*scale,1, {msb:true});
var arrow_img = require("heatshrink").decompress(atob("lEowIPMjAEDngEDvwED/4DCgP/wAEBgf/4AEBg//8AEBh//+AEBj///AEBn///gEBv///wmCAAImCAAIoBFggE/AkaaEABo="));
2021-02-25 19:51:35 +00:00
var settings = Object.assign({
// default values
smoothDirection: true,
}, require('Storage').readJSON("waypointer.json", true) || {});
2021-02-25 19:51:35 +00:00
function flip1(x,y) {
2022-03-23 20:52:26 +00:00
g.drawImage({width:160*scale,height:160*scale,bpp:1,buffer:buf1.buffer, palette:pal_by},x,y);
2021-02-25 19:51:35 +00:00
buf1.clear();
}
function flip2_bw(x,y) {
2022-03-23 20:52:26 +00:00
g.drawImage({width:g.getWidth()/3,height:40*scale,bpp:1,buffer:buf2.buffer, palette:pal_bw},x,y);
2021-02-25 19:51:35 +00:00
buf2.clear();
}
function flip2_bb(x,y) {
2022-03-23 20:52:26 +00:00
g.drawImage({width:g.getWidth()/3,height:40*scale,bpp:1,buffer:buf2.buffer, palette:pal_bb},x,y);
2021-02-25 19:51:35 +00:00
buf2.clear();
}
var candraw = true;
var wp_bearing = 0;
var direction = 0;
var wpindex=0;
var loc = require("locale");
var selected = false;
var previous = {
bs: '',
dst: '',
wp_name: '',
course: 0,
selected: false,
};
// clear the attributes that control the display refresh
function clear_previous() {
previous.bs = '-';
previous.dst = '-';
previous.wp_name = '-';
previous.course = -999;
2021-03-01 11:47:58 +00:00
}
2021-02-25 19:51:35 +00:00
function drawCompass(course) {
if(!candraw) return;
if (Math.abs(previous.course - course) < 9) return; // reduce number of draws due to compass jitter
2021-02-25 19:51:35 +00:00
previous.course = course;
2021-02-25 19:51:35 +00:00
buf1.setColor(1);
2022-03-23 20:52:26 +00:00
buf1.fillCircle(buf1.getWidth()/2,buf1.getHeight()/2,79*scale);
2021-02-25 19:51:35 +00:00
buf1.setColor(0);
2022-03-23 20:52:26 +00:00
buf1.fillCircle(buf1.getWidth()/2,buf1.getHeight()/2,69*scale);
2021-02-25 19:51:35 +00:00
buf1.setColor(1);
2022-03-23 20:52:26 +00:00
buf1.drawImage(arrow_img, buf1.getWidth()/2, buf1.getHeight()/2, {scale:3*scale, rotate:radians(course)} );
flip1(40*scale, Bangle.appRect.y+6*scale);
2021-02-25 19:51:35 +00:00
}
/***** COMPASS CODE ***********/
var heading = 0;
function newHeading(m,h){
2021-02-25 19:51:35 +00:00
var s = Math.abs(m - h);
var delta = (m>h)?1:-1;
if (s>=180){s=360-s; delta = -delta;}
2021-02-25 19:51:35 +00:00
if (s<2) return h;
var hd;
if (settings.smoothDirection) {
hd = h + delta*(1 + Math.round(s/5));
} else {
hd = h + delta*s;
}
2021-02-25 19:51:35 +00:00
if (hd<0) hd+=360;
if (hd>360)hd-= 360;
return hd;
}
var CALIBDATA = require("Storage").readJSON("magnav.json",1) || {};
let tiltfixread;
try {
tiltfixread = require("magnav").tiltfixread;
} catch(e) {
// magnav not installed
2021-02-25 19:51:35 +00:00
}
// Note actual mag is 360-m, error in firmware
function read_compass() {
let d;
if (tiltfixread === undefined || CALIBDATA.offset === undefined || CALIBDATA.scale === undefined) {
// magnav not installed or no valid calibration, use built in
d = Bangle.getCompass().heading;
} else {
d = tiltfixread(CALIBDATA.offset,CALIBDATA.scale);
}
if (isNaN(d)) return; // built in compass heading can return NaN when uncalibrated
2021-02-25 19:51:35 +00:00
heading = newHeading(d,heading);
direction = wp_bearing - heading;
if (direction < 0) direction += 360;
if (direction > 360) direction -= 360;
drawCompass(direction);
}
/***** END Compass ***********/
2024-03-04 20:34:50 +00:00
//var speed = 0;
//var satellites = 0;
2021-02-25 19:51:35 +00:00
var wp;
var dist=0;
function radians(a) {
return a*Math.PI/180;
}
function degrees(a) {
var d = a*180/Math.PI;
return (d+360)%360;
}
function bearing(a,b){
var delta = radians(b.lon-a.lon);
var alat = radians(a.lat);
var blat = radians(b.lat);
var y = Math.sin(delta) * Math.cos(blat);
var x = Math.cos(alat)*Math.sin(blat) -
Math.sin(alat)*Math.cos(blat)*Math.cos(delta);
return Math.round(degrees(Math.atan2(y, x)));
}
function distance(a,b){
var x = radians(a.lon-b.lon) * Math.cos(radians((a.lat+b.lat)/2));
var y = radians(b.lat-a.lat);
return Math.round(Math.sqrt(x*x + y*y) * 6371000);
}
function drawN(){
2022-03-23 20:52:26 +00:00
buf2.setFont("Vector",24*scale);
2021-02-25 19:51:35 +00:00
var bs = wp_bearing.toString();
bs = wp_bearing<10?"00"+bs : wp_bearing<100 ?"0"+bs : bs;
var dst = loc.distance(dist);
2021-02-25 19:51:35 +00:00
// -1=left (default), 0=center, 1=right
2021-02-25 19:51:35 +00:00
// show distance on the left
if (previous.dst !== dst) {
2022-03-23 20:52:26 +00:00
previous.dst = dst;
2021-02-25 19:51:35 +00:00
buf2.setColor(1);
buf2.setFontAlign(-1,-1);
2022-03-23 20:52:26 +00:00
buf2.setFont("Vector", 20*scale);
2021-02-25 19:51:35 +00:00
buf2.drawString(dst,0,0);
2022-03-23 20:52:26 +00:00
flip2_bw(0, g.getHeight()-40*scale);
2021-02-25 19:51:35 +00:00
}
2021-02-25 19:51:35 +00:00
// bearing, place in middle at bottom of compass
if (previous.bs !== bs) {
previous.bs = bs;
buf2.setColor(1);
buf2.setFontAlign(0, -1);
2022-03-23 20:52:26 +00:00
buf2.setFont("Vector",38*scale);
buf2.drawString(bs,40*scale,0);
flip2_bw(g.getWidth()/3, g.getHeight()-40*scale);
2021-02-25 19:51:35 +00:00
}
// waypoint name on right
if (previous.wp_name !== wp.name || previous.selected !== selected) {
previous.selected = selected;
buf2.setColor(1);
buf2.setFontAlign(1,-1); // right, bottom
2022-03-23 20:52:26 +00:00
buf2.setFont("Vector", 20*scale);
buf2.drawString(wp.name, 80*scale, 0);
2021-02-25 19:51:35 +00:00
if (selected)
2022-03-23 20:52:26 +00:00
flip2_bw(g.getWidth()/3*2, g.getHeight()-40*scale);
2021-02-25 19:51:35 +00:00
else
2022-03-23 20:52:26 +00:00
flip2_bb(g.getWidth()/3*2, g.getHeight()-40*scale);
2021-02-25 19:51:35 +00:00
}
}
var savedfix;
function onGPS(fix) {
savedfix = fix;
2024-03-04 20:34:50 +00:00
/*if (fix!==undefined){
2021-02-25 19:51:35 +00:00
satellites = fix.satellites;
2024-03-04 20:34:50 +00:00
}*/
2021-02-25 19:51:35 +00:00
if (candraw) {
if (fix!==undefined && fix.fix==1){
dist = distance(fix,wp);
if (isNaN(dist)) dist = 0;
wp_bearing = bearing(fix,wp);
if (isNaN(wp_bearing)) wp_bearing = 0;
drawN();
}
}
}
var intervalRef;
function stopdraw() {
candraw=false;
2024-03-13 10:51:40 +00:00
//prev_course = -1;
2021-02-25 19:51:35 +00:00
if(intervalRef) {clearInterval(intervalRef);}
}
function startTimers() {
candraw=true;
2024-03-13 10:51:40 +00:00
/*intervalRefSec =*/ setInterval(function() {
2021-02-25 19:51:35 +00:00
read_compass();
}, 500);
}
function drawAll(){
g.setColor(1,1,1);
drawN();
drawCompass(direction);
}
function startdraw(){
g.clear();
Bangle.drawWidgets();
startTimers();
candraw=true;
drawAll();
}
function setButtons(){
2022-03-23 20:52:26 +00:00
Bangle.setUI("updown", d=>{
if (d<0) { nextwp(-1); }
else if (d>0) { nextwp(1); }
else { doselect(); }
});
2021-02-25 19:51:35 +00:00
}
2021-02-25 19:51:35 +00:00
Bangle.on('lcdPower',function(on) {
if (on) {
clear_previous();
startdraw();
} else {
stopdraw();
}
});
var waypoints = require("waypoints").load();
2021-02-25 19:51:35 +00:00
wp=waypoints[0];
function nextwp(inc){
if (!selected) return;
wpindex+=inc;
if (wpindex>=waypoints.length) wpindex=0;
if (wpindex<0) wpindex = waypoints.length-1;
wp = waypoints[wpindex];
drawN();
}
function doselect(){
2022-10-04 15:42:08 +00:00
if (selected && wpindex>=0 && waypoints[wpindex].lat===undefined && savedfix.fix) {
2021-02-25 19:51:35 +00:00
waypoints[wpindex] ={name:"@"+wp.name, lat:savedfix.lat, lon:savedfix.lon};
wp = waypoints[wpindex];
require("waypoints").save(waypoints);
2021-02-25 19:51:35 +00:00
}
if (selected) {
Bangle.resetCompass(); // reset built in compass when a waypoint is selected
}
2021-02-25 19:51:35 +00:00
selected=!selected;
drawN();
}
Bangle.on('kill',()=>{
Bangle.setCompassPower(0);
Bangle.setGPSPower(0);
});
g.clear();
Bangle.setLCDBrightness(1);
Bangle.loadWidgets();
Bangle.drawWidgets();
// load widgets can turn off GPS
Bangle.setGPSPower(1);
Bangle.setCompassPower(1);
Bangle.resetCompass() // reset built in compass on start in case we are not using tilt compensation
2021-02-25 19:51:35 +00:00
drawAll();
startTimers();
Bangle.on('GPS', onGPS);
setButtons();