Big refactor to attempt to merge all the waypoints code into one place. At least 3 apps had basically identical interface.html files, and yet wpmoto had a great map-based editor.
parent
e9fdb1dee5
commit
91728c147f
|
|
@ -3,4 +3,4 @@
|
||||||
0.03: Add Waypoint Editor
|
0.03: Add Waypoint Editor
|
||||||
0.04: Fix great circle formula
|
0.04: Fix great circle formula
|
||||||
0.05: Use locale for speed and distance + fix Vector font sizes
|
0.05: Use locale for speed and distance + fix Vector font sizes
|
||||||
|
0.06: Move waypoints.json (and editor) to 'waypoints' app
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ Bangle.on('lcdPower',function(on) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var waypoints = require("Storage").readJSON("waypoints.json")||[{name:"NONE"}];
|
var waypoints = require("waypoints").load();
|
||||||
wp=waypoints[0];
|
wp=waypoints[0];
|
||||||
|
|
||||||
function nextwp(inc){
|
function nextwp(inc){
|
||||||
|
|
@ -223,7 +223,7 @@ function doselect(){
|
||||||
if (selected && wpindex!=0 && waypoints[wpindex].lat===undefined && savedfix.fix) {
|
if (selected && wpindex!=0 && waypoints[wpindex].lat===undefined && savedfix.fix) {
|
||||||
waypoints[wpindex] ={name:"@"+wp.name, lat:savedfix.lat, lon:savedfix.lon};
|
waypoints[wpindex] ={name:"@"+wp.name, lat:savedfix.lat, lon:savedfix.lon};
|
||||||
wp = waypoints[wpindex];
|
wp = waypoints[wpindex];
|
||||||
require("Storage").writeJSON("waypoints.json", waypoints);
|
require("waypoints").save(waypoints);
|
||||||
}
|
}
|
||||||
selected=!selected;
|
selected=!selected;
|
||||||
drawN();
|
drawN();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ function drawN(){var a=loc.speed(speed);buf.setColor(1);buf.setFont("6x8",2);buf
|
||||||
0,30);buf.setColor(selected?1:2);buf.drawString(wp.name,140,0);buf.setColor(1);buf.drawString(a,60,0);buf.drawString(loc.distance(dist),60,30);flip(buf,Yoff+130);g.setFont("6x8",1);g.setColor(0,0,0);g.fillRect(10,230,60,239);g.setColor(1,1,1);g.drawString("Sats "+satellites.toString(),10,230)}var savedfix;
|
0,30);buf.setColor(selected?1:2);buf.drawString(wp.name,140,0);buf.setColor(1);buf.drawString(a,60,0);buf.drawString(loc.distance(dist),60,30);flip(buf,Yoff+130);g.setFont("6x8",1);g.setColor(0,0,0);g.fillRect(10,230,60,239);g.setColor(1,1,1);g.drawString("Sats "+satellites.toString(),10,230)}var savedfix;
|
||||||
function onGPS(a){savedfix=a;void 0!==a&&(course=isNaN(a.course)?course:Math.round(a.course),speed=isNaN(a.speed)?speed:a.speed,satellites=a.satellites);candraw&&(void 0!==a&&1==a.fix&&(dist=distance(a,wp),isNaN(dist)&&(dist=0),brg=bearing(a,wp),isNaN(brg)&&(brg=0)),drawN())}var intervalRef;function stopdraw(){candraw=!1;intervalRef&&clearInterval(intervalRef)}
|
function onGPS(a){savedfix=a;void 0!==a&&(course=isNaN(a.course)?course:Math.round(a.course),speed=isNaN(a.speed)?speed:a.speed,satellites=a.satellites);candraw&&(void 0!==a&&1==a.fix&&(dist=distance(a,wp),isNaN(dist)&&(dist=0),brg=bearing(a,wp),isNaN(brg)&&(brg=0)),drawN())}var intervalRef;function stopdraw(){candraw=!1;intervalRef&&clearInterval(intervalRef)}
|
||||||
function startTimers(){candraw=!0;intervalRefSec=setInterval(function(){heading=newHeading(course,heading);course!=heading&&drawCompass(heading)},200)}function drawAll(){g.setColor(1,.5,.5);g.fillPoly([120,Yoff+50,110,Yoff+70,130,Yoff+70]);g.setColor(1,1,1);drawN();drawCompass(heading)}function startdraw(){g.clear();Bangle.drawWidgets();startTimers();drawAll()}
|
function startTimers(){candraw=!0;intervalRefSec=setInterval(function(){heading=newHeading(course,heading);course!=heading&&drawCompass(heading)},200)}function drawAll(){g.setColor(1,.5,.5);g.fillPoly([120,Yoff+50,110,Yoff+70,130,Yoff+70]);g.setColor(1,1,1);drawN();drawCompass(heading)}function startdraw(){g.clear();Bangle.drawWidgets();startTimers();drawAll()}
|
||||||
function setButtons(){setWatch(nextwp.bind(null,-1),BTN1,{repeat:!0,edge:"falling"});setWatch(doselect,BTN2,{repeat:!0,edge:"falling"});setWatch(nextwp.bind(null,1),BTN3,{repeat:!0,edge:"falling"})}var SCREENACCESS={withApp:!0,request:function(){this.withApp=!1;stopdraw();clearWatch()},release:function(){this.withApp=!0;startdraw();setButtons()}};Bangle.on("lcdPower",function(a){SCREENACCESS.withApp&&(a?startdraw():stopdraw())});var waypoints=require("Storage").readJSON("waypoints.json")||[{name:"NONE"}];
|
function setButtons(){setWatch(nextwp.bind(null,-1),BTN1,{repeat:!0,edge:"falling"});setWatch(doselect,BTN2,{repeat:!0,edge:"falling"});setWatch(nextwp.bind(null,1),BTN3,{repeat:!0,edge:"falling"})}var SCREENACCESS={withApp:!0,request:function(){this.withApp=!1;stopdraw();clearWatch()},release:function(){this.withApp=!0;startdraw();setButtons()}};Bangle.on("lcdPower",function(a){SCREENACCESS.withApp&&(a?startdraw():stopdraw())});var waypoints=require("waypoints").load();
|
||||||
wp=waypoints[0];function nextwp(a){selected&&(wpindex+=a,wpindex>=waypoints.length&&(wpindex=0),0>wpindex&&(wpindex=waypoints.length-1),wp=waypoints[wpindex],drawN())}function doselect(){selected&&0!=wpindex&&void 0===waypoints[wpindex].lat&&savedfix.fix&&(waypoints[wpindex]={name:"@"+wp.name,lat:savedfix.lat,lon:savedfix.lon},wp=waypoints[wpindex],require("Storage").writeJSON("waypoints.json",waypoints));selected=!selected;drawN()}g.clear();Bangle.setLCDBrightness(1);Bangle.loadWidgets();Bangle.drawWidgets();
|
wp=waypoints[0];function nextwp(a){selected&&(wpindex+=a,wpindex>=waypoints.length&&(wpindex=0),0>wpindex&&(wpindex=waypoints.length-1),wp=waypoints[wpindex],drawN())}function doselect(){selected&&0!=wpindex&&void 0===waypoints[wpindex].lat&&savedfix.fix&&(waypoints[wpindex]={name:"@"+wp.name,lat:savedfix.lat,lon:savedfix.lon},wp=waypoints[wpindex],require("waypoints").save(waypoints));selected=!selected;drawN()}g.clear();Bangle.setLCDBrightness(1);Bangle.loadWidgets();Bangle.drawWidgets();
|
||||||
Bangle.setGPSPower(1);drawAll();startTimers();Bangle.on("GPS",onGPS);setButtons();
|
Bangle.setGPSPower(1);drawAll();startTimers();Bangle.on("GPS",onGPS);setButtons();
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
{
|
{
|
||||||
"id": "gpsnav",
|
"id": "gpsnav",
|
||||||
"name": "GPS Navigation",
|
"name": "GPS Navigation",
|
||||||
"version": "0.05",
|
"version": "0.06",
|
||||||
"description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording, now with waypoint editor",
|
"description": "Displays GPS Course and Speed, + Directions to waypoint and waypoint recording, now with waypoint editor",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"interface": "waypoints.html",
|
"dependencies" : { "waypoints":"type" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"gpsnav.app.js","url":"app.min.js"},
|
{"name":"gpsnav.app.js","url":"app.min.js"},
|
||||||
{"name":"gpsnav.img","url":"app-icon.js","evaluate":true}
|
{"name":"gpsnav.img","url":"app-icon.js","evaluate":true}
|
||||||
],
|
]
|
||||||
"data": [{"name":"waypoints.json","url":"waypoints.json"}]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
|
||||||
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h4>List of waypoints</h4>
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Lat.</th>
|
|
||||||
<th>Long.</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="waypoints">
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<br>
|
|
||||||
<h4>Add a new waypoint</h4>
|
|
||||||
<form id="add_waypoint_form">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" type="text" id="add_waypoint_name" placeholder="Name">
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_latitude" placeholder="Lat">
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_longtitude" placeholder="Long">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<button id="add_name_button" class="btn btn-primary btn-sm">Add Name Only</button>
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<button id="add_waypoint_button" class="btn btn-primary btn-sm">Add Waypoint</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<br>
|
|
||||||
<button id="Download" class="btn btn-error">Reload</button> <button id="Upload" class="btn btn-primary">Upload</button>
|
|
||||||
|
|
||||||
<script src="../../core/lib/interface.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var waypoints = []
|
|
||||||
|
|
||||||
var $name = document.getElementById('add_waypoint_name')
|
|
||||||
var $form = document.getElementById('add_waypoint_form')
|
|
||||||
var $button = document.getElementById('add_waypoint_button')
|
|
||||||
var $name_button = document.getElementById('add_name_button')
|
|
||||||
var $latitude = document.getElementById('add_latitude')
|
|
||||||
var $longtitude = document.getElementById('add_longtitude')
|
|
||||||
var $list = document.getElementById('waypoints')
|
|
||||||
|
|
||||||
function compare(a, b){
|
|
||||||
var x = a.name.toLowerCase();
|
|
||||||
var y = b.name.toLowerCase();
|
|
||||||
if (x=="none") {return -1};
|
|
||||||
if (y=="none") {return 1};
|
|
||||||
if (x < y) {return -1;}
|
|
||||||
if (x > y) {return 1;}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$button.addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
var name = $name.value.trim()
|
|
||||||
if(!name) return;
|
|
||||||
var lat = parseFloat($latitude.value).toPrecision(5);
|
|
||||||
var lon = parseFloat($longtitude.value).toPrecision(5);
|
|
||||||
|
|
||||||
waypoints.push({
|
|
||||||
name, lat,lon,
|
|
||||||
});
|
|
||||||
|
|
||||||
waypoints.sort(compare);
|
|
||||||
|
|
||||||
renderWaypoints()
|
|
||||||
$name.value = ''
|
|
||||||
$latitude.value = (0).toPrecision(5);
|
|
||||||
$longtitude.value = (0).toPrecision(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
$name_button.addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
var name = $name.value.trim()
|
|
||||||
if(!name) return;
|
|
||||||
|
|
||||||
waypoints.push({
|
|
||||||
name
|
|
||||||
});
|
|
||||||
waypoints.sort(compare);
|
|
||||||
|
|
||||||
renderWaypoints()
|
|
||||||
$name.value = ''
|
|
||||||
$latitude.value = 0.0000
|
|
||||||
$longtitude.value = 0.0000
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function removeWaypoint(index){
|
|
||||||
$name.value = waypoints[index].name
|
|
||||||
$latitude.value = waypoints[index].lat
|
|
||||||
$longtitude.value = waypoints[index].lon
|
|
||||||
waypoints = waypoints.filter((p,i) => i!==index)
|
|
||||||
renderWaypoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderWaypoints(){
|
|
||||||
$list.innerHTML = ''
|
|
||||||
waypoints.forEach((waypoint,index) => {
|
|
||||||
var $waypoint = document.createElement('tr')
|
|
||||||
if (index==0){
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td>`
|
|
||||||
} else if(waypoint.lat==undefined){
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>------</td><td>-----</td><td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-edit"></i></button></td>`
|
|
||||||
} else {
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>${waypoint.lat}</td><td>${waypoint.lon}</td><td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-edit"></i></button></td>`
|
|
||||||
}
|
|
||||||
$list.appendChild($waypoint)
|
|
||||||
})
|
|
||||||
$name.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadJSONfile(fileid, callback) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
var pts = require("Storage").readJSON("${fileid}")||[{name:"NONE"}];
|
|
||||||
Bluetooth.print(JSON.stringify(pts));
|
|
||||||
})()\n`,contents=>{
|
|
||||||
var storedpts = JSON.parse(contents);
|
|
||||||
callback(storedpts);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadFile(fileid, contents) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
require("Storage").write("${fileid}",'${contents}');
|
|
||||||
Bluetooth.print("OK");
|
|
||||||
})()\n`,ret=>{
|
|
||||||
console.log("uploadFile",ret);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotStored(pts){
|
|
||||||
waypoints = pts;
|
|
||||||
renderWaypoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInit() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("Download").addEventListener("click", function() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("Upload").addEventListener("click", function() {
|
|
||||||
var data = JSON.stringify(waypoints);
|
|
||||||
uploadFile("waypoints.json",data);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"name":"NONE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"No10",
|
|
||||||
"lat":51.5032,
|
|
||||||
"lon":-0.1269
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Stone",
|
|
||||||
"lat":51.1788,
|
|
||||||
"lon":-1.8260
|
|
||||||
},
|
|
||||||
{ "name":"WP0" },
|
|
||||||
{ "name":"WP1" },
|
|
||||||
{ "name":"WP2" },
|
|
||||||
{ "name":"WP3" },
|
|
||||||
{ "name":"WP4" }
|
|
||||||
]
|
|
||||||
|
|
@ -11,3 +11,4 @@
|
||||||
0.11: Detect when waypoints.json is not present, error E-WPT
|
0.11: Detect when waypoints.json is not present, error E-WPT
|
||||||
0.12: Added stepo2 as a replacement for stepo and digi
|
0.12: Added stepo2 as a replacement for stepo and digi
|
||||||
0.13: Added long press BTN2 toggle gpsrec status in GPS clock
|
0.13: Added long press BTN2 toggle gpsrec status in GPS clock
|
||||||
|
0.14: Move waypoints.json (and editor) to 'waypoints' app
|
||||||
|
|
|
||||||
|
|
@ -208,14 +208,8 @@ which will obviously limit this.
|
||||||
|
|
||||||
### Waypoint Editor
|
### Waypoint Editor
|
||||||
|
|
||||||
Clicking on the download icon of gpsnav in the app loader invokes the
|
Clicking on the download icon of `Waypoints` in the app loader invokes the
|
||||||
waypoint editor. The editor downloads and displays the current
|
waypoint editor. See the `Waypoints` app for more information.
|
||||||
`waypoints.json` file. Clicking the `Edit` button beside an entry
|
|
||||||
causes the entry to be deleted from the list and displayed in the
|
|
||||||
edit boxes. It can be restored - by clicking the `Add waypoint`
|
|
||||||
button. A new markable entry is created by using the `Add name`
|
|
||||||
button. The edited `waypoints.json` file is uploaded to the Bangle by
|
|
||||||
clicking the `Upload` button.
|
|
||||||
|
|
||||||
|
|
||||||
### Calibration of the Compass
|
### Calibration of the Compass
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ GPS.prototype.getWPbearing = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
GPS.prototype.loadFirstWaypoint = function() {
|
GPS.prototype.loadFirstWaypoint = function() {
|
||||||
var waypoints = require("Storage").readJSON("waypoints.json")||[{name:"E-WPT"}];
|
var waypoints = require("waypoints").load();
|
||||||
this.wp_index = 0;
|
this.wp_index = 0;
|
||||||
this.wp_current = waypoints[this.wp_index];
|
this.wp_current = waypoints[this.wp_index];
|
||||||
log_debug(this.wp_current);
|
log_debug(this.wp_current);
|
||||||
|
|
@ -346,7 +346,7 @@ GPS.prototype.markWaypoint = function() {
|
||||||
|
|
||||||
log_debug("GPS::markWaypoint()");
|
log_debug("GPS::markWaypoint()");
|
||||||
|
|
||||||
var waypoints = require("Storage").readJSON("waypoints.json")||[{name:"E-WPT"}];
|
var waypoints = require("waypoints").load();
|
||||||
this.wp_current = waypoints[this.wp_index];
|
this.wp_current = waypoints[this.wp_index];
|
||||||
|
|
||||||
if (this.waypointHasLocation()) {
|
if (this.waypointHasLocation()) {
|
||||||
|
|
@ -356,12 +356,12 @@ GPS.prototype.markWaypoint = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.wp_current = waypoints[this.wp_index];
|
this.wp_current = waypoints[this.wp_index];
|
||||||
require("Storage").writeJSON("waypoints.json", waypoints);
|
require("waypoints").save(waypoints);
|
||||||
log_debug("GPS::markWaypoint() written");
|
log_debug("GPS::markWaypoint() written");
|
||||||
}
|
}
|
||||||
|
|
||||||
GPS.prototype.nextWaypoint = function(inc) {
|
GPS.prototype.nextWaypoint = function(inc) {
|
||||||
var waypoints = require("Storage").readJSON("waypoints.json")||[{name:"E-WPT"}];
|
var waypoints = require("waypoints").load();
|
||||||
this.wp_index+=inc;
|
this.wp_index+=inc;
|
||||||
if (this.wp_index>=waypoints.length) this.wp_index=0;
|
if (this.wp_index>=waypoints.length) this.wp_index=0;
|
||||||
if (this.wp_index<0) this.wp_index = waypoints.length-1;
|
if (this.wp_index<0) this.wp_index = waypoints.length-1;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
{
|
{
|
||||||
"id": "kitchen",
|
"id": "kitchen",
|
||||||
"name": "Kitchen Combo",
|
"name": "Kitchen Combo",
|
||||||
"version": "0.13",
|
"version": "0.14",
|
||||||
"description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'",
|
"description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'",
|
||||||
"icon": "kitchen.png",
|
"icon": "kitchen.png",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"interface": "waypoints.html",
|
"dependencies" : { "waypoints":"type" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"kitchen.app.js","url":"kitchen.app.js"},
|
{"name":"kitchen.app.js","url":"kitchen.app.js"},
|
||||||
{"name":"stepo2.kit.js","url":"stepo2.kit.js"},
|
{"name":"stepo2.kit.js","url":"stepo2.kit.js"},
|
||||||
|
|
@ -16,6 +16,5 @@
|
||||||
{"name":"gps.kit.js","url":"gps.kit.js"},
|
{"name":"gps.kit.js","url":"gps.kit.js"},
|
||||||
{"name":"compass.kit.js","url":"compass.kit.js"},
|
{"name":"compass.kit.js","url":"compass.kit.js"},
|
||||||
{"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
|
{"name":"kitchen.img","url":"kitchen.icon.js","evaluate":true}
|
||||||
],
|
]
|
||||||
"data": [{"name":"waypoints.json","url":"waypoints.json"}]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
|
||||||
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h4>List of waypoints</h4>
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Lat.</th>
|
|
||||||
<th>Long.</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="waypoints">
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<br>
|
|
||||||
<h4>Add a new waypoint</h4>
|
|
||||||
<form id="add_waypoint_form">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" type="text" id="add_waypoint_name" placeholder="Name">
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_latitude" placeholder="Lat">
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_longtitude" placeholder="Long">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<button id="add_name_button" class="btn btn-primary btn-sm">Add Name Only</button>
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<button id="add_waypoint_button" class="btn btn-primary btn-sm">Add Waypoint</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<br>
|
|
||||||
<button id="Download" class="btn btn-error">Reload</button> <button id="Upload" class="btn btn-primary">Upload</button>
|
|
||||||
|
|
||||||
<script src="../../core/lib/interface.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var waypoints = []
|
|
||||||
|
|
||||||
var $name = document.getElementById('add_waypoint_name')
|
|
||||||
var $form = document.getElementById('add_waypoint_form')
|
|
||||||
var $button = document.getElementById('add_waypoint_button')
|
|
||||||
var $name_button = document.getElementById('add_name_button')
|
|
||||||
var $latitude = document.getElementById('add_latitude')
|
|
||||||
var $longtitude = document.getElementById('add_longtitude')
|
|
||||||
var $list = document.getElementById('waypoints')
|
|
||||||
|
|
||||||
function compare(a, b){
|
|
||||||
var x = a.name.toLowerCase();
|
|
||||||
var y = b.name.toLowerCase();
|
|
||||||
if (x=="none") {return -1};
|
|
||||||
if (y=="none") {return 1};
|
|
||||||
if (x < y) {return -1;}
|
|
||||||
if (x > y) {return 1;}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$button.addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
var name = $name.value.trim()
|
|
||||||
if(!name) return;
|
|
||||||
var lat = parseFloat($latitude.value).toPrecision(5);
|
|
||||||
var lon = parseFloat($longtitude.value).toPrecision(5);
|
|
||||||
|
|
||||||
waypoints.push({
|
|
||||||
name, lat,lon,
|
|
||||||
});
|
|
||||||
|
|
||||||
waypoints.sort(compare);
|
|
||||||
|
|
||||||
renderWaypoints()
|
|
||||||
$name.value = ''
|
|
||||||
$latitude.value = (0).toPrecision(5);
|
|
||||||
$longtitude.value = (0).toPrecision(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
$name_button.addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
var name = $name.value.trim()
|
|
||||||
if(!name) return;
|
|
||||||
|
|
||||||
waypoints.push({
|
|
||||||
name
|
|
||||||
});
|
|
||||||
waypoints.sort(compare);
|
|
||||||
|
|
||||||
renderWaypoints()
|
|
||||||
$name.value = ''
|
|
||||||
$latitude.value = 0.0000
|
|
||||||
$longtitude.value = 0.0000
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function removeWaypoint(index){
|
|
||||||
$name.value = waypoints[index].name
|
|
||||||
$latitude.value = waypoints[index].lat
|
|
||||||
$longtitude.value = waypoints[index].lon
|
|
||||||
waypoints = waypoints.filter((p,i) => i!==index)
|
|
||||||
renderWaypoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderWaypoints(){
|
|
||||||
$list.innerHTML = ''
|
|
||||||
waypoints.forEach((waypoint,index) => {
|
|
||||||
var $waypoint = document.createElement('tr')
|
|
||||||
if (index==0){
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td>`
|
|
||||||
} else if(waypoint.lat==undefined){
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>------</td><td>-----</td><td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-edit"></i></button></td>`
|
|
||||||
} else {
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>${waypoint.lat}</td><td>${waypoint.lon}</td><td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-edit"></i></button></td>`
|
|
||||||
}
|
|
||||||
$list.appendChild($waypoint)
|
|
||||||
})
|
|
||||||
$name.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadJSONfile(fileid, callback) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
var pts = require("Storage").readJSON("${fileid}")||[{name:"NONE"}];
|
|
||||||
Bluetooth.print(JSON.stringify(pts));
|
|
||||||
})()\n`,contents=>{
|
|
||||||
var storedpts = JSON.parse(contents);
|
|
||||||
callback(storedpts);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadFile(fileid, contents) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
require("Storage").write("${fileid}",'${contents}');
|
|
||||||
Bluetooth.print("OK");
|
|
||||||
})()\n`,ret=>{
|
|
||||||
console.log("uploadFile",ret);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotStored(pts){
|
|
||||||
waypoints = pts;
|
|
||||||
renderWaypoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInit() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("Download").addEventListener("click", function() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("Upload").addEventListener("click", function() {
|
|
||||||
var data = JSON.stringify(waypoints);
|
|
||||||
uploadFile("waypoints.json",data);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"name":"NONE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"No10",
|
|
||||||
"lat":51.5032,
|
|
||||||
"lon":-0.1269
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Stone",
|
|
||||||
"lat":51.1788,
|
|
||||||
"lon":-1.8260
|
|
||||||
},
|
|
||||||
{ "name":"WP0" },
|
|
||||||
{ "name":"WP1" },
|
|
||||||
{ "name":"WP2" },
|
|
||||||
{ "name":"WP3" },
|
|
||||||
{ "name":"WP4" }
|
|
||||||
]
|
|
||||||
|
|
@ -71,9 +71,7 @@ The MAX values continue to be collected with the display off so may appear a lit
|
||||||
|
|
||||||
## Waypoints
|
## Waypoints
|
||||||
|
|
||||||
Waypoints are used in [D]istance mode. Create a file waypoints.json and write to storage on the Bangle.js using the IDE. The first 6 characters of the name are displayed in Speed+[D]istance mode.
|
Waypoints are used in Distance and VMG modes. See the `Waypoints` app for information on how to create/edit waypoints. The first 6 characters of the name are displayed in Speed+[D]istance mode.
|
||||||
|
|
||||||
The [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app in the App Loader has a really nice waypoints file editor. (Must be connected to your Bangle.JS and then click on the Download icon.)
|
|
||||||
|
|
||||||
Sample waypoints.json (My sailing waypoints)
|
Sample waypoints.json (My sailing waypoints)
|
||||||
|
|
||||||
|
|
@ -149,5 +147,3 @@ Developed for my use in sailing, cycling and motorcycling. If you find this soft
|
||||||
Many thanks to Gordon Williams. Awesome job.
|
Many thanks to Gordon Williams. Awesome job.
|
||||||
|
|
||||||
Special thanks also to @jeffmer, for the [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app and @hughbarney for the Low power GPS code development and Wouter Bulten for the Kalman filter code.
|
Special thanks also to @jeffmer, for the [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app and @hughbarney for the Low power GPS code development and Wouter Bulten for the Kalman filter code.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ function nxtWp(inc){
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadWp() {
|
function loadWp() {
|
||||||
var w = require("Storage").readJSON('waypoints.json')||[{name:"NONE"}];
|
var w = require("waypoints").load();
|
||||||
if (cfg.wp>=w.length) cfg.wp=0;
|
if (cfg.wp>=w.length) cfg.wp=0;
|
||||||
if (cfg.wp<0) cfg.wp = w.length-1;
|
if (cfg.wp<0) cfg.wp = w.length-1;
|
||||||
savSettings();
|
savSettings();
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
"type": "app",
|
"type": "app",
|
||||||
"tags": "tool,outdoors",
|
"tags": "tool,outdoors",
|
||||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
|
"dependencies" : { "waypoints":"type" },
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"allow_emulator": true,
|
"allow_emulator": true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"speedalt.app.js","url":"app.js"},
|
{"name":"speedalt.app.js","url":"app.js"},
|
||||||
{"name":"speedalt.img","url":"app-icon.js","evaluate":true},
|
{"name":"speedalt.img","url":"app-icon.js","evaluate":true},
|
||||||
{"name":"speedalt.settings.js","url":"settings.js"}
|
{"name":"speedalt.settings.js","url":"settings.js"}
|
||||||
],
|
]
|
||||||
"data": [{"name":"speedalt.json"}]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,4 @@
|
||||||
0.15: Droidscript mirroring prog automatically uses last connection address. Auto connects when run.
|
0.15: Droidscript mirroring prog automatically uses last connection address. Auto connects when run.
|
||||||
0.16: Add configuration item Wpt File Suffix. A one character suffix to append to the waypoints.json file. A number of other apps also use this file name. Using the file name suffix allows the speedalt2 waypoints to be retained if one of these other apps is installed for a different use.
|
0.16: Add configuration item Wpt File Suffix. A one character suffix to append to the waypoints.json file. A number of other apps also use this file name. Using the file name suffix allows the speedalt2 waypoints to be retained if one of these other apps is installed for a different use.
|
||||||
0.17: Use default Bangle formatter for booleans
|
0.17: Use default Bangle formatter for booleans
|
||||||
|
0.18: Move waypoints.json to 'waypoints' app (with editor)
|
||||||
|
|
|
||||||
|
|
@ -74,13 +74,11 @@ Android Screen Mirroring:<br>
|
||||||
|
|
||||||
## Waypoints
|
## Waypoints
|
||||||
|
|
||||||
Waypoints are used in Distance and VMG modes. Create a file waypoints.json and write to storage on the Bangle.js using the IDE. The first 6 characters of the name are displayed in Speed+[D]istance mode.
|
Waypoints are used in Distance and VMG modes. See the `Waypoints` app for information on how to create/edit waypoints. The first 6 characters of the name are displayed in Speed+[D]istance mode.
|
||||||
|
|
||||||
The [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app in the App Loader has a really nice waypoints file editor. (Must be connected to your Bangle.JS and then click on the Download icon.)
|
|
||||||
|
|
||||||
By default the waypoints file is called waypoints.json
|
By default the waypoints file is called waypoints.json
|
||||||
|
|
||||||
**Note** : The waypoints.json file is used by a number of different gps apps. The setting 'Wpt File Suffix' allows one of waypoints1.json, waypoints2.json or waypoints3.json to be used instead. This allows the other apps to be used with a different set of waypoints without losing the speedalt2 waypoint set.
|
**Note** : The waypoints.json file is used by a number of different gps apps. The setting 'Wpt File Suffix' allows one of waypoints.1.json, waypoints.2.json or waypoints.3.json to be used instead. This allows the other apps to be used with a different set of waypoints without losing the speedalt2 waypoint set.
|
||||||
|
|
||||||
Sample waypoints.json (My sailing waypoints)
|
Sample waypoints.json (My sailing waypoints)
|
||||||
|
|
||||||
|
|
@ -156,4 +154,3 @@ Developed for my use in sailing, cycling and motorcycling. If you find this soft
|
||||||
Many thanks to Gordon Williams. Awesome job.
|
Many thanks to Gordon Williams. Awesome job.
|
||||||
|
|
||||||
Special thanks also to @jeffmer, for the [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app and @hughbarney for the Low power GPS code development and Wouter Bulten for the Kalman filter code.
|
Special thanks also to @jeffmer, for the [GPS Navigation](https://banglejs.com/apps/#gps%20navigation) app and @hughbarney for the Low power GPS code development and Wouter Bulten for the Kalman filter code.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@ function nxtWp(){
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadWp() {
|
function loadWp() {
|
||||||
var w = require("Storage").readJSON('waypoints'+cfg.wptSfx+'.json')||[{name:"NONE"}];
|
var w = require("waypoints").load(cfg.wptSfx);
|
||||||
if (cfg.wp>=w.length) cfg.wp=0;
|
if (cfg.wp>=w.length) cfg.wp=0;
|
||||||
if (cfg.wp<0) cfg.wp = w.length-1;
|
if (cfg.wp<0) cfg.wp = w.length-1;
|
||||||
savSettings();
|
savSettings();
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,13 @@
|
||||||
"id": "speedalt2",
|
"id": "speedalt2",
|
||||||
"name": "GPS Adventure Sports II",
|
"name": "GPS Adventure Sports II",
|
||||||
"shortName":"GPS Adv Sport II",
|
"shortName":"GPS Adv Sport II",
|
||||||
"version":"0.17",
|
"version":"0.18",
|
||||||
"description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.",
|
"description": "GPS speed, altitude and distance to waypoint display. Designed for easy viewing and use during outdoor activities such as para-gliding, hang-gliding, sailing, cycling etc.",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
"tags": "tool,outdoors",
|
"tags": "tool,outdoors",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS"],
|
||||||
|
"dependencies" : { "waypoints":"type" },
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"allow_emulator": true,
|
"allow_emulator": true,
|
||||||
"storage": [
|
"storage": [
|
||||||
|
|
@ -16,10 +17,6 @@
|
||||||
{"name":"speedalt2.settings.js","url":"settings.js"}
|
{"name":"speedalt2.settings.js","url":"settings.js"}
|
||||||
],
|
],
|
||||||
"data": [
|
"data": [
|
||||||
{"name":"speedalt2.json"},
|
{"name":"speedalt2.json"}
|
||||||
{"name":"waypoints.json"},
|
|
||||||
{"name":"waypoints1.json"},
|
|
||||||
{"name":"waypoints2.json"},
|
|
||||||
{"name":"waypoints3.json"}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
0.01: New app!
|
0.01: New app!
|
||||||
0.02: Make Bangle.js 2 compatible
|
0.02: Make Bangle.js 2 compatible
|
||||||
0.03: Silently use built in heading when no magnav calibration file is present
|
0.03: Silently use built in heading when no magnav calibration file is present
|
||||||
|
0.04: Move waypoints.json (and editor) to 'waypoints' app
|
||||||
|
|
|
||||||
|
|
@ -61,58 +61,10 @@ The app indicates that WP2 is now marked by adding the prefix @ to
|
||||||
it's name. The distance should be small as shown in the screen shot
|
it's name. The distance should be small as shown in the screen shot
|
||||||
as you have just marked your current location.
|
as you have just marked your current location.
|
||||||
|
|
||||||
## Waypoint JSON file
|
## Setting Waypoints
|
||||||
|
|
||||||
When the app is loaded from the app loader, a file named
|
|
||||||
`waypoints.json` is loaded along with the javascript etc. The file
|
|
||||||
has the following contents:
|
|
||||||
|
|
||||||
|
|
||||||
```
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"name":"NONE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"No10",
|
|
||||||
"lat":51.5032,
|
|
||||||
"lon":-0.1269
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Stone",
|
|
||||||
"lat":51.1788,
|
|
||||||
"lon":-1.8260
|
|
||||||
},
|
|
||||||
{ "name":"WP0" },
|
|
||||||
{ "name":"WP1" },
|
|
||||||
{ "name":"WP2" },
|
|
||||||
{ "name":"WP3" },
|
|
||||||
{ "name":"WP4" }
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
The file contains the initial NONE waypoint which is useful if you
|
|
||||||
just want to display course and speed. The next two entries are
|
|
||||||
waypoints to No 10 Downing Street and to Stone Henge - obtained from
|
|
||||||
Google Maps. The last five entries are entries which can be *marked*.
|
|
||||||
|
|
||||||
You add and delete entries using the Web IDE to load and then save
|
|
||||||
the file from and to watch storage. The app itself does not limit the
|
|
||||||
number of entries although it does load the entire file into RAM
|
|
||||||
which will obviously limit this.
|
|
||||||
|
|
||||||
|
|
||||||
## Waypoint Editor
|
|
||||||
|
|
||||||
Clicking on the download icon of gpsnav in the app loader invokes the
|
|
||||||
waypoint editor. The editor downloads and displays the current
|
|
||||||
`waypoints.json` file. Clicking the `Edit` button beside an entry
|
|
||||||
causes the entry to be deleted from the list and displayed in the
|
|
||||||
edit boxes. It can be restored - by clicking the `Add waypoint`
|
|
||||||
button. A new markable entry is created by using the `Add name`
|
|
||||||
button. The edited `waypoints.json` file is uploaded to the Bangle by
|
|
||||||
clicking the `Upload` button.
|
|
||||||
|
|
||||||
|
Check out the documentation for the `Waypoints` app. This provides
|
||||||
|
the ability to set waypoints from your browser.
|
||||||
|
|
||||||
## Calibration of the Compass
|
## Calibration of the Compass
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ Bangle.on('lcdPower',function(on) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var waypoints = require("Storage").readJSON("waypoints.json")||[{name:"NONE"}];
|
var waypoints = require("waypoints").load();
|
||||||
wp=waypoints[0];
|
wp=waypoints[0];
|
||||||
|
|
||||||
function nextwp(inc){
|
function nextwp(inc){
|
||||||
|
|
@ -266,7 +266,7 @@ function doselect(){
|
||||||
if (selected && wpindex!=0 && waypoints[wpindex].lat===undefined && savedfix.fix) {
|
if (selected && wpindex!=0 && waypoints[wpindex].lat===undefined && savedfix.fix) {
|
||||||
waypoints[wpindex] ={name:"@"+wp.name, lat:savedfix.lat, lon:savedfix.lon};
|
waypoints[wpindex] ={name:"@"+wp.name, lat:savedfix.lat, lon:savedfix.lon};
|
||||||
wp = waypoints[wpindex];
|
wp = waypoints[wpindex];
|
||||||
require("Storage").writeJSON("waypoints.json", waypoints);
|
require("waypoints").save(waypoints);
|
||||||
}
|
}
|
||||||
selected=!selected;
|
selected=!selected;
|
||||||
drawN();
|
drawN();
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
{
|
{
|
||||||
"id": "waypointer",
|
"id": "waypointer",
|
||||||
"name": "Way Pointer",
|
"name": "Way Pointer",
|
||||||
"version": "0.03",
|
"version": "0.04",
|
||||||
"description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation",
|
"description": "Navigate to a waypoint using the GPS for bearing and compass to point way, uses the same waypoint interface as GPS Navigation",
|
||||||
"icon": "waypointer.png",
|
"icon": "waypointer.png",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||||
|
"dependencies" : { "waypoints":"type" },
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"interface": "waypoints.html",
|
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"waypointer.app.js","url":"app.js"},
|
{"name":"waypointer.app.js","url":"app.js"},
|
||||||
{"name":"waypointer.img","url":"icon.js","evaluate":true}
|
{"name":"waypointer.img","url":"icon.js","evaluate":true}
|
||||||
],
|
]
|
||||||
"data": [{"name":"waypoints.json","url":"waypoints.json"}]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
|
||||||
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h4>List of waypoints</h4>
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Lat.</th>
|
|
||||||
<th>Long.</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="waypoints">
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<br>
|
|
||||||
<h4>Add a new waypoint</h4>
|
|
||||||
<form id="add_waypoint_form">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" type="text" id="add_waypoint_name" placeholder="Name">
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_latitude" placeholder="Lat">
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_longtitude" placeholder="Long">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<button id="add_name_button" class="btn btn-primary btn-sm">Add Name Only</button>
|
|
||||||
</div>
|
|
||||||
<div class="column col-3 col-xs-8">
|
|
||||||
<button id="add_waypoint_button" class="btn btn-primary btn-sm">Add Waypoint</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<br>
|
|
||||||
<button id="Download" class="btn btn-error">Reload</button> <button id="Upload" class="btn btn-primary">Upload</button>
|
|
||||||
|
|
||||||
<script src="../../core/lib/interface.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
var waypoints = []
|
|
||||||
|
|
||||||
var $name = document.getElementById('add_waypoint_name')
|
|
||||||
var $form = document.getElementById('add_waypoint_form')
|
|
||||||
var $button = document.getElementById('add_waypoint_button')
|
|
||||||
var $name_button = document.getElementById('add_name_button')
|
|
||||||
var $latitude = document.getElementById('add_latitude')
|
|
||||||
var $longtitude = document.getElementById('add_longtitude')
|
|
||||||
var $list = document.getElementById('waypoints')
|
|
||||||
|
|
||||||
function compare(a, b){
|
|
||||||
var x = a.name.toLowerCase();
|
|
||||||
var y = b.name.toLowerCase();
|
|
||||||
if (x=="none") {return -1};
|
|
||||||
if (y=="none") {return 1};
|
|
||||||
if (x < y) {return -1;}
|
|
||||||
if (x > y) {return 1;}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$button.addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
var name = $name.value.trim()
|
|
||||||
if(!name) return;
|
|
||||||
var lat = parseFloat($latitude.value);
|
|
||||||
var lon = parseFloat($longtitude.value);
|
|
||||||
|
|
||||||
waypoints.push({
|
|
||||||
name, lat,lon,
|
|
||||||
});
|
|
||||||
|
|
||||||
waypoints.sort(compare);
|
|
||||||
|
|
||||||
renderWaypoints()
|
|
||||||
$name.value = ''
|
|
||||||
$latitude.value = (0).toPrecision(5);
|
|
||||||
$longtitude.value = (0).toPrecision(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
$name_button.addEventListener('click', event => {
|
|
||||||
event.preventDefault()
|
|
||||||
var name = $name.value.trim()
|
|
||||||
if(!name) return;
|
|
||||||
|
|
||||||
waypoints.push({
|
|
||||||
name
|
|
||||||
});
|
|
||||||
waypoints.sort(compare);
|
|
||||||
|
|
||||||
renderWaypoints()
|
|
||||||
$name.value = ''
|
|
||||||
$latitude.value = 0.0000
|
|
||||||
$longtitude.value = 0.0000
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function removeWaypoint(index){
|
|
||||||
$name.value = waypoints[index].name
|
|
||||||
$latitude.value = waypoints[index].lat
|
|
||||||
$longtitude.value = waypoints[index].lon
|
|
||||||
waypoints = waypoints.filter((p,i) => i!==index)
|
|
||||||
renderWaypoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderWaypoints(){
|
|
||||||
$list.innerHTML = ''
|
|
||||||
waypoints.forEach((waypoint,index) => {
|
|
||||||
var $waypoint = document.createElement('tr')
|
|
||||||
if (index==0){
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td>`
|
|
||||||
} else if(waypoint.lat==undefined){
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>------</td><td>-----</td><td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-edit"></i></button></td>`
|
|
||||||
} else {
|
|
||||||
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>${waypoint.lat}</td><td>${waypoint.lon}</td><td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-edit"></i></button></td>`
|
|
||||||
}
|
|
||||||
$list.appendChild($waypoint)
|
|
||||||
})
|
|
||||||
$name.focus()
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadJSONfile(fileid, callback) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
var pts = require("Storage").readJSON("${fileid}")||[{name:"NONE"}];
|
|
||||||
Bluetooth.print(JSON.stringify(pts));
|
|
||||||
})()\n`,contents=>{
|
|
||||||
var storedpts = JSON.parse(contents);
|
|
||||||
callback(storedpts);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadFile(fileid, contents) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
require("Storage").write("${fileid}",'${contents}');
|
|
||||||
Bluetooth.print("OK");
|
|
||||||
})()\n`,ret=>{
|
|
||||||
console.log("uploadFile",ret);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotStored(pts){
|
|
||||||
waypoints = pts;
|
|
||||||
renderWaypoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onInit() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("Download").addEventListener("click", function() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("Upload").addEventListener("click", function() {
|
|
||||||
var data = JSON.stringify(waypoints);
|
|
||||||
uploadFile("waypoints.json",data);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"name":"NONE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"No10",
|
|
||||||
"lat":51.5032,
|
|
||||||
"lon":-0.1269
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name":"Stone",
|
|
||||||
"lat":51.1788,
|
|
||||||
"lon":-1.8260
|
|
||||||
},
|
|
||||||
{ "name":"WP0" },
|
|
||||||
{ "name":"WP1" },
|
|
||||||
{ "name":"WP2" },
|
|
||||||
{ "name":"WP3" },
|
|
||||||
{ "name":"WP4" }
|
|
||||||
]
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Waypoints
|
||||||
|
|
||||||
|
This app provides a common way to set up the `waypoints.json` file,
|
||||||
|
which several other apps rely on for navigation.
|
||||||
|
|
||||||
|
## Waypoint JSON file
|
||||||
|
|
||||||
|
When the app is loaded from the app loader, a file named
|
||||||
|
`waypoints.json` is loaded along with the javascript etc. The file
|
||||||
|
has the following contents:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name":"NONE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"No10",
|
||||||
|
"lat":51.5032,
|
||||||
|
"lon":-0.1269
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Stone",
|
||||||
|
"lat":51.1788,
|
||||||
|
"lon":-1.8260
|
||||||
|
},
|
||||||
|
{ "name":"WP0" },
|
||||||
|
{ "name":"WP1" },
|
||||||
|
{ "name":"WP2" },
|
||||||
|
{ "name":"WP3" },
|
||||||
|
{ "name":"WP4" }
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
The file contains the initial NONE waypoint which is useful if you
|
||||||
|
just want to display course and speed. The next two entries are
|
||||||
|
waypoints to No 10 Downing Street and to Stone Henge - obtained from
|
||||||
|
Google Maps. The last five entries are entries which can be *marked*.
|
||||||
|
|
||||||
|
You add and delete entries using the Web IDE to load and then save
|
||||||
|
the file from and to watch storage. The app itself does not limit the
|
||||||
|
number of entries although it does load the entire file into RAM
|
||||||
|
which will obviously limit this.
|
||||||
|
|
||||||
|
|
||||||
|
## Waypoint Editor
|
||||||
|
|
||||||
|
Clicking on the download icon of `Waypoints` in the app loader invokes the
|
||||||
|
waypoint editor. The editor downloads and displays the current
|
||||||
|
`waypoints.json` file. Clicking the `Edit` button beside an entry
|
||||||
|
causes the entry to be deleted from the list and displayed in the
|
||||||
|
edit boxes. It can be restored - by clicking the `Add waypoint`
|
||||||
|
button. A new markable entry is created by using the `Add name`
|
||||||
|
button. The edited `waypoints.json` file is uploaded to the Bangle by
|
||||||
|
clicking the `Upload` button.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA=="))
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// place your const, vars, functions or classes here
|
||||||
|
|
||||||
|
// clear the screen
|
||||||
|
g.clear();
|
||||||
|
|
||||||
|
var n = 0;
|
||||||
|
|
||||||
|
// redraw the screen
|
||||||
|
function draw() {
|
||||||
|
g.reset().clearRect(Bangle.appRect);
|
||||||
|
g.setFont("6x8").setFontAlign(0,0).drawString("Up / Down",g.getWidth()/2,g.getHeight()/2 - 20);
|
||||||
|
g.setFont("Vector",60).setFontAlign(0,0).drawString(n,g.getWidth()/2,g.getHeight()/2 + 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Respond to user input
|
||||||
|
Bangle.setUI({mode: "updown"}, function(dir) {
|
||||||
|
if (dir<0) {
|
||||||
|
n--;
|
||||||
|
draw();
|
||||||
|
} else if (dir>0) {
|
||||||
|
n++;
|
||||||
|
draw();
|
||||||
|
} else {
|
||||||
|
n = 0;
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// First draw...
|
||||||
|
draw();
|
||||||
|
|
||||||
|
// Load widgets
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||||
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
||||||
|
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css">
|
<link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css">
|
||||||
|
|
||||||
|
|
@ -11,6 +12,8 @@
|
||||||
html, body { height: 100% }
|
html, body { height: 100% }
|
||||||
.flex-col { display:flex; flex-direction:column; height:100% }
|
.flex-col { display:flex; flex-direction:column; height:100% }
|
||||||
#map { width:100%; height:100% }
|
#map { width:100%; height:100% }
|
||||||
|
#tab-map { width:100%; height:100% }
|
||||||
|
#tab-list { width:100%; height:100% }
|
||||||
|
|
||||||
/* https://stackoverflow.com/a/58686215 */
|
/* https://stackoverflow.com/a/58686215 */
|
||||||
.arrow-icon {
|
.arrow-icon {
|
||||||
|
|
@ -23,6 +26,7 @@
|
||||||
transform-origin: center center;
|
transform-origin: center center;
|
||||||
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -32,9 +36,58 @@
|
||||||
<span id="status"></span>
|
<span id="status"></span>
|
||||||
<span id="routestatus"></span>
|
<span id="routestatus"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<ul class="tab tab-block">
|
||||||
|
<li class="tab-item active" id="tabitem-map">
|
||||||
|
<a href="#">Map</a>
|
||||||
|
</li>
|
||||||
|
<li class="tab-item" id="tabitem-list">
|
||||||
|
<a href="#">List</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<div style="flex: 1">
|
<div style="flex: 1">
|
||||||
|
<div id="tab-map">
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="tab-list" style="display:none">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Lat.</th>
|
||||||
|
<th>Long.</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="waypoints">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<br>
|
||||||
|
<h4>Add a new waypoint</h4>
|
||||||
|
<form id="add_waypoint_form">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column col-3 col-xs-8">
|
||||||
|
<input class="form-input input-sm" type="text" id="add_waypoint_name" placeholder="Name">
|
||||||
|
</div>
|
||||||
|
<div class="column col-3 col-xs-8">
|
||||||
|
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_latitude" placeholder="Lat">
|
||||||
|
</div>
|
||||||
|
<div class="column col-3 col-xs-8">
|
||||||
|
<input class="form-input input-sm" value="0.0000" type="number" step="any" id="add_longtitude" placeholder="Long">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column col-3 col-xs-8">
|
||||||
|
<button id="add_name_button" class="btn btn-primary btn-sm">Add Name Only</button>
|
||||||
|
</div>
|
||||||
|
<div class="column col-3 col-xs-8">
|
||||||
|
<button id="add_waypoint_button" class="btn btn-primary btn-sm">Add Waypoint</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="anonymous"></script>
|
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin="anonymous"></script>
|
||||||
|
|
@ -44,8 +97,23 @@
|
||||||
<script src="../../core/lib/interface.js"></script>
|
<script src="../../core/lib/interface.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var map;
|
|
||||||
var waypoints = [];
|
var waypoints = [];
|
||||||
|
|
||||||
|
// ========================================================================== tabs
|
||||||
|
document.getElementById('tabitem-map').addEventListener('click',function() {
|
||||||
|
document.getElementById('tabitem-map').classList.remove("active");
|
||||||
|
document.getElementById('tabitem-list').classList.add("active");
|
||||||
|
document.getElementById('tab-map').style.display="block";
|
||||||
|
document.getElementById('tab-list').style.display="none";
|
||||||
|
});
|
||||||
|
document.getElementById('tabitem-list').addEventListener('click',function() {
|
||||||
|
document.getElementById('tabitem-map').classList.add("active");
|
||||||
|
document.getElementById('tabitem-list').classList.remove("active");
|
||||||
|
document.getElementById('tab-map').style.display="none";
|
||||||
|
document.getElementById('tab-list').style.display="block";
|
||||||
|
});
|
||||||
|
// ========================================================================== MAP
|
||||||
|
var map;
|
||||||
var mapmarkers = L.layerGroup();
|
var mapmarkers = L.layerGroup();
|
||||||
var searchresult = L.layerGroup();
|
var searchresult = L.layerGroup();
|
||||||
var dynamicarrow = L.layerGroup();
|
var dynamicarrow = L.layerGroup();
|
||||||
|
|
@ -100,9 +168,6 @@
|
||||||
L.featureGroup(getArrows(latlngs, 'black', 2, map)).addTo(dynamicarrow)
|
L.featureGroup(getArrows(latlngs, 'black', 2, map)).addTo(dynamicarrow)
|
||||||
map.addLayer(dynamicarrow);
|
map.addLayer(dynamicarrow);
|
||||||
});
|
});
|
||||||
clean();
|
|
||||||
renderAllWaypoints();
|
|
||||||
|
|
||||||
/*** status ***/
|
/*** status ***/
|
||||||
|
|
||||||
function clean() {
|
function clean() {
|
||||||
|
|
@ -152,11 +217,11 @@
|
||||||
dirty();
|
dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderWaypoints(wps, isroute, parentidx) {
|
function renderWaypointsMap(wps, isroute, parentidx) {
|
||||||
var latlngs = [];
|
var latlngs = [];
|
||||||
for (var i = 0; i < wps.length; i++) {
|
for (var i = 0; i < wps.length; i++) {
|
||||||
if (wps[i].route) {
|
if (wps[i].route) {
|
||||||
renderWaypoints(wps[i].route, true, i);
|
renderWaypointsMap(wps[i].route, true, i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (wps[i].lat == null || wps[i].lon == null)
|
if (wps[i].lat == null || wps[i].lon == null)
|
||||||
|
|
@ -182,7 +247,8 @@
|
||||||
|
|
||||||
function renderAllWaypoints() {
|
function renderAllWaypoints() {
|
||||||
mapmarkers.clearLayers();
|
mapmarkers.clearLayers();
|
||||||
renderWaypoints(waypoints, false, 0);
|
renderWaypointsMap(waypoints, false, 0);
|
||||||
|
renderWaypointsList();
|
||||||
map.addLayer(mapmarkers);
|
map.addLayer(mapmarkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -234,51 +300,18 @@
|
||||||
|
|
||||||
/*** Bangle.js ***/
|
/*** Bangle.js ***/
|
||||||
|
|
||||||
function downloadJSONfile(fileid, callback) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
var pts = require("Storage").readJSON("${fileid}")||[{name:"NONE"}];
|
|
||||||
Bluetooth.print(JSON.stringify(pts));
|
|
||||||
})()\n`, contents => {
|
|
||||||
var storedpts = JSON.parse(contents);
|
|
||||||
callback(storedpts);
|
|
||||||
clean();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadFile(fileid, contents) {
|
|
||||||
Puck.write(`\x10(function() {
|
|
||||||
require("Storage").write("${fileid}",'${contents}');
|
|
||||||
Bluetooth.print("OK");
|
|
||||||
})()\n`, ret => {
|
|
||||||
console.log("uploadFile", ret);
|
|
||||||
if (ret == "OK")
|
|
||||||
clean();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function gotStored(pts) {
|
function gotStored(pts) {
|
||||||
waypoints = pts;
|
waypoints = pts;
|
||||||
|
|
||||||
var latlngs = waypoints.map(p => [p.lat, p.lon]);
|
var latlngs = waypoints.filter(p => isFinite(p.lat)&&isFinite(p.lon)).map(p => [p.lat, p.lon]);
|
||||||
var poly = L.polygon(latlngs);
|
var poly = L.polygon(latlngs);
|
||||||
map.fitBounds(poly.getBounds());
|
var bounds = poly.getBounds();
|
||||||
|
if (bounds.isValid())
|
||||||
|
map.fitBounds(bounds);
|
||||||
|
|
||||||
renderAllWaypoints();
|
renderAllWaypoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onInit() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#download').on('click', function() {
|
|
||||||
downloadJSONfile("waypoints.json", gotStored);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#upload').click(function() {
|
|
||||||
var data = JSON.stringify(waypoints);
|
|
||||||
uploadFile("waypoints.json",data);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#statusarea').click(closeRoute);
|
$('#statusarea').click(closeRoute);
|
||||||
|
|
||||||
/*** map arrows ***/
|
/*** map arrows ***/
|
||||||
|
|
@ -348,5 +381,136 @@
|
||||||
this.x = (round ? Math.round(x) : x);
|
this.x = (round ? Math.round(x) : x);
|
||||||
this.y = (round ? Math.round(y) : y);
|
this.y = (round ? Math.round(y) : y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========================================================================== LIST
|
||||||
|
|
||||||
|
var $name = document.getElementById('add_waypoint_name')
|
||||||
|
var $form = document.getElementById('add_waypoint_form')
|
||||||
|
var $button = document.getElementById('add_waypoint_button')
|
||||||
|
var $name_button = document.getElementById('add_name_button')
|
||||||
|
var $latitude = document.getElementById('add_latitude')
|
||||||
|
var $longtitude = document.getElementById('add_longtitude')
|
||||||
|
var $list = document.getElementById('waypoints')
|
||||||
|
|
||||||
|
function compare(a, b){
|
||||||
|
var x = a.name.toLowerCase();
|
||||||
|
var y = b.name.toLowerCase();
|
||||||
|
if (x=="none") {return -1};
|
||||||
|
if (y=="none") {return 1};
|
||||||
|
if (x < y) {return -1;}
|
||||||
|
if (x > y) {return 1;}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$button.addEventListener('click', event => {
|
||||||
|
event.preventDefault()
|
||||||
|
var name = $name.value.trim()
|
||||||
|
if(!name) return;
|
||||||
|
var lat = parseFloat($latitude.value);
|
||||||
|
var lon = parseFloat($longtitude.value);
|
||||||
|
|
||||||
|
waypoints.push({
|
||||||
|
name, lat,lon,
|
||||||
|
});
|
||||||
|
|
||||||
|
waypoints.sort(compare);
|
||||||
|
|
||||||
|
renderAllWaypoints()
|
||||||
|
$name.value = ''
|
||||||
|
$latitude.value = (0).toPrecision(5);
|
||||||
|
$longtitude.value = (0).toPrecision(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
$name_button.addEventListener('click', event => {
|
||||||
|
event.preventDefault()
|
||||||
|
var name = $name.value.trim()
|
||||||
|
if(!name) return;
|
||||||
|
|
||||||
|
waypoints.push({
|
||||||
|
name
|
||||||
|
});
|
||||||
|
waypoints.sort(compare);
|
||||||
|
|
||||||
|
renderAllWaypoints()
|
||||||
|
$name.value = ''
|
||||||
|
$latitude.value = 0.0000
|
||||||
|
$longtitude.value = 0.0000
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function removeWaypoint(index){
|
||||||
|
$name.value = waypoints[index].name
|
||||||
|
$latitude.value = waypoints[index].lat
|
||||||
|
$longtitude.value = waypoints[index].lon
|
||||||
|
waypoints = waypoints.filter((p,i) => i!==index)
|
||||||
|
renderAllWaypoints()
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderWaypointsList(){
|
||||||
|
$list.innerHTML = ''
|
||||||
|
waypoints.forEach((waypoint,index) => {
|
||||||
|
var $waypoint = document.createElement('tr')
|
||||||
|
if (index==0){
|
||||||
|
$waypoint.innerHTML = `<td>${waypoint.name}</td><td></td><td></td>`
|
||||||
|
} else if(waypoint.lat==undefined){
|
||||||
|
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>------</td><td>-----</td>`;
|
||||||
|
} else {
|
||||||
|
$waypoint.innerHTML = `<td>${waypoint.name}</td><td>${waypoint.lat.toFixed(6)}</td><td>${waypoint.lon.toFixed(6)}</td>`;
|
||||||
|
}
|
||||||
|
$waypoint.innerHTML += `<td><button class="btn btn-action btn-primary" onclick="removeWaypoint(${index})"><i class="icon icon-delete"></i></button></td>`;
|
||||||
|
$list.appendChild($waypoint)
|
||||||
|
})
|
||||||
|
$name.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderWaypoints() {
|
||||||
|
renderWaypointsList();
|
||||||
|
renderWaypointsMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================================== UPLOAD/DOWNLOAD
|
||||||
|
|
||||||
|
function downloadJSONfile(fileid, callback) {
|
||||||
|
// TODO: use interface.js-provided stuff?
|
||||||
|
Puck.write(`\x10(function() {
|
||||||
|
var pts = require("Storage").readJSON("${fileid}")||[{name:"NONE"}];
|
||||||
|
Bluetooth.print(JSON.stringify(pts));
|
||||||
|
})()\n`, contents => {
|
||||||
|
if (contents=='[{name:"NONE"}]') contents="[]";
|
||||||
|
var storedpts = JSON.parse(contents);
|
||||||
|
callback(storedpts);
|
||||||
|
clean();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadFile(fileid, contents) {
|
||||||
|
// TODO: use interface.js-provided stuff?
|
||||||
|
Puck.write(`\x10(function() {
|
||||||
|
require("Storage").write("${fileid}",'${contents}');
|
||||||
|
Bluetooth.print("OK");
|
||||||
|
})()\n`, ret => {
|
||||||
|
console.log("uploadFile", ret);
|
||||||
|
if (ret == "OK")
|
||||||
|
clean();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onInit() {
|
||||||
|
downloadJSONfile("waypoints.json", gotStored);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#download').on('click', function() {
|
||||||
|
downloadJSONfile("waypoints.json", gotStored);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#upload').click(function() {
|
||||||
|
var data = JSON.stringify(waypoints);
|
||||||
|
uploadFile("waypoints.json",data);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ========================================================================== FINALLY...
|
||||||
|
clean();
|
||||||
|
renderAllWaypoints();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
exports.load = (num) => {
|
||||||
|
return require("Storage").readJSON(`waypoints${num?`.${num}`:""}.json`)||[{name:"NONE"}];
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.save = (waypoints,num) => {
|
||||||
|
require("Storage").writeJSON(`waypoints${num?`.${num}`:""}.json`, waypoints);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
{ "id": "waypoints",
|
||||||
|
"name": "Waypoints",
|
||||||
|
"version":"0.01",
|
||||||
|
"description": "Provides 'waypoints.json' used by various navigation apps, as well as a way to edit it from the App Loader with maps or a list",
|
||||||
|
"icon": "app.png",
|
||||||
|
"tags": "tool,outdoors,gps",
|
||||||
|
"type": "waypoints",
|
||||||
|
"supports" : ["BANGLEJS2"],
|
||||||
|
"readme": "README.md",
|
||||||
|
"interface": "interface.html",
|
||||||
|
"storage": [
|
||||||
|
{"name":"waypoints","url":"lib.js"}
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
{"name":"waypoints.json","url":"waypoints.json"},
|
||||||
|
{"name":"waypoints.1.json"},
|
||||||
|
{"name":"waypoints.2.json"},
|
||||||
|
{"name":"waypoints.3.json"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name":"No10",
|
||||||
|
"lat":51.5032,
|
||||||
|
"lon":-0.1269
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"Stone",
|
||||||
|
"lat":51.1788,
|
||||||
|
"lon":-1.8260
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
...
|
...
|
||||||
0.02: First update with ChangeLog Added
|
0.02: First update with ChangeLog Added
|
||||||
|
0.03: Move waypoints.json (and editor) to 'waypoints' app
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
var loc = require("locale");
|
var loc = require("locale");
|
||||||
|
|
||||||
var waypoints = require("Storage").readJSON("waypoints.json") || [];
|
var waypoints = require("waypoints").load();
|
||||||
var wp = waypoints[0];
|
var wp = waypoints[0];
|
||||||
if (wp == undefined) wp = {name:"NONE"};
|
if (wp == undefined) wp = {name:"NONE"};
|
||||||
var wp_bearing = 0;
|
var wp_bearing = 0;
|
||||||
|
|
@ -196,7 +196,7 @@ function addCurrentWaypoint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveWaypoints() {
|
function saveWaypoints() {
|
||||||
require("Storage").writeJSON("waypoints.json", waypoints);
|
require("waypoints").save(waypoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteWaypoint(w) {
|
function deleteWaypoint(w) {
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,16 @@
|
||||||
"id": "wpmoto",
|
"id": "wpmoto",
|
||||||
"name": "Waypointer Moto",
|
"name": "Waypointer Moto",
|
||||||
"shortName": "Waypointer Moto",
|
"shortName": "Waypointer Moto",
|
||||||
"version": "0.02",
|
"version": "0.03",
|
||||||
"description": "Waypoint-based motorcycle navigation aid",
|
"description": "Waypoint-based motorcycle navigation aid",
|
||||||
"icon": "wpmoto.png",
|
"icon": "wpmoto.png",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"screenshots": [{"url":"screenshot.png"},{"url":"screenshot-menu.png"},{"url":"screenshot-delete.png"}],
|
"screenshots": [{"url":"screenshot.png"},{"url":"screenshot-menu.png"},{"url":"screenshot-delete.png"}],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"interface": "wpmoto.html",
|
"dependencies" : { "waypoints":"type" },
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"wpmoto.app.js","url":"app.js"},
|
{"name":"wpmoto.app.js","url":"app.js"},
|
||||||
{"name":"wpmoto.img","url":"icon.js","evaluate":true}
|
{"name":"wpmoto.img","url":"icon.js","evaluate":true}
|
||||||
],
|
]
|
||||||
"data": [{"name":"waypoints.json","url":"waypoints.json"}]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"name":"NONE"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
@ -77,12 +77,13 @@ const APP_KEYS = [
|
||||||
const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports'];
|
const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports'];
|
||||||
const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate'];
|
const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate'];
|
||||||
const SUPPORTS_DEVICES = ["BANGLEJS","BANGLEJS2"]; // device IDs allowed for 'supports'
|
const SUPPORTS_DEVICES = ["BANGLEJS","BANGLEJS2"]; // device IDs allowed for 'supports'
|
||||||
const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","textinput","scheduler","notify","locale","settings"]; // values allowed for "type" field
|
const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","textinput","scheduler","notify","locale","settings","waypoints"]; // values allowed for "type" field
|
||||||
const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info
|
const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info
|
||||||
const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ];
|
const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ];
|
||||||
const GRANDFATHERED_ICONS = ["s7clk", "snek", "astral", "alpinenav", "slomoclock", "arrow", "pebble", "rebble"];
|
const GRANDFATHERED_ICONS = ["s7clk", "snek", "astral", "alpinenav", "slomoclock", "arrow", "pebble", "rebble"];
|
||||||
const INTERNAL_FILES_IN_APP_TYPE = { // list of app types and files they SHOULD provide...
|
const INTERNAL_FILES_IN_APP_TYPE = { // list of app types and files they SHOULD provide...
|
||||||
'textinput' : ['textinput'],
|
'textinput' : ['textinput'],
|
||||||
|
'waypoints' : ['waypoints'],
|
||||||
// notify?
|
// notify?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue