forked from FOSS/BangleApps
commit
e513b90bf4
|
@ -115,3 +115,16 @@
|
||||||
* Integrating fixes in upstream rust heatshrink crate
|
* Integrating fixes in upstream rust heatshrink crate
|
||||||
* Small path optimisations with brouter (removing looplets)
|
* Small path optimisations with brouter (removing looplets)
|
||||||
* Bugfix in nearest segment detection
|
* Bugfix in nearest segment detection
|
||||||
|
|
||||||
|
0.23:
|
||||||
|
* New display algorithm : way faster, larger roads, zooming out is now ok
|
||||||
|
* You will need to re-generate your maps because the new algorithm uses a different scale
|
||||||
|
* Better path simplification
|
||||||
|
* Removed sharp turns auto-detection
|
||||||
|
* Waypoints autodetection using the map : this will generate more points than really needed but can still be effective.
|
||||||
|
* New option: sleep between waypoints
|
||||||
|
* Interface: centered svg preview + display file sizes
|
||||||
|
* Interface: disable/enable waypoints detection and elevation
|
||||||
|
* Touching the screen when sleeping will wake up but not change screen
|
||||||
|
* Removing footways (if bicycles not allowed) to reduce resource usage
|
||||||
|
* Switching screen will clear the screen immediately so you can know your screen touch has been received
|
|
@ -18,7 +18,6 @@ It provides the following features :
|
||||||
- display the path with current position from gps
|
- display the path with current position from gps
|
||||||
- display a local map around you, downloaded from openstreetmap
|
- display a local map around you, downloaded from openstreetmap
|
||||||
- detects and buzzes if you leave the path
|
- detects and buzzes if you leave the path
|
||||||
- (optional) buzzes before sharp turns
|
|
||||||
- (optional) buzzes before waypoints
|
- (optional) buzzes before waypoints
|
||||||
(for example when you need to turn in https://mapstogpx.com/)
|
(for example when you need to turn in https://mapstogpx.com/)
|
||||||
- display instant / average speed
|
- display instant / average speed
|
||||||
|
@ -122,6 +121,7 @@ Few settings for now (feel free to suggest me more) :
|
||||||
- power lcd off (disabled by default): turn lcd off when inactive to save power. the watch will wake up when reaching points,
|
- power lcd off (disabled by default): turn lcd off when inactive to save power. the watch will wake up when reaching points,
|
||||||
when you touch the screen and when speed is below 13km/h.
|
when you touch the screen and when speed is below 13km/h.
|
||||||
- powersave by default: when gipy starts is powersaving activated ? (see below)
|
- powersave by default: when gipy starts is powersaving activated ? (see below)
|
||||||
|
- sleep between waypoints: instead of powersaving between points save power between waypoints (crossroads). this way you can save more. waypoints autodetection is WIP.
|
||||||
|
|
||||||
### Powersaving
|
### Powersaving
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ The algorithm works in the following ways :
|
||||||
|
|
||||||
Activation events are the following :
|
Activation events are the following :
|
||||||
|
|
||||||
- you are near (< 100m) the next point on path
|
- you are near (< 100m) the next point (only waypoints of *sleep between waypoints* is on) on path
|
||||||
- you are slow (< *wake-up speed* setting (13 km/h by default))
|
- you are slow (< *wake-up speed* setting (13 km/h by default))
|
||||||
- you are lost
|
- you are lost
|
||||||
- you press the button / touch the screen
|
- you press the button / touch the screen
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
|
||||||
|
urgent TODO:
|
||||||
|
|
||||||
|
- prefetch tiles ?
|
||||||
|
- update documentation to reflect new display ?
|
||||||
|
- add an image for the arrow ?
|
||||||
|
|
||||||
*** thoughts on lcd power ***
|
*** thoughts on lcd power ***
|
||||||
|
|
||||||
so, i tried experimenting with turning the lcd off in order to save power.
|
so, i tried experimenting with turning the lcd off in order to save power.
|
||||||
|
|
690
apps/gipy/app.js
690
apps/gipy/app.js
|
@ -2,17 +2,16 @@ let simulated = false;
|
||||||
let displaying = false;
|
let displaying = false;
|
||||||
let in_menu = false;
|
let in_menu = false;
|
||||||
let go_backwards = false;
|
let go_backwards = false;
|
||||||
let zoomed = true;
|
|
||||||
let status;
|
let status;
|
||||||
|
|
||||||
let initial_options = Bangle.getOptions();
|
let initial_options = Bangle.getOptions();
|
||||||
|
|
||||||
let interests_colors = [
|
let interests_colors = [
|
||||||
0xffff, // Waypoints, white
|
[1, 1, 1], // Waypoints, white
|
||||||
0xf800, // Bakery, red
|
[1, 0, 0], // Bakery, red
|
||||||
0x001f, // DrinkingWater, blue
|
[0, 0, 1], // DrinkingWater, blue
|
||||||
0x07ff, // Toilets, cyan
|
[0, 1, 1], // Toilets, cyan
|
||||||
0x07e0, // Artwork, green
|
[0, 1, 0], // Artwork, green
|
||||||
];
|
];
|
||||||
|
|
||||||
let Y_OFFSET = 20;
|
let Y_OFFSET = 20;
|
||||||
|
@ -31,9 +30,10 @@ var settings = Object.assign(
|
||||||
active_time: 10,
|
active_time: 10,
|
||||||
brightness: 0.5,
|
brightness: 0.5,
|
||||||
buzz_on_turns: false,
|
buzz_on_turns: false,
|
||||||
disable_bluetooth: true,
|
disable_bluetooth: false,
|
||||||
power_lcd_off: false,
|
power_lcd_off: false,
|
||||||
powersave_by_default: false,
|
powersave_by_default: false,
|
||||||
|
sleep_between_waypoints: false,
|
||||||
},
|
},
|
||||||
s.readJSON("gipy.json", true) || {}
|
s.readJSON("gipy.json", true) || {}
|
||||||
);
|
);
|
||||||
|
@ -152,29 +152,8 @@ class TilesOffsets {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function is not inlined to avoid array declaration in jit
|
|
||||||
function center_points(points, scaled_current_x, scaled_current_y) {
|
|
||||||
return g.transformVertices(points, [
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
-scaled_current_x,
|
|
||||||
-scaled_current_y,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function is not inlined to avoid array declaration in jit
|
|
||||||
function rotate_points(points, c, s) {
|
|
||||||
let center_x = g.getWidth() / 2;
|
|
||||||
let center_y = g.getHeight() / 2 + Y_OFFSET;
|
|
||||||
|
|
||||||
return g.transformVertices(points, [-c, s, s, c, center_x, center_y]);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Map {
|
class Map {
|
||||||
constructor(buffer, offset, filename) {
|
constructor(buffer, offset, filename) {
|
||||||
this.points_cache = []; // don't refetch points all the time
|
|
||||||
// header
|
// header
|
||||||
let color_array = Uint8Array(buffer, offset, 3);
|
let color_array = Uint8Array(buffer, offset, 3);
|
||||||
this.color = [
|
this.color = [
|
||||||
|
@ -262,123 +241,16 @@ class Map {
|
||||||
// offset += encoded_blocks_size;
|
// offset += encoded_blocks_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
display(
|
add_to_tile_image(img, absolute_tile_x, absolute_tile_y) {
|
||||||
displayed_x,
|
let tile_x = absolute_tile_x - this.first_tile[0];
|
||||||
displayed_y,
|
let tile_y = absolute_tile_y - this.first_tile[1];
|
||||||
scale_factor,
|
let side = img.getWidth() - 6;
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
) {
|
|
||||||
g.setColor(this.color[0], this.color[1], this.color[2]);
|
|
||||||
let local_x = displayed_x - this.start_coordinates[0];
|
|
||||||
let local_y = displayed_y - this.start_coordinates[1];
|
|
||||||
let tile_x = Math.floor(local_x / this.side);
|
|
||||||
let tile_y = Math.floor(local_y / this.side);
|
|
||||||
|
|
||||||
let limit = 1;
|
let thick = this.color[0] != 0;
|
||||||
if (!zoomed) {
|
img.setColor(this.color[0], this.color[1], this.color[2]);
|
||||||
limit = 2;
|
|
||||||
}
|
|
||||||
for (let y = tile_y - limit; y <= tile_y + limit; y++) {
|
|
||||||
if (y < 0 || y >= this.grid_size[1]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (let x = tile_x - limit; x <= tile_x + limit; x++) {
|
|
||||||
if (x < 0 || x >= this.grid_size[0]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
this.tile_is_on_screen(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
local_x,
|
|
||||||
local_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
// let colors = [
|
|
||||||
// [0, 0, 0],
|
|
||||||
// [0, 0, 1],
|
|
||||||
// [0, 1, 0],
|
|
||||||
// [0, 1, 1],
|
|
||||||
// [1, 0, 0],
|
|
||||||
// [1, 0, 1],
|
|
||||||
// [1, 1, 0],
|
|
||||||
// [1, 1, 0.5],
|
|
||||||
// [0.5, 0, 0.5],
|
|
||||||
// [0, 0.5, 0.5],
|
|
||||||
// ];
|
|
||||||
if (this.color[0] == 1 && this.color[1] == 0 && this.color[2] == 0) {
|
|
||||||
this.display_thick_tile(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
local_x,
|
|
||||||
local_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.display_tile(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
local_x,
|
|
||||||
local_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tile_is_on_screen(
|
let tile_num = tile_x + tile_y * this.grid_size[0];
|
||||||
tile_x,
|
|
||||||
tile_y,
|
|
||||||
current_x,
|
|
||||||
current_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
) {
|
|
||||||
let width = g.getWidth();
|
|
||||||
let height = g.getHeight();
|
|
||||||
let center_x = width / 2;
|
|
||||||
let center_y = height / 2 + Y_OFFSET;
|
|
||||||
let side = this.side;
|
|
||||||
let tile_center_x = (tile_x + 0.5) * side;
|
|
||||||
let tile_center_y = (tile_y + 0.5) * side;
|
|
||||||
let scaled_center_x = (tile_center_x - current_x) * scale_factor;
|
|
||||||
let scaled_center_y = (tile_center_y - current_y) * scale_factor;
|
|
||||||
let rotated_center_x =
|
|
||||||
scaled_center_x * cos_direction - scaled_center_y * sin_direction;
|
|
||||||
let rotated_center_y =
|
|
||||||
scaled_center_x * sin_direction + scaled_center_y * cos_direction;
|
|
||||||
let on_screen_center_x = center_x - rotated_center_x;
|
|
||||||
let on_screen_center_y = center_y + rotated_center_y;
|
|
||||||
|
|
||||||
let scaled_side = side * scale_factor * Math.sqrt(1 / 2);
|
|
||||||
|
|
||||||
if (on_screen_center_x + scaled_side <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (on_screen_center_x - scaled_side >= width) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (on_screen_center_y + scaled_side <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (on_screen_center_y - scaled_side >= height) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
tile_points(tile_num, tile_x, tile_y, scaled_side) {
|
|
||||||
let line_start_offset = this.tiles_offsets.tile_start_offset(
|
let line_start_offset = this.tiles_offsets.tile_start_offset(
|
||||||
tile_y * this.grid_size[0]
|
tile_y * this.grid_size[0]
|
||||||
);
|
);
|
||||||
|
@ -388,117 +260,37 @@ class Map {
|
||||||
this.tiles_offsets.tile_end_offset(tile_num) - line_start_offset;
|
this.tiles_offsets.tile_end_offset(tile_num) - line_start_offset;
|
||||||
|
|
||||||
let line = this.binary_lines[tile_y];
|
let line = this.binary_lines[tile_y];
|
||||||
// we need to copy both for correct results and for performances
|
for (let i = offset; i < upper_limit; i += 4) {
|
||||||
// let's precompute also.
|
let x1 = (line.buffer[i] / 255) * side + 3;
|
||||||
let cached_tile = new Float64Array(upper_limit - offset);
|
let y1 = ((255 - line.buffer[i + 1]) / 255) * side + 3;
|
||||||
for (let i = offset; i < upper_limit; i += 2) {
|
let x2 = (line.buffer[i + 2] / 255) * side + 3;
|
||||||
let x = (tile_x + line.buffer[i] / 255) * scaled_side;
|
let y2 = ((255 - line.buffer[i + 3]) / 255) * side + 3;
|
||||||
let y = (tile_y + line.buffer[i + 1] / 255) * scaled_side;
|
|
||||||
cached_tile[i - offset] = x;
|
let thickness = 1;
|
||||||
cached_tile[i + 1 - offset] = y;
|
if (thick) {
|
||||||
}
|
thickness = 3.5;
|
||||||
return cached_tile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidate_caches() {
|
let xdiff = x2 - x1;
|
||||||
this.points_cache = [];
|
let ydiff = y2 - y1;
|
||||||
}
|
|
||||||
|
|
||||||
fetch_points(tile_x, tile_y, scaled_side) {
|
|
||||||
let tile_num = tile_x + tile_y * this.grid_size[0];
|
|
||||||
for (let i = 0; i < this.points_cache.length; i++) {
|
|
||||||
if (this.points_cache[i][0] == tile_num) {
|
|
||||||
return this.points_cache[i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.points_cache.length > 40) {
|
|
||||||
this.points_cache.shift();
|
|
||||||
}
|
|
||||||
let points = this.tile_points(tile_num, tile_x, tile_y, scaled_side);
|
|
||||||
this.points_cache.push([tile_num, points]);
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
display_tile(
|
|
||||||
tile_x,
|
|
||||||
tile_y,
|
|
||||||
current_x,
|
|
||||||
current_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
) {
|
|
||||||
"jit";
|
|
||||||
let points = this.fetch_points(tile_x, tile_y, this.side * scale_factor);
|
|
||||||
let scaled_current_x = current_x * scale_factor;
|
|
||||||
let scaled_current_y = current_y * scale_factor;
|
|
||||||
let recentered_points = center_points(
|
|
||||||
points,
|
|
||||||
scaled_current_x,
|
|
||||||
scaled_current_y
|
|
||||||
);
|
|
||||||
let screen_points = rotate_points(
|
|
||||||
recentered_points,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
);
|
|
||||||
|
|
||||||
for (let i = 0; i < screen_points.length; i += 4) {
|
|
||||||
g.drawLine(
|
|
||||||
screen_points[i],
|
|
||||||
screen_points[i + 1],
|
|
||||||
screen_points[i + 2],
|
|
||||||
screen_points[i + 3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
display_thick_tile(
|
|
||||||
tile_x,
|
|
||||||
tile_y,
|
|
||||||
current_x,
|
|
||||||
current_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
) {
|
|
||||||
"jit";
|
|
||||||
|
|
||||||
let points = this.fetch_points(tile_x, tile_y, this.side * scale_factor);
|
|
||||||
let scaled_current_x = current_x * scale_factor;
|
|
||||||
let scaled_current_y = current_y * scale_factor;
|
|
||||||
let recentered_points = center_points(
|
|
||||||
points,
|
|
||||||
scaled_current_x,
|
|
||||||
scaled_current_y
|
|
||||||
);
|
|
||||||
let screen_points = rotate_points(
|
|
||||||
recentered_points,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
);
|
|
||||||
|
|
||||||
for (let i = 0; i < screen_points.length; i += 4) {
|
|
||||||
let final_x = screen_points[i];
|
|
||||||
let final_y = screen_points[i + 1];
|
|
||||||
let new_final_x = screen_points[i + 2];
|
|
||||||
let new_final_y = screen_points[i + 3];
|
|
||||||
|
|
||||||
let xdiff = new_final_x - final_x;
|
|
||||||
let ydiff = new_final_y - final_y;
|
|
||||||
let d = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
|
let d = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
|
||||||
let ox = (-ydiff / d) * 3;
|
let ox = (-ydiff / d) * thickness;
|
||||||
let oy = (xdiff / d) * 3;
|
let oy = (xdiff / d) * thickness;
|
||||||
g.fillPoly([
|
img.fillPoly([
|
||||||
final_x + ox,
|
x1 + ox,
|
||||||
final_y + oy,
|
y1 + oy,
|
||||||
new_final_x + ox,
|
x2 + ox,
|
||||||
new_final_y + oy,
|
y2 + oy,
|
||||||
new_final_x - ox,
|
x2 - ox,
|
||||||
new_final_y - oy,
|
y2 - oy,
|
||||||
final_x - ox,
|
x1 - ox,
|
||||||
final_y - oy,
|
y1 - oy,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// img.drawLine(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,112 +317,30 @@ class Interests {
|
||||||
this.binary_interests[i] = binary_interests[i];
|
this.binary_interests[i] = binary_interests[i];
|
||||||
}
|
}
|
||||||
offset += end;
|
offset += end;
|
||||||
this.points_cache = [];
|
|
||||||
return [this, offset];
|
return [this, offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
display(
|
add_to_tile_image(img, absolute_tile_x, absolute_tile_y) {
|
||||||
displayed_x,
|
let tile_x = absolute_tile_x - this.first_tile[0];
|
||||||
displayed_y,
|
let tile_y = absolute_tile_y - this.first_tile[1];
|
||||||
scale_factor,
|
let side = img.getWidth() - 6;
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
let tile_num = tile_x + tile_y * this.grid_size[0];
|
||||||
) {
|
|
||||||
let local_x = displayed_x - this.start_coordinates[0];
|
|
||||||
let local_y = displayed_y - this.start_coordinates[1];
|
|
||||||
let tile_x = Math.floor(local_x / this.side);
|
|
||||||
let tile_y = Math.floor(local_y / this.side);
|
|
||||||
for (let y = tile_y - 1; y <= tile_y + 1; y++) {
|
|
||||||
if (y < 0 || y >= this.grid_size[1]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (let x = tile_x - 1; x <= tile_x + 1; x++) {
|
|
||||||
if (x < 0 || x >= this.grid_size[0]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.display_tile(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
local_x,
|
|
||||||
local_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tile_points(tile_num, tile_x, tile_y, scaled_side) {
|
|
||||||
let offset = this.offsets.tile_start_offset(tile_num);
|
let offset = this.offsets.tile_start_offset(tile_num);
|
||||||
let upper_limit = this.offsets.tile_end_offset(tile_num);
|
let upper_limit = this.offsets.tile_end_offset(tile_num);
|
||||||
|
|
||||||
let tile_interests = [];
|
let buffer = this.binary_interests;
|
||||||
for (let i = offset; i < upper_limit; i += 3) {
|
for (let i = offset; i < upper_limit; i += 3) {
|
||||||
let interest = this.binary_interests[i];
|
let type = buffer[i];
|
||||||
let x = (tile_x + this.binary_interests[i + 1] / 255) * scaled_side;
|
let x = (buffer[i + 1] / 255) * side + 3;
|
||||||
let y = (tile_y + this.binary_interests[i + 2] / 255) * scaled_side;
|
let y = ((255 - buffer[i + 2]) / 255) * side + 3;
|
||||||
if (interest >= interests_colors.length) {
|
|
||||||
throw "bad interest" + interest + "at" + tile_num + "offset" + i;
|
|
||||||
}
|
|
||||||
tile_interests.push(interest);
|
|
||||||
tile_interests.push(x);
|
|
||||||
tile_interests.push(y);
|
|
||||||
}
|
|
||||||
return tile_interests;
|
|
||||||
}
|
|
||||||
fetch_points(tile_x, tile_y, scaled_side) {
|
|
||||||
//TODO: factorize with map ?
|
|
||||||
let tile_num = tile_x + tile_y * this.grid_size[0];
|
|
||||||
for (let i = 0; i < this.points_cache.length; i++) {
|
|
||||||
if (this.points_cache[i][0] == tile_num) {
|
|
||||||
return this.points_cache[i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.points_cache.length > 40) {
|
|
||||||
this.points_cache.shift();
|
|
||||||
}
|
|
||||||
let points = this.tile_points(tile_num, tile_x, tile_y, scaled_side);
|
|
||||||
this.points_cache.push([tile_num, points]);
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
invalidate_caches() {
|
|
||||||
this.points_cache = [];
|
|
||||||
}
|
|
||||||
display_tile(
|
|
||||||
tile_x,
|
|
||||||
tile_y,
|
|
||||||
displayed_x,
|
|
||||||
displayed_y,
|
|
||||||
scale_factor,
|
|
||||||
cos_direction,
|
|
||||||
sin_direction
|
|
||||||
) {
|
|
||||||
let width = g.getWidth();
|
|
||||||
let half_width = width / 2;
|
|
||||||
let half_height = g.getHeight() / 2 + Y_OFFSET;
|
|
||||||
let interests = this.fetch_points(tile_x, tile_y, this.side * scale_factor);
|
|
||||||
|
|
||||||
let scaled_current_x = displayed_x * scale_factor;
|
|
||||||
let scaled_current_y = displayed_y * scale_factor;
|
|
||||||
|
|
||||||
for (let i = 0; i < interests.length; i += 3) {
|
|
||||||
let type = interests[i];
|
|
||||||
let x = interests[i + 1];
|
|
||||||
let y = interests[i + 2];
|
|
||||||
|
|
||||||
let scaled_x = x - scaled_current_x;
|
|
||||||
let scaled_y = y - scaled_current_y;
|
|
||||||
let rotated_x = scaled_x * cos_direction - scaled_y * sin_direction;
|
|
||||||
let rotated_y = scaled_x * sin_direction + scaled_y * cos_direction;
|
|
||||||
let final_x = half_width - rotated_x;
|
|
||||||
let final_y = half_height + rotated_y;
|
|
||||||
|
|
||||||
let color = interests_colors[type];
|
let color = interests_colors[type];
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
g.setColor(0, 0, 0).fillCircle(final_x, final_y, 6);
|
img.setColor(0, 0, 0).fillCircle(x, y, 6);
|
||||||
}
|
}
|
||||||
g.setColor(color).fillCircle(final_x, final_y, 5);
|
img.setColor(color[0], color[1], color[2]).fillCircle(x, y, 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -645,21 +355,23 @@ class Status {
|
||||||
this.interests = interests;
|
this.interests = interests;
|
||||||
this.heights = heights;
|
this.heights = heights;
|
||||||
this.screen = MAP;
|
this.screen = MAP;
|
||||||
let half_screen_width = g.getWidth() / 2;
|
|
||||||
let half_screen_height = g.getHeight() / 2;
|
|
||||||
let half_screen_diagonal = Math.sqrt(
|
|
||||||
half_screen_width * half_screen_width +
|
|
||||||
half_screen_height * half_screen_height
|
|
||||||
);
|
|
||||||
this.scale_factor = half_screen_diagonal / maps[0].side; // multiply geo coordinates by this to get pixels coordinates
|
|
||||||
this.on_path = true; // are we on the path or lost ?
|
this.on_path = true; // are we on the path or lost ?
|
||||||
this.position = null; // where we are
|
this.position = null; // where we are
|
||||||
this.adjusted_cos_direction = 1; // cos of where we look at
|
this.direction = 0;
|
||||||
this.adjusted_sin_direction = 0; // sin of where we look at
|
this.adjusted_cos_direction = Math.cos(-Math.PI / 2.0);
|
||||||
|
this.adjusted_sin_direction = Math.sin(-Math.PI / 2.0);
|
||||||
|
this.zoomed_in = true;
|
||||||
|
|
||||||
this.current_segment = null; // which segment is closest
|
this.current_segment = null; // which segment is closest
|
||||||
this.reaching = null; // which waypoint are we reaching ?
|
this.reaching = null; // which waypoint are we reaching ?
|
||||||
this.distance_to_next_point = null; // how far are we from next point ?
|
this.distance_to_next_point = null; // how far are we from next point ?
|
||||||
this.projected_point = null;
|
this.projected_point = null;
|
||||||
|
this.reset_images_cache();
|
||||||
|
|
||||||
|
let width = g.getWidth();
|
||||||
|
let height = g.getHeight();
|
||||||
|
let diagonal_third = Math.sqrt(width * width + height * height) / 3;
|
||||||
|
this.scale_factor = diagonal_third / maps[0].side; // multiply geo coordinates by this to get pixels coordinates
|
||||||
|
|
||||||
if (this.path !== null) {
|
if (this.path !== null) {
|
||||||
let r = [0];
|
let r = [0];
|
||||||
|
@ -681,6 +393,28 @@ class Status {
|
||||||
this.old_points = []; // record previous points but only when enough distance between them
|
this.old_points = []; // record previous points but only when enough distance between them
|
||||||
this.old_times = []; // the corresponding times
|
this.old_times = []; // the corresponding times
|
||||||
}
|
}
|
||||||
|
reset_images_cache() {
|
||||||
|
let tiles_per_diagonals = this.zoomed_in ? 3 : 5;
|
||||||
|
let screen_width = g.getWidth();
|
||||||
|
let screen_height = g.getHeight();
|
||||||
|
this.images_cache = [];
|
||||||
|
|
||||||
|
let img_side =
|
||||||
|
Math.ceil(
|
||||||
|
Math.sqrt(screen_width * screen_width + screen_height * screen_height) /
|
||||||
|
tiles_per_diagonals
|
||||||
|
) + 6; // three extra pixels on each side to allow thick lines
|
||||||
|
|
||||||
|
E.defrag();
|
||||||
|
let limit = tiles_per_diagonals * (tiles_per_diagonals + 1);
|
||||||
|
|
||||||
|
for (let i = 0; i < limit; i++) {
|
||||||
|
let img = Graphics.createArrayBuffer(img_side, img_side, 4, {
|
||||||
|
msb: true,
|
||||||
|
});
|
||||||
|
this.images_cache.push({ image: img, x: -1, y: -1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
activate() {
|
activate() {
|
||||||
if (!powersaving) {
|
if (!powersaving) {
|
||||||
return;
|
return;
|
||||||
|
@ -709,14 +443,6 @@ class Status {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
invalidate_caches() {
|
|
||||||
for (let i = 0; i < this.maps.length; i++) {
|
|
||||||
this.maps[i].invalidate_caches();
|
|
||||||
}
|
|
||||||
if (this.interests !== null) {
|
|
||||||
this.interests.invalidate_caches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_position_reached(position) {
|
new_position_reached(position) {
|
||||||
// we try to figure out direction by looking at previous points
|
// we try to figure out direction by looking at previous points
|
||||||
// instead of the gps course which is not very nice.
|
// instead of the gps course which is not very nice.
|
||||||
|
@ -746,11 +472,14 @@ class Status {
|
||||||
|
|
||||||
let oldest_point = this.old_points[0];
|
let oldest_point = this.old_points[0];
|
||||||
let distance_to_oldest = oldest_point.distance(position);
|
let distance_to_oldest = oldest_point.distance(position);
|
||||||
|
let time_to_oldest = now - this.old_times[0];
|
||||||
|
|
||||||
// every 3 points we count the distance
|
// every 3 points we count the distance
|
||||||
if (this.gps_coordinates_counter % 3 == 0) {
|
if (this.gps_coordinates_counter % 3 == 0) {
|
||||||
if (distance_to_oldest < 150.0) {
|
if (time_to_oldest > 6 || distance_to_oldest < 150.0) {
|
||||||
// to avoid gps glitches
|
// to avoid gps glitches (sometimes the gps signal will make you jump around)
|
||||||
|
// however if gps disconnects (time_to_oldest becomes large) we still count the distance
|
||||||
|
// when it re-activates
|
||||||
this.advanced_distance += distance_to_oldest;
|
this.advanced_distance += distance_to_oldest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -778,6 +507,7 @@ class Status {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.direction = direction;
|
||||||
if (in_menu) {
|
if (in_menu) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -877,14 +607,15 @@ class Status {
|
||||||
// }, time_to_next_point);
|
// }, time_to_next_point);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
let reaching_waypoint = this.path.is_waypoint(next_point);
|
||||||
if (this.distance_to_next_point <= 100) {
|
if (this.distance_to_next_point <= 100) {
|
||||||
|
if (reaching_waypoint || !settings.sleep_between_waypoints) {
|
||||||
this.activate();
|
this.activate();
|
||||||
}
|
}
|
||||||
if (this.reaching != next_point && this.distance_to_next_point <= 100) {
|
|
||||||
|
if (this.reaching != next_point) {
|
||||||
this.reaching = next_point;
|
this.reaching = next_point;
|
||||||
let reaching_waypoint = this.path.is_waypoint(next_point);
|
if (reaching_waypoint && settings.buzz_on_turns) {
|
||||||
if (reaching_waypoint) {
|
|
||||||
if (settings.buzz_on_turns) {
|
|
||||||
Bangle.buzz();
|
Bangle.buzz();
|
||||||
setTimeout(() => Bangle.buzz(), 500);
|
setTimeout(() => Bangle.buzz(), 500);
|
||||||
setTimeout(() => Bangle.buzz(), 1000);
|
setTimeout(() => Bangle.buzz(), 1000);
|
||||||
|
@ -922,21 +653,12 @@ class Status {
|
||||||
direction = Math.atan2(diff.lat, diff.lon);
|
direction = Math.atan2(diff.lat, diff.lon);
|
||||||
|
|
||||||
let full_angle = direction - this.angle;
|
let full_angle = direction - this.angle;
|
||||||
// let c = towards.coordinates(p, this.adjusted_cos_direction, this.adjusted_sin_direction, this.scale_factor);
|
|
||||||
// g.setColor(1,0,1).fillCircle(c[0], c[1], 5);
|
|
||||||
|
|
||||||
let scale;
|
|
||||||
if (zoomed) {
|
|
||||||
scale = this.scale_factor;
|
|
||||||
} else {
|
|
||||||
scale = this.scale_factor / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = this.projected_point.coordinates(
|
c = this.projected_point.coordinates(
|
||||||
this.displayed_position,
|
this.displayed_position,
|
||||||
this.adjusted_cos_direction,
|
this.adjusted_cos_direction,
|
||||||
this.adjusted_sin_direction,
|
this.adjusted_sin_direction,
|
||||||
scale
|
this.scale_factor
|
||||||
);
|
);
|
||||||
|
|
||||||
let cos1 = Math.cos(full_angle + 0.6 + Math.PI / 2);
|
let cos1 = Math.cos(full_angle + 0.6 + Math.PI / 2);
|
||||||
|
@ -990,14 +712,97 @@ class Status {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tile_image(absolute_tile_x, absolute_tile_y) {
|
||||||
|
// in the cache old images are front and recently used ones are back
|
||||||
|
let cached_img_index = this.images_cache.findIndex((i) => {
|
||||||
|
return i.x == absolute_tile_x && i.y == absolute_tile_y;
|
||||||
|
});
|
||||||
|
if (cached_img_index == -1) {
|
||||||
|
// console.log("loading", absolute_tile_x, absolute_tile_y);
|
||||||
|
let old_image = this.images_cache.shift();
|
||||||
|
this.compute_tile_image(old_image.image, absolute_tile_x, absolute_tile_y);
|
||||||
|
this.images_cache.push({
|
||||||
|
image: old_image.image,
|
||||||
|
x: absolute_tile_x,
|
||||||
|
y: absolute_tile_y,
|
||||||
|
});
|
||||||
|
return old_image.image;
|
||||||
|
} else {
|
||||||
|
let cached_img = this.images_cache.splice(cached_img_index, 1)[0];
|
||||||
|
this.images_cache.push(cached_img);
|
||||||
|
return cached_img.image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compute_tile_image(img, absolute_tile_x, absolute_tile_y) {
|
||||||
|
img.transparent = img.toColor(1, 1, 1);
|
||||||
|
img.setBgColor(1, 1, 1).clear();
|
||||||
|
|
||||||
|
this.maps.forEach((m) => {
|
||||||
|
m.add_to_tile_image(img, absolute_tile_x, absolute_tile_y);
|
||||||
|
});
|
||||||
|
this.interests.add_to_tile_image(img, absolute_tile_x, absolute_tile_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
display_map() {
|
||||||
|
|
||||||
|
// start_profiling();
|
||||||
|
let displayed_x = this.displayed_position.lon;
|
||||||
|
let displayed_y = this.displayed_position.lat;
|
||||||
|
let tile_x_coord = displayed_x / this.maps[0].side;
|
||||||
|
let tile_y_coord = displayed_y / this.maps[0].side;
|
||||||
|
let absolute_tile_x = Math.floor(tile_x_coord);
|
||||||
|
let absolute_tile_y = Math.floor(tile_y_coord);
|
||||||
|
|
||||||
|
let tiles_per_diagonals = this.zoomed_in ? 3 : 5;
|
||||||
|
let diagonal = Math.ceil(
|
||||||
|
Math.sqrt(g.getWidth() * g.getWidth() + g.getHeight() * g.getHeight()) /
|
||||||
|
tiles_per_diagonals
|
||||||
|
);
|
||||||
|
let angle = this.direction - Math.PI / 2;
|
||||||
|
let cos_direction = Math.cos(angle);
|
||||||
|
let sin_direction = Math.sin(angle);
|
||||||
|
let d = Math.floor(tiles_per_diagonals / 2);
|
||||||
|
|
||||||
|
for (let x = -d; x <= d; x++) {
|
||||||
|
for (let y = -d; y <= d; y++) {
|
||||||
|
let img = this.tile_image(absolute_tile_x + x, absolute_tile_y + y);
|
||||||
|
|
||||||
|
let screen_x =
|
||||||
|
(absolute_tile_x + x + 0.5 - tile_x_coord) * diagonal + 3;
|
||||||
|
let screen_y =
|
||||||
|
-(absolute_tile_y + y + 0.5 - tile_y_coord) * diagonal - 3;
|
||||||
|
|
||||||
|
let rotated_x = screen_x * cos_direction - screen_y * sin_direction;
|
||||||
|
let rotated_y = screen_x * sin_direction + screen_y * cos_direction;
|
||||||
|
let final_x = g.getWidth() / 2 + rotated_x;
|
||||||
|
let final_y = g.getHeight() / 2 + Y_OFFSET + rotated_y;
|
||||||
|
|
||||||
|
g.drawImage(img, final_x, final_y, { rotate: angle });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end_profiling("map display");
|
||||||
|
}
|
||||||
display() {
|
display() {
|
||||||
if (displaying || in_menu) {
|
if (displaying || in_menu) {
|
||||||
return; // don't draw on drawings
|
return; // don't draw on drawings
|
||||||
}
|
}
|
||||||
|
g.reset();
|
||||||
displaying = true;
|
displaying = true;
|
||||||
g.clear();
|
g.clear();
|
||||||
if (this.screen == MAP) {
|
if (this.screen == MAP) {
|
||||||
this.display_map();
|
this.display_map();
|
||||||
|
if (this.position !== null) {
|
||||||
|
// start_profiling();
|
||||||
|
this.display_path();
|
||||||
|
// end_profiling("path display");
|
||||||
|
}
|
||||||
|
|
||||||
|
// start_profiling();
|
||||||
|
this.display_direction();
|
||||||
|
this.display_stats();
|
||||||
|
// end_profiling("direction and stats display");
|
||||||
} else {
|
} else {
|
||||||
let current_position = 0;
|
let current_position = 0;
|
||||||
if (this.current_segment !== null) {
|
if (this.current_segment !== null) {
|
||||||
|
@ -1023,6 +828,7 @@ class Status {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
g.flip();
|
||||||
displaying = false;
|
displaying = false;
|
||||||
}
|
}
|
||||||
display_heights(display_start, current_position, displayed_length) {
|
display_heights(display_start, current_position, displayed_length) {
|
||||||
|
@ -1175,39 +981,6 @@ class Status {
|
||||||
widgets_height
|
widgets_height
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
display_map() {
|
|
||||||
let scale_factor = this.scale_factor;
|
|
||||||
if (!zoomed) {
|
|
||||||
scale_factor /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// start_profiling();
|
|
||||||
for (let i = 0; i < this.maps.length; i++) {
|
|
||||||
this.maps[i].display(
|
|
||||||
this.displayed_position.lon,
|
|
||||||
this.displayed_position.lat,
|
|
||||||
scale_factor,
|
|
||||||
this.adjusted_cos_direction,
|
|
||||||
this.adjusted_sin_direction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// end_profiling("map");
|
|
||||||
if (this.interests !== null) {
|
|
||||||
this.interests.display(
|
|
||||||
this.displayed_position.lon,
|
|
||||||
this.displayed_position.lat,
|
|
||||||
scale_factor,
|
|
||||||
this.adjusted_cos_direction,
|
|
||||||
this.adjusted_sin_direction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this.position !== null) {
|
|
||||||
this.display_path();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.display_direction();
|
|
||||||
this.display_stats();
|
|
||||||
}
|
|
||||||
display_stats() {
|
display_stats() {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
let minutes = now.getMinutes().toString();
|
let minutes = now.getMinutes().toString();
|
||||||
|
@ -1303,9 +1076,6 @@ class Status {
|
||||||
let half_width = width / 2;
|
let half_width = width / 2;
|
||||||
let half_height = height / 2 + Y_OFFSET;
|
let half_height = height / 2 + Y_OFFSET;
|
||||||
let scale_factor = this.scale_factor;
|
let scale_factor = this.scale_factor;
|
||||||
if (!zoomed) {
|
|
||||||
scale_factor /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.path !== null) {
|
if (this.path !== null) {
|
||||||
// compute coordinate for projection on path
|
// compute coordinate for projection on path
|
||||||
|
@ -1424,8 +1194,6 @@ function load_gps(filename) {
|
||||||
|
|
||||||
class Path {
|
class Path {
|
||||||
constructor(buffer, offset) {
|
constructor(buffer, offset) {
|
||||||
// let p = Uint16Array(buffer, offset, 1);
|
|
||||||
// console.log(p);
|
|
||||||
let points_number = Uint16Array(buffer, offset, 1)[0];
|
let points_number = Uint16Array(buffer, offset, 1)[0];
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
||||||
|
@ -1640,11 +1408,11 @@ function start_gipy(path, maps, interests, heights) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Zoom: {
|
Zoom: {
|
||||||
value: zoomed,
|
value: status.zoomed_in,
|
||||||
format: (v) => (v ? "In" : "Out"),
|
format: (v) => (v ? "In" : "Out"),
|
||||||
onchange: (v) => {
|
onchange: (v) => {
|
||||||
status.invalidate_caches();
|
status.zoomed_in = v;
|
||||||
zoomed = v;
|
status.reset_images_cache();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
/*LANG*/
|
/*LANG*/
|
||||||
|
@ -1687,11 +1455,14 @@ function start_gipy(path, maps, interests, heights) {
|
||||||
status.display();
|
status.display();
|
||||||
|
|
||||||
Bangle.on("touch", () => {
|
Bangle.on("touch", () => {
|
||||||
|
let active = status.active;
|
||||||
status.activate();
|
status.activate();
|
||||||
if (in_menu) {
|
if (in_menu) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (status.heights !== null) {
|
if (active && status.heights !== null) {
|
||||||
|
g.clear();
|
||||||
|
g.flip();
|
||||||
status.screen = (status.screen + 1) % 3;
|
status.screen = (status.screen + 1) % 3;
|
||||||
status.display();
|
status.display();
|
||||||
}
|
}
|
||||||
|
@ -1720,51 +1491,52 @@ function start_gipy(path, maps, interests, heights) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (simulated) {
|
if (simulated) {
|
||||||
status.starting_time = getTime();
|
// status.starting_time = getTime();
|
||||||
// let's keep the screen on in simulations
|
// // let's keep the screen on in simulations
|
||||||
Bangle.setLCDTimeout(0);
|
// Bangle.setLCDTimeout(0);
|
||||||
Bangle.setLCDPower(1);
|
// Bangle.setLCDPower(1);
|
||||||
Bangle.loadWidgets(); // i don't know why i cannot load them at start : they would display on splash screen
|
// Bangle.loadWidgets(); // i don't know why i cannot load them at start : they would display on splash screen
|
||||||
|
|
||||||
function simulate_gps(status) {
|
// function simulate_gps(status) {
|
||||||
if (status.path === null) {
|
// if (status.path === null) {
|
||||||
let map = status.maps[0];
|
// let map = status.maps[0];
|
||||||
let p1 = new Point(map.start_coordinates[0], map.start_coordinates[1]);
|
// let p1 = new Point(map.start_coordinates[0], map.start_coordinates[1]);
|
||||||
let p2 = new Point(
|
// let p2 = new Point(
|
||||||
map.start_coordinates[0] + map.side * map.grid_size[0],
|
// map.start_coordinates[0] + map.side * map.grid_size[0],
|
||||||
map.start_coordinates[1] + map.side * map.grid_size[1]
|
// map.start_coordinates[1] + map.side * map.grid_size[1]
|
||||||
);
|
// );
|
||||||
let pos = p1.times(1 - fake_gps_point).plus(p2.times(fake_gps_point));
|
// let pos = p1.times(1 - fake_gps_point).plus(p2.times(fake_gps_point));
|
||||||
if (fake_gps_point < 1) {
|
// if (fake_gps_point < 1) {
|
||||||
fake_gps_point += 0.05;
|
// fake_gps_point += 0.05;
|
||||||
}
|
// }
|
||||||
status.update_position(pos);
|
// status.update_position(pos);
|
||||||
} else {
|
// } else {
|
||||||
if (fake_gps_point > status.path.len - 1 || fake_gps_point < 0) {
|
// if (fake_gps_point > status.path.len - 1 || fake_gps_point < 0) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
let point_index = Math.floor(fake_gps_point);
|
// let point_index = Math.floor(fake_gps_point);
|
||||||
if (point_index >= status.path.len / 2 - 1) {
|
// if (point_index >= status.path.len / 2 - 1) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
let p1 = status.path.point(2 * point_index); // use these to approximately follow path
|
// let p1 = status.path.point(2 * point_index); // use these to approximately follow path
|
||||||
let p2 = status.path.point(2 * (point_index + 1));
|
// let p2 = status.path.point(2 * (point_index + 1));
|
||||||
//let p1 = status.path.point(point_index); // use these to strictly follow path
|
// //let p1 = status.path.point(point_index); // use these to strictly follow path
|
||||||
//let p2 = status.path.point(point_index + 1);
|
// //let p2 = status.path.point(point_index + 1);
|
||||||
|
|
||||||
let alpha = fake_gps_point - point_index;
|
// let alpha = fake_gps_point - point_index;
|
||||||
let pos = p1.times(1 - alpha).plus(p2.times(alpha));
|
// let pos = p1.times(1 - alpha).plus(p2.times(alpha));
|
||||||
|
|
||||||
if (go_backwards) {
|
// if (go_backwards) {
|
||||||
fake_gps_point -= 0.2; // advance simulation
|
// fake_gps_point -= 0.2; // advance simulation
|
||||||
} else {
|
// } else {
|
||||||
fake_gps_point += 0.2; // advance simulation
|
// fake_gps_point += 0.2; // advance simulation
|
||||||
}
|
// }
|
||||||
status.update_position(pos);
|
// console.log(fake_gps_point);
|
||||||
}
|
// status.update_position(pos);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
setInterval(simulate_gps, 500, status);
|
// setInterval(simulate_gps, 500, status);
|
||||||
} else {
|
} else {
|
||||||
status.activate();
|
status.activate();
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,10 @@
|
||||||
|
|
||||||
|
|
||||||
<input type="button" id="upload" name="upload" value="Upload" disabled>
|
<input type="button" id="upload" name="upload" value="Upload" disabled>
|
||||||
|
<input type="checkbox" id="autodetect_waypoints" name="autodetect_waypoints" checked/>
|
||||||
|
<label for="autodetect_waypoints">detect waypoints</label>
|
||||||
|
<input type="checkbox" id="include_elevation" name="include_elevation" checked/>
|
||||||
|
<label for="include_elevation">include elevation</label>
|
||||||
<div id="status"></div>
|
<div id="status"></div>
|
||||||
<div id="svgmap"></div>
|
<div id="svgmap"></div>
|
||||||
|
|
||||||
|
@ -111,10 +115,11 @@ function display_polygon(map) {
|
||||||
}
|
}
|
||||||
|
|
||||||
map.fitBounds(L.latLngBounds(L.latLng(min_lat, min_lng), L.latLng(max_lat, max_lng)));
|
map.fitBounds(L.latLngBounds(L.latLng(min_lat, min_lng), L.latLng(max_lat, max_lng)));
|
||||||
|
|
||||||
document.getElementById('convert').disabled = false;
|
document.getElementById('convert').disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
import init, { load_gps_from_string, get_polygon, get_polyline, request_map, get_gps_content, get_gps_map_svg, gps_from_area } from "./pkg/gps.js";
|
import init, { disable_elevation, load_gps_from_string, get_polygon, get_polyline, request_map, get_gps_content, get_gps_map_svg, gps_from_area } from "./pkg/gps.js";
|
||||||
console.log("imported wasm");
|
console.log("imported wasm");
|
||||||
|
|
||||||
// start map
|
// start map
|
||||||
|
@ -187,7 +192,8 @@ document
|
||||||
status.innerHTML = "file reading completed";
|
status.innerHTML = "file reading completed";
|
||||||
let gpx_content = reader.result;
|
let gpx_content = reader.result;
|
||||||
|
|
||||||
gps_data = load_gps_from_string(gpx_content);
|
let autodetect_waypoints = document.getElementById("autodetect_waypoints").checked;
|
||||||
|
gps_data = load_gps_from_string(gpx_content, autodetect_waypoints);
|
||||||
display_polygon(map);
|
display_polygon(map);
|
||||||
};
|
};
|
||||||
reader.readAsText(this.files[0]);
|
reader.readAsText(this.files[0]);
|
||||||
|
@ -211,8 +217,12 @@ document
|
||||||
request_map(gps_data, key1, value1, key2, value2, key3, value3, key4, value4).then(
|
request_map(gps_data, key1, value1, key2, value2, key3, value3, key4, value4).then(
|
||||||
() => {
|
() => {
|
||||||
|
|
||||||
status.innerHTML = "file converted";
|
let include_elevation = document.getElementById("include_elevation").checked;
|
||||||
|
if (!include_elevation) {
|
||||||
|
disable_elevation(gps_data);
|
||||||
|
}
|
||||||
gps_content = get_gps_content(gps_data);
|
gps_content = get_gps_content(gps_data);
|
||||||
|
status.innerHTML = "file converted (" + gps_content.length + " bytes)";
|
||||||
let svg_string = get_gps_map_svg(gps_data);
|
let svg_string = get_gps_map_svg(gps_data);
|
||||||
let img = document.getElementById("svgmap");
|
let img = document.getElementById("svgmap");
|
||||||
img.innerHTML = svg_string;
|
img.innerHTML = svg_string;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "gipy",
|
"id": "gipy",
|
||||||
"name": "Gipy",
|
"name": "Gipy",
|
||||||
"shortName": "Gipy",
|
"shortName": "Gipy",
|
||||||
"version": "0.22",
|
"version": "0.23",
|
||||||
"description": "Follow gpx files using the gps. Don't get lost in your bike trips and hikes.",
|
"description": "Follow gpx files using the gps. Don't get lost in your bike trips and hikes.",
|
||||||
"allow_emulator":false,
|
"allow_emulator":false,
|
||||||
"icon": "gipy.png",
|
"icon": "gipy.png",
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Gps} gps
|
* @param {Gps} gps
|
||||||
|
*/
|
||||||
|
export function disable_elevation(gps: Gps): void;
|
||||||
|
/**
|
||||||
|
* @param {Gps} gps
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function get_gps_map_svg(gps: Gps): string;
|
export function get_gps_map_svg(gps: Gps): string;
|
||||||
|
@ -40,9 +44,10 @@ export function get_gps_content(gps: Gps): Uint8Array;
|
||||||
export function request_map(gps: Gps, key1: string, value1: string, key2: string, value2: string, key3: string, value3: string, key4: string, value4: string): Promise<void>;
|
export function request_map(gps: Gps, key1: string, value1: string, key2: string, value2: string, key3: string, value3: string, key4: string, value4: string): Promise<void>;
|
||||||
/**
|
/**
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
|
* @param {boolean} autodetect_waypoints
|
||||||
* @returns {Gps}
|
* @returns {Gps}
|
||||||
*/
|
*/
|
||||||
export function load_gps_from_string(input: string): Gps;
|
export function load_gps_from_string(input: string, autodetect_waypoints: boolean): Gps;
|
||||||
/**
|
/**
|
||||||
* @param {number} xmin
|
* @param {number} xmin
|
||||||
* @param {number} ymin
|
* @param {number} ymin
|
||||||
|
@ -62,22 +67,23 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
readonly __wbg_gps_free: (a: number) => void;
|
readonly __wbg_gps_free: (a: number) => void;
|
||||||
|
readonly disable_elevation: (a: number) => void;
|
||||||
readonly get_gps_map_svg: (a: number, b: number) => void;
|
readonly get_gps_map_svg: (a: number, b: number) => void;
|
||||||
readonly get_polygon: (a: number, b: number) => void;
|
readonly get_polygon: (a: number, b: number) => void;
|
||||||
readonly has_heights: (a: number) => number;
|
readonly has_heights: (a: number) => number;
|
||||||
readonly get_polyline: (a: number, b: number) => void;
|
readonly get_polyline: (a: number, b: number) => void;
|
||||||
readonly get_gps_content: (a: number, b: number) => void;
|
readonly get_gps_content: (a: number, b: number) => void;
|
||||||
readonly request_map: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number) => number;
|
readonly request_map: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number) => number;
|
||||||
readonly load_gps_from_string: (a: number, b: number) => number;
|
readonly load_gps_from_string: (a: number, b: number, c: number) => number;
|
||||||
readonly gps_from_area: (a: number, b: number, c: number, d: number) => number;
|
readonly gps_from_area: (a: number, b: number, c: number, d: number) => number;
|
||||||
readonly __wbindgen_malloc: (a: number) => number;
|
readonly __wbindgen_malloc: (a: number) => number;
|
||||||
readonly __wbindgen_realloc: (a: number, b: number, c: number) => number;
|
readonly __wbindgen_realloc: (a: number, b: number, c: number) => number;
|
||||||
readonly __wbindgen_export_2: WebAssembly.Table;
|
readonly __wbindgen_export_2: WebAssembly.Table;
|
||||||
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h9f56e5d7ebbfdb61: (a: number, b: number, c: number) => void;
|
readonly wasm_bindgen__convert__closures__invoke1_mut__hef038f7a61abd0f6: (a: number, b: number, c: number) => void;
|
||||||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
readonly __wbindgen_exn_store: (a: number) => void;
|
readonly __wbindgen_exn_store: (a: number) => void;
|
||||||
readonly wasm_bindgen__convert__closures__invoke2_mut__h193105c6f054446a: (a: number, b: number, c: number, d: number) => void;
|
readonly wasm_bindgen__convert__closures__invoke2_mut__h545ed49cfafdda52: (a: number, b: number, c: number, d: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||||
|
|
|
@ -98,14 +98,6 @@ function takeObject(idx) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
||||||
|
|
||||||
cachedTextDecoder.decode();
|
|
||||||
|
|
||||||
function getStringFromWasm0(ptr, len) {
|
|
||||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
|
||||||
}
|
|
||||||
|
|
||||||
function addHeapObject(obj) {
|
function addHeapObject(obj) {
|
||||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
const idx = heap_next;
|
const idx = heap_next;
|
||||||
|
@ -115,6 +107,14 @@ function addHeapObject(obj) {
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
|
||||||
|
cachedTextDecoder.decode();
|
||||||
|
|
||||||
|
function getStringFromWasm0(ptr, len) {
|
||||||
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||||
|
}
|
||||||
|
|
||||||
function debugString(val) {
|
function debugString(val) {
|
||||||
// primitive types
|
// primitive types
|
||||||
const type = typeof val;
|
const type = typeof val;
|
||||||
|
@ -205,7 +205,7 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
||||||
return real;
|
return real;
|
||||||
}
|
}
|
||||||
function __wbg_adapter_24(arg0, arg1, arg2) {
|
function __wbg_adapter_24(arg0, arg1, arg2) {
|
||||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h9f56e5d7ebbfdb61(arg0, arg1, addHeapObject(arg2));
|
wasm.wasm_bindgen__convert__closures__invoke1_mut__hef038f7a61abd0f6(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _assertClass(instance, klass) {
|
function _assertClass(instance, klass) {
|
||||||
|
@ -214,6 +214,14 @@ function _assertClass(instance, klass) {
|
||||||
}
|
}
|
||||||
return instance.ptr;
|
return instance.ptr;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @param {Gps} gps
|
||||||
|
*/
|
||||||
|
export function disable_elevation(gps) {
|
||||||
|
_assertClass(gps, Gps);
|
||||||
|
wasm.disable_elevation(gps.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Gps} gps
|
* @param {Gps} gps
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
@ -350,12 +358,13 @@ export function request_map(gps, key1, value1, key2, value2, key3, value3, key4,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} input
|
* @param {string} input
|
||||||
|
* @param {boolean} autodetect_waypoints
|
||||||
* @returns {Gps}
|
* @returns {Gps}
|
||||||
*/
|
*/
|
||||||
export function load_gps_from_string(input) {
|
export function load_gps_from_string(input, autodetect_waypoints) {
|
||||||
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ret = wasm.load_gps_from_string(ptr0, len0);
|
const ret = wasm.load_gps_from_string(ptr0, len0, autodetect_waypoints);
|
||||||
return Gps.__wrap(ret);
|
return Gps.__wrap(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,8 +387,8 @@ function handleError(f, args) {
|
||||||
wasm.__wbindgen_exn_store(addHeapObject(e));
|
wasm.__wbindgen_exn_store(addHeapObject(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function __wbg_adapter_85(arg0, arg1, arg2, arg3) {
|
function __wbg_adapter_86(arg0, arg1, arg2, arg3) {
|
||||||
wasm.wasm_bindgen__convert__closures__invoke2_mut__h193105c6f054446a(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
wasm.wasm_bindgen__convert__closures__invoke2_mut__h545ed49cfafdda52(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -454,6 +463,10 @@ function getImports() {
|
||||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||||
takeObject(arg0);
|
takeObject(arg0);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||||
|
const ret = getObject(arg0);
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
||||||
const ret = getStringFromWasm0(arg0, arg1);
|
const ret = getStringFromWasm0(arg0, arg1);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -462,29 +475,6 @@ function getImports() {
|
||||||
const ret = fetch(getObject(arg0));
|
const ret = fetch(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
|
||||||
const ret = getObject(arg0);
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_fetch_749a56934f95c96c = function(arg0, arg1) {
|
|
||||||
const ret = getObject(arg0).fetch(getObject(arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_newwithstrandinit_05d7180788420c40 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
||||||
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_signal_31753ac644b25fbb = function(arg0) {
|
|
||||||
const ret = getObject(arg0).signal;
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_new_6396e586b56e1dff = function() { return handleError(function () {
|
|
||||||
const ret = new AbortController();
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_abort_064ae59cda5cd244 = function(arg0) {
|
|
||||||
getObject(arg0).abort();
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_new_2d0053ee81e4dd2a = function() { return handleError(function () {
|
imports.wbg.__wbg_new_2d0053ee81e4dd2a = function() { return handleError(function () {
|
||||||
const ret = new Headers();
|
const ret = new Headers();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -521,6 +511,25 @@ function getImports() {
|
||||||
const ret = getObject(arg0).text();
|
const ret = getObject(arg0).text();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_fetch_749a56934f95c96c = function(arg0, arg1) {
|
||||||
|
const ret = getObject(arg0).fetch(getObject(arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_signal_31753ac644b25fbb = function(arg0) {
|
||||||
|
const ret = getObject(arg0).signal;
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_new_6396e586b56e1dff = function() { return handleError(function () {
|
||||||
|
const ret = new AbortController();
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_abort_064ae59cda5cd244 = function(arg0) {
|
||||||
|
getObject(arg0).abort();
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_newwithstrandinit_05d7180788420c40 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
|
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
imports.wbg.__wbg_new_abda76e883ba8a5f = function() {
|
||||||
const ret = new Error();
|
const ret = new Error();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -620,7 +629,7 @@ function getImports() {
|
||||||
const a = state0.a;
|
const a = state0.a;
|
||||||
state0.a = 0;
|
state0.a = 0;
|
||||||
try {
|
try {
|
||||||
return __wbg_adapter_85(a, state0.b, arg0, arg1);
|
return __wbg_adapter_86(a, state0.b, arg0, arg1);
|
||||||
} finally {
|
} finally {
|
||||||
state0.a = a;
|
state0.a = a;
|
||||||
}
|
}
|
||||||
|
@ -655,6 +664,10 @@ function getImports() {
|
||||||
const ret = new Uint8Array(getObject(arg0));
|
const ret = new Uint8Array(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_stringify_d6471d300ded9b68 = function() { return handleError(function (arg0) {
|
||||||
|
const ret = JSON.stringify(getObject(arg0));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_get_765201544a2b6869 = function() { return handleError(function (arg0, arg1) {
|
imports.wbg.__wbg_get_765201544a2b6869 = function() { return handleError(function (arg0, arg1) {
|
||||||
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
const ret = Reflect.get(getObject(arg0), getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -667,10 +680,6 @@ function getImports() {
|
||||||
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
||||||
return ret;
|
return ret;
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_stringify_d6471d300ded9b68 = function() { return handleError(function (arg0) {
|
|
||||||
const ret = JSON.stringify(getObject(arg0));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||||
const ret = debugString(getObject(arg1));
|
const ret = debugString(getObject(arg1));
|
||||||
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -685,8 +694,8 @@ function getImports() {
|
||||||
const ret = wasm.memory;
|
const ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper2230 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper2354 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 264, __wbg_adapter_24);
|
const ret = makeMutClosure(arg0, arg1, 299, __wbg_adapter_24);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -2,19 +2,20 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export const memory: WebAssembly.Memory;
|
export const memory: WebAssembly.Memory;
|
||||||
export function __wbg_gps_free(a: number): void;
|
export function __wbg_gps_free(a: number): void;
|
||||||
|
export function disable_elevation(a: number): void;
|
||||||
export function get_gps_map_svg(a: number, b: number): void;
|
export function get_gps_map_svg(a: number, b: number): void;
|
||||||
export function get_polygon(a: number, b: number): void;
|
export function get_polygon(a: number, b: number): void;
|
||||||
export function has_heights(a: number): number;
|
export function has_heights(a: number): number;
|
||||||
export function get_polyline(a: number, b: number): void;
|
export function get_polyline(a: number, b: number): void;
|
||||||
export function get_gps_content(a: number, b: number): void;
|
export function get_gps_content(a: number, b: number): void;
|
||||||
export function request_map(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number): number;
|
export function request_map(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number): number;
|
||||||
export function load_gps_from_string(a: number, b: number): number;
|
export function load_gps_from_string(a: number, b: number, c: number): number;
|
||||||
export function gps_from_area(a: number, b: number, c: number, d: number): number;
|
export function gps_from_area(a: number, b: number, c: number, d: number): number;
|
||||||
export function __wbindgen_malloc(a: number): number;
|
export function __wbindgen_malloc(a: number): number;
|
||||||
export function __wbindgen_realloc(a: number, b: number, c: number): number;
|
export function __wbindgen_realloc(a: number, b: number, c: number): number;
|
||||||
export const __wbindgen_export_2: WebAssembly.Table;
|
export const __wbindgen_export_2: WebAssembly.Table;
|
||||||
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h9f56e5d7ebbfdb61(a: number, b: number, c: number): void;
|
export function wasm_bindgen__convert__closures__invoke1_mut__hef038f7a61abd0f6(a: number, b: number, c: number): void;
|
||||||
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
export function __wbindgen_exn_store(a: number): void;
|
export function __wbindgen_exn_store(a: number): void;
|
||||||
export function wasm_bindgen__convert__closures__invoke2_mut__h193105c6f054446a(a: number, b: number, c: number, d: number): void;
|
export function wasm_bindgen__convert__closures__invoke2_mut__h545ed49cfafdda52(a: number, b: number, c: number, d: number): void;
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
wake_up_speed: 13,
|
wake_up_speed: 13,
|
||||||
active_time: 10,
|
active_time: 10,
|
||||||
buzz_on_turns: false,
|
buzz_on_turns: false,
|
||||||
disable_bluetooth: true,
|
disable_bluetooth: false,
|
||||||
brightness: 0.5,
|
brightness: 0.5,
|
||||||
power_lcd_off: false,
|
power_lcd_off: false,
|
||||||
powersave_by_default: false,
|
powersave_by_default: false,
|
||||||
|
sleep_between_waypoints: false,
|
||||||
},
|
},
|
||||||
require("Storage").readJSON(FILE, true) || {}
|
require("Storage").readJSON(FILE, true) || {}
|
||||||
);
|
);
|
||||||
|
@ -89,6 +90,13 @@
|
||||||
settings.powersave_by_default = v;
|
settings.powersave_by_default = v;
|
||||||
writeSettings();
|
writeSettings();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"sleep between waypoints": {
|
||||||
|
value: settings.sleep_between_waypoints == true,
|
||||||
|
onchange: (v) => {
|
||||||
|
settings.sleep_between_waypoints = v;
|
||||||
|
writeSettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue