From 6b51925109a316507cb9b79cd812d00dad569316 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Mon, 21 Aug 2023 15:09:34 +0200 Subject: [PATCH 01/12] gipy: jit is back --- apps/gipy/ChangeLog | 3 +++ apps/gipy/TODO | 12 +++++++++++- apps/gipy/app.js | 34 +++++++++++++++++++--------------- apps/gipy/metadata.json | 2 +- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/apps/gipy/ChangeLog b/apps/gipy/ChangeLog index 870ad0fdb7..3ca699a4fe 100644 --- a/apps/gipy/ChangeLog +++ b/apps/gipy/ChangeLog @@ -98,3 +98,6 @@ * New setting : power screen off between points to save battery * Color change for lost direction (now purple) * Adaptive screen powersaving + +0.21: + * Jit is back for display functions (10% speed increase) diff --git a/apps/gipy/TODO b/apps/gipy/TODO index b2a3c7ae1d..614d2dda2a 100644 --- a/apps/gipy/TODO +++ b/apps/gipy/TODO @@ -36,10 +36,20 @@ my conclusion is that: ************************** +JIT: array declaration in jit is buggy +(especially several declarations) + +************************** + ++ there is still a bug with negative remaining distances (when lost and nearest point is endpoint ?) ++ when lost we still get powersaving ++ try disabling gps for more powersaving + ++ add heights + + when you walk the direction still has a tendency to shift + put back foot only ways -+ try fiddling with jit + put back street names + put back shortest paths but with points cache this time and jit + how to display paths from shortest path ? diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 071ef82835..3a1ddcc61b 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -139,6 +139,19 @@ 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 { constructor(buffer, offset, filename) { this.points_cache = []; // don't refetch points all the time @@ -393,17 +406,12 @@ class Map { cos_direction, sin_direction ) { - // "jit"; - let center_x = g.getWidth() / 2; - let center_y = g.getHeight() / 2 + Y_OFFSET; - + "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 = g.transformVertices(points, [1, 0, 0, 1, -scaled_current_x, -scaled_current_y]); - let c = cos_direction; - let s = sin_direction; - let screen_points = g.transformVertices(recentered_points, [-c, s, s, c, center_x, center_y]); + 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]); @@ -419,17 +427,13 @@ class Map { cos_direction, sin_direction ) { - // "jit"; - let center_x = g.getWidth() / 2; - let center_y = g.getHeight() / 2 + Y_OFFSET; + "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 = g.transformVertices(points, [1, 0, 0, 1, -scaled_current_x, -scaled_current_y]); - let c = cos_direction; - let s = sin_direction; - let screen_points = g.transformVertices(recentered_points, [-c, s, s, c, center_x, center_y]); + 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]; diff --git a/apps/gipy/metadata.json b/apps/gipy/metadata.json index 7dd4123f68..3526e1afa5 100644 --- a/apps/gipy/metadata.json +++ b/apps/gipy/metadata.json @@ -2,7 +2,7 @@ "id": "gipy", "name": "Gipy", "shortName": "Gipy", - "version": "0.20", + "version": "0.21", "description": "Follow gpx files using the gps. Don't get lost in your bike trips and hikes.", "allow_emulator":false, "icon": "gipy.png", From 3a6eb8b2adc41dd06cdffb6dd7fe9e07c3050493 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Mon, 21 Aug 2023 17:02:29 +0200 Subject: [PATCH 02/12] gipy: parsing heights --- apps/gipy/TODO | 3 +++ apps/gipy/app.js | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/gipy/TODO b/apps/gipy/TODO index 614d2dda2a..51ca381842 100644 --- a/apps/gipy/TODO +++ b/apps/gipy/TODO @@ -46,6 +46,9 @@ JIT: array declaration in jit is buggy + try disabling gps for more powersaving + add heights + -> have two views: zoomed in and zoomed out + ++ remove "lost" indicator and change position point's color instead + when you walk the direction still has a tendency to shift diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 3a1ddcc61b..c608d182ac 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -593,13 +593,14 @@ class Interests { } class Status { - constructor(path, maps, interests) { + constructor(path, maps, interests, heights) { this.path = path; this.default_options = true; // do we still have default options ? this.active = false; // should we have screen on this.last_activity = getTime(); this.maps = maps; this.interests = interests; + this.heights = heights; let half_screen_width = g.getWidth() / 2; let half_screen_height = g.getHeight() / 2; let half_screen_diagonal = Math.sqrt( @@ -1164,6 +1165,7 @@ function load_gps(filename) { let offset = 0; let path = null; + let heights = null; let maps = []; let interests = null; while (offset < file_size) { @@ -1186,6 +1188,11 @@ function load_gps(filename) { let res = new Interests(buffer, offset); interests = res[0]; offset = res[1]; + } else if (block_type == 4) { + console.log("loading heights"); + let heights_number = path.points.length / 2; + heights = Float64Array(buffer, offset, heights_number); + offset += 8 * heights_number; } else { console.log("todo : block type", block_type); } @@ -1197,10 +1204,10 @@ function load_gps(filename) { let msg = "invalid file\nsize " + file_size + "\ninstead of" + offset; E.showAlert(msg).then(function() { E.showAlert(); - start_gipy(path, maps, interests); + start_gipy(path, maps, interests, heights); }); } else { - start_gipy(path, maps, interests); + start_gipy(path, maps, interests, heights); } } @@ -1394,14 +1401,14 @@ function start(fn) { load_gps(fn); } -function start_gipy(path, maps, interests) { +function start_gipy(path, maps, interests, heights) { console.log("starting"); if (!simulated && settings.disable_bluetooth) { NRF.sleep(); // disable bluetooth completely } - status = new Status(path, maps, interests); + status = new Status(path, maps, interests, heights); setWatch( function() { From df46cd643e47f76cc752fac41e60ae8052d20faa Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Tue, 22 Aug 2023 14:37:44 +0200 Subject: [PATCH 03/12] gipy: elevation --- apps/gipy/README.md | 7 + apps/gipy/TODO | 3 - apps/gipy/app.js | 3047 +++++++++++++++++--------------- apps/gipy/pkg/gps.d.ts | 48 +- apps/gipy/pkg/gps.js | 735 +------- apps/gipy/pkg/gps_bg.wasm | Bin 748683 -> 743877 bytes apps/gipy/pkg/gps_bg.wasm.d.ts | 5 +- apps/gipy/pkg/package.json | 1 + 8 files changed, 1643 insertions(+), 2203 deletions(-) diff --git a/apps/gipy/README.md b/apps/gipy/README.md index 03ca977538..ac65f8c3ff 100644 --- a/apps/gipy/README.md +++ b/apps/gipy/README.md @@ -28,6 +28,7 @@ It provides the following features : - toilets - artwork - bakeries +- display elevation data if available in the trace ## Usage @@ -95,6 +96,12 @@ The distance to next point displayed corresponds to the length of the black segm If you click the button you'll reach a menu where you can currently zoom out to see more of the map (with a slower refresh rate), reverse the path direction and disable power saving (keeping backlight on). +### Elevation + +If you touch the screen you will switch between display modes. +The first one displays the map, the second one the nearby elevation and the last one the elevation +for the whole path. + ### Settings Few settings for now (feel free to suggest me more) : diff --git a/apps/gipy/TODO b/apps/gipy/TODO index 51ca381842..ef1df3dc5f 100644 --- a/apps/gipy/TODO +++ b/apps/gipy/TODO @@ -45,9 +45,6 @@ JIT: array declaration in jit is buggy + when lost we still get powersaving + try disabling gps for more powersaving -+ add heights - -> have two views: zoomed in and zoomed out - + remove "lost" indicator and change position point's color instead + when you walk the direction still has a tendency to shift diff --git a/apps/gipy/app.js b/apps/gipy/app.js index c608d182ac..70c1aafd36 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -7,24 +7,31 @@ let powersaving = true; let status; let interests_colors = [ - 0xffff, // Waypoints, white - 0xf800, // Bakery, red - 0x001f, // DrinkingWater, blue - 0x07ff, // Toilets, cyan - 0x07e0, // Artwork, green + 0xffff, // Waypoints, white + 0xf800, // Bakery, red + 0x001f, // DrinkingWater, blue + 0x07ff, // Toilets, cyan + 0x07e0, // Artwork, green ]; let Y_OFFSET = 20; + +// some constants for screen types +let MAP = 0; +let HEIGHTS_ZOOMED_IN = 1; +let HEIGHTS_FULL = 2; + let s = require("Storage"); -var settings = Object.assign({ - lost_distance: 50, - brightness: 0.5, - buzz_on_turns: false, - disable_bluetooth: true, - power_lcd_off: false, - }, - s.readJSON("gipy.json", true) || {} +var settings = Object.assign( + { + lost_distance: 50, + brightness: 0.5, + buzz_on_turns: false, + disable_bluetooth: true, + power_lcd_off: false, + }, + s.readJSON("gipy.json", true) || {} ); // let profile_start_times = []; @@ -41,25 +48,25 @@ var settings = Object.assign({ // return the index of the largest element of the array which is <= x function binary_search(array, x) { - let start = 0, - end = array.length; - - while (end - start >= 0) { - let mid = Math.floor((start + end) / 2); - if (array[mid] == x) { - return mid; - } else if (array[mid] < x) { - if (array[mid + 1] > x) { - return mid; - } - start = mid + 1; - } else end = mid - 1; - } - if (array[start] > x) { - return null; - } else { - return start; - } + let start = 0, + end = array.length; + + while (end - start >= 0) { + let mid = Math.floor((start + end) / 2); + if (array[mid] == x) { + return mid; + } else if (array[mid] < x) { + if (array[mid + 1] > x) { + return mid; + } + start = mid + 1; + } else end = mid - 1; + } + if (array[start] > x) { + return null; + } else { + return start; + } } // return a string containing estimated time of arrival. @@ -67,81 +74,88 @@ function binary_search(array, x) { // remaining distance in km // hour, minutes is current time function compute_eta(hour, minutes, approximate_speed, remaining_distance) { - if (isNaN(approximate_speed) || approximate_speed < 0.1) { - return ""; - } - let time_needed = (remaining_distance * 60) / approximate_speed; // in minutes - let eta_in_minutes = Math.round(hour * 60 + minutes + time_needed); - let eta_minutes = eta_in_minutes % 60; - let eta_hour = ((eta_in_minutes - eta_minutes) / 60) % 24; - if (eta_minutes < 10) { - return eta_hour.toString() + ":0" + eta_minutes; - } else { - return eta_hour.toString() + ":" + eta_minutes; - } + if (isNaN(approximate_speed) || approximate_speed < 0.1) { + return ""; + } + let time_needed = (remaining_distance * 60) / approximate_speed; // in minutes + let eta_in_minutes = Math.round(hour * 60 + minutes + time_needed); + let eta_minutes = eta_in_minutes % 60; + let eta_hour = ((eta_in_minutes - eta_minutes) / 60) % 24; + if (eta_minutes < 10) { + return eta_hour.toString() + ":0" + eta_minutes; + } else { + return eta_hour.toString() + ":" + eta_minutes; + } } class TilesOffsets { - constructor(buffer, offset) { - let type_size = Uint8Array(buffer, offset, 1)[0]; - offset += 1; - this.entry_size = Uint8Array(buffer, offset, 1)[0]; - offset += 1; - let non_empty_tiles_number = Uint16Array(buffer, offset, 1)[0]; - offset += 2; - this.non_empty_tiles = Uint16Array(buffer, offset, non_empty_tiles_number); - offset += 2 * non_empty_tiles_number; - if (type_size == 24) { - this.non_empty_tiles_ends = Uint24Array( - buffer, - offset, - non_empty_tiles_number - ); - offset += 3 * non_empty_tiles_number; - } else if (type_size == 16) { - this.non_empty_tiles_ends = Uint16Array( - buffer, - offset, - non_empty_tiles_number - ); - offset += 2 * non_empty_tiles_number; - } else { - throw "unknown size"; - } - return [this, offset]; + constructor(buffer, offset) { + let type_size = Uint8Array(buffer, offset, 1)[0]; + offset += 1; + this.entry_size = Uint8Array(buffer, offset, 1)[0]; + offset += 1; + let non_empty_tiles_number = Uint16Array(buffer, offset, 1)[0]; + offset += 2; + this.non_empty_tiles = Uint16Array(buffer, offset, non_empty_tiles_number); + offset += 2 * non_empty_tiles_number; + if (type_size == 24) { + this.non_empty_tiles_ends = Uint24Array( + buffer, + offset, + non_empty_tiles_number + ); + offset += 3 * non_empty_tiles_number; + } else if (type_size == 16) { + this.non_empty_tiles_ends = Uint16Array( + buffer, + offset, + non_empty_tiles_number + ); + offset += 2 * non_empty_tiles_number; + } else { + throw "unknown size"; } - tile_start_offset(tile_index) { - if (tile_index <= this.non_empty_tiles[0]) { - return 0; - } else { - return this.tile_end_offset(tile_index - 1); - } + return [this, offset]; + } + tile_start_offset(tile_index) { + if (tile_index <= this.non_empty_tiles[0]) { + return 0; + } else { + return this.tile_end_offset(tile_index - 1); } - tile_end_offset(tile_index) { - let me_or_before = binary_search(this.non_empty_tiles, tile_index); - if (me_or_before === null) { - return 0; - } - if (me_or_before >= this.non_empty_tiles_ends.length) { - return ( - this.non_empty_tiles_ends[this.non_empty_tiles.length - 1] * - this.entry_size - ); - } else { - return this.non_empty_tiles_ends[me_or_before] * this.entry_size; - } + } + tile_end_offset(tile_index) { + let me_or_before = binary_search(this.non_empty_tiles, tile_index); + if (me_or_before === null) { + return 0; } - end_offset() { - return ( - this.non_empty_tiles_ends[this.non_empty_tiles_ends.length - 1] * - this.entry_size - ); + if (me_or_before >= this.non_empty_tiles_ends.length) { + return ( + this.non_empty_tiles_ends[this.non_empty_tiles.length - 1] * + this.entry_size + ); + } else { + return this.non_empty_tiles_ends[me_or_before] * this.entry_size; } + } + end_offset() { + return ( + this.non_empty_tiles_ends[this.non_empty_tiles_ends.length - 1] * + this.entry_size + ); + } } // 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]); + 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 @@ -153,1438 +167,1627 @@ function rotate_points(points, c, s) { } class Map { - constructor(buffer, offset, filename) { - this.points_cache = []; // don't refetch points all the time - // header - let color_array = Uint8Array(buffer, offset, 3); - this.color = [ - color_array[0] / 255, - color_array[1] / 255, - color_array[2] / 255, - ]; - offset += 3; - this.first_tile = Int32Array(buffer, offset, 2); // absolute tile id of first tile - offset += 2 * 4; - this.grid_size = Uint32Array(buffer, offset, 2); // tiles width and height - offset += 2 * 4; - this.start_coordinates = Float64Array(buffer, offset, 2); // min x and y coordinates - offset += 2 * 8; - let side_array = Float64Array(buffer, offset, 1); // side of a tile - this.side = side_array[0]; - offset += 8; - - // tiles offsets - let res = new TilesOffsets(buffer, offset); - this.tiles_offsets = res[0]; - offset = res[1]; - - // now, do binary ways - // since the file is so big we'll go line by line - let binary_lines = []; - for (let y = 0; y < this.grid_size[1]; y++) { - let first_tile_start = this.tiles_offsets.tile_start_offset( - y * this.grid_size[0] + constructor(buffer, offset, filename) { + this.points_cache = []; // don't refetch points all the time + // header + let color_array = Uint8Array(buffer, offset, 3); + this.color = [ + color_array[0] / 255, + color_array[1] / 255, + color_array[2] / 255, + ]; + offset += 3; + this.first_tile = Int32Array(buffer, offset, 2); // absolute tile id of first tile + offset += 2 * 4; + this.grid_size = Uint32Array(buffer, offset, 2); // tiles width and height + offset += 2 * 4; + this.start_coordinates = Float64Array(buffer, offset, 2); // min x and y coordinates + offset += 2 * 8; + let side_array = Float64Array(buffer, offset, 1); // side of a tile + this.side = side_array[0]; + offset += 8; + + // tiles offsets + let res = new TilesOffsets(buffer, offset); + this.tiles_offsets = res[0]; + offset = res[1]; + + // now, do binary ways + // since the file is so big we'll go line by line + let binary_lines = []; + for (let y = 0; y < this.grid_size[1]; y++) { + let first_tile_start = this.tiles_offsets.tile_start_offset( + y * this.grid_size[0] + ); + let last_tile_end = this.tiles_offsets.tile_start_offset( + (y + 1) * this.grid_size[0] + ); + let size = last_tile_end - first_tile_start; + let string = s.read(filename, offset + first_tile_start, size); + let array = Uint8Array(E.toArrayBuffer(string)); + binary_lines.push(array); + } + this.binary_lines = binary_lines; + offset += this.tiles_offsets.end_offset(); + + return [this, offset]; + + // now do streets data header + // let streets_header = E.toArrayBuffer(s.read(filename, offset, 8)); + // let streets_header_offset = 0; + // let full_streets_size = Uint32Array( + // streets_header, + // streets_header_offset, + // 1 + // )[0]; + // streets_header_offset += 4; + // let blocks_number = Uint16Array( + // streets_header, + // streets_header_offset, + // 1 + // )[0]; + // streets_header_offset += 2; + // let labels_string_size = Uint16Array( + // streets_header, + // streets_header_offset, + // 1 + // )[0]; + // streets_header_offset += 2; + // offset += streets_header_offset; + + // // continue with main streets labels + // main_streets_labels = s.read(filename, offset, labels_string_size); + // // this.main_streets_labels = main_streets_labels.split(/\r?\n/); + // this.main_streets_labels = main_streets_labels.split(/\n/); + // offset += labels_string_size; + + // // continue with blocks start offsets + // this.blocks_offsets = Uint32Array( + // E.toArrayBuffer(s.read(filename, offset, blocks_number * 4)) + // ); + // offset += blocks_number * 4; + + // // continue with compressed street blocks + // let encoded_blocks_size = + // full_streets_size - 4 - 2 - 2 - labels_string_size - blocks_number * 4; + // this.compressed_streets = Uint8Array( + // E.toArrayBuffer(s.read(filename, offset, encoded_blocks_size)) + // ); + // offset += encoded_blocks_size; + } + + display( + displayed_x, + displayed_y, + scale_factor, + 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; + if (!zoomed) { + 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 ); - let last_tile_end = this.tiles_offsets.tile_start_offset( - (y + 1) * this.grid_size[0] + } else { + this.display_tile( + x, + y, + local_x, + local_y, + scale_factor, + cos_direction, + sin_direction ); - let size = last_tile_end - first_tile_start; - let string = s.read(filename, offset + first_tile_start, size); - let array = Uint8Array(E.toArrayBuffer(string)); - binary_lines.push(array); - } - this.binary_lines = binary_lines; - offset += this.tiles_offsets.end_offset(); - - return [this, offset]; - - // now do streets data header - // let streets_header = E.toArrayBuffer(s.read(filename, offset, 8)); - // let streets_header_offset = 0; - // let full_streets_size = Uint32Array( - // streets_header, - // streets_header_offset, - // 1 - // )[0]; - // streets_header_offset += 4; - // let blocks_number = Uint16Array( - // streets_header, - // streets_header_offset, - // 1 - // )[0]; - // streets_header_offset += 2; - // let labels_string_size = Uint16Array( - // streets_header, - // streets_header_offset, - // 1 - // )[0]; - // streets_header_offset += 2; - // offset += streets_header_offset; - - // // continue with main streets labels - // main_streets_labels = s.read(filename, offset, labels_string_size); - // // this.main_streets_labels = main_streets_labels.split(/\r?\n/); - // this.main_streets_labels = main_streets_labels.split(/\n/); - // offset += labels_string_size; - - // // continue with blocks start offsets - // this.blocks_offsets = Uint32Array( - // E.toArrayBuffer(s.read(filename, offset, blocks_number * 4)) - // ); - // offset += blocks_number * 4; - - // // continue with compressed street blocks - // let encoded_blocks_size = - // full_streets_size - 4 - 2 - 2 - labels_string_size - blocks_number * 4; - // this.compressed_streets = Uint8Array( - // E.toArrayBuffer(s.read(filename, offset, encoded_blocks_size)) - // ); - // offset += encoded_blocks_size; - } - - display( - displayed_x, - displayed_y, - scale_factor, - 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; - if (!zoomed) { - 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( - 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_is_on_screen( + 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; } - - tile_points(tile_num, tile_x, tile_y, scaled_side) { - let line_start_offset = this.tiles_offsets.tile_start_offset( - tile_y * this.grid_size[0] - ); - let offset = - this.tiles_offsets.tile_start_offset(tile_num) - line_start_offset; - let upper_limit = - this.tiles_offsets.tile_end_offset(tile_num) - line_start_offset; - - let line = this.binary_lines[tile_y]; - // we need to copy both for correct results and for performances - // let's precompute also. - let cached_tile = new Float64Array(upper_limit - offset); - for (let i = offset; i < upper_limit; i += 2) { - let x = (tile_x + line.buffer[i] / 255) * scaled_side; - let y = (tile_y + line.buffer[i + 1] / 255) * scaled_side; - cached_tile[i - offset] = x; - cached_tile[i + 1 - offset] = y; - } - return cached_tile; + if (on_screen_center_x - scaled_side >= width) { + return false; } - - invalidate_caches() { - this.points_cache = []; + if (on_screen_center_y + scaled_side <= 0) { + return false; + } + if (on_screen_center_y - scaled_side >= height) { + return false; } + return true; + } - 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; + tile_points(tile_num, tile_x, tile_y, scaled_side) { + let line_start_offset = this.tiles_offsets.tile_start_offset( + tile_y * this.grid_size[0] + ); + let offset = + this.tiles_offsets.tile_start_offset(tile_num) - line_start_offset; + let upper_limit = + this.tiles_offsets.tile_end_offset(tile_num) - line_start_offset; + + let line = this.binary_lines[tile_y]; + // we need to copy both for correct results and for performances + // let's precompute also. + let cached_tile = new Float64Array(upper_limit - offset); + for (let i = offset; i < upper_limit; i += 2) { + let x = (tile_x + line.buffer[i] / 255) * scaled_side; + let y = (tile_y + line.buffer[i + 1] / 255) * scaled_side; + cached_tile[i - offset] = x; + cached_tile[i + 1 - offset] = y; + } + return cached_tile; + } + + invalidate_caches() { + this.points_cache = []; + } + + 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 + ); - 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]); - } + 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 + ); - 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 ox = (-ydiff / d) * 3; - let oy = (xdiff / d) * 3; - g.fillPoly([ - final_x + ox, - final_y + oy, - new_final_x + ox, - new_final_y + oy, - new_final_x - ox, - new_final_y - oy, - final_x - ox, - final_y - oy, - ]); - } + 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 ox = (-ydiff / d) * 3; + let oy = (xdiff / d) * 3; + g.fillPoly([ + final_x + ox, + final_y + oy, + new_final_x + ox, + new_final_y + oy, + new_final_x - ox, + new_final_y - oy, + final_x - ox, + final_y - oy, + ]); } + } } class Interests { - constructor(buffer, offset) { - this.first_tile = Int32Array(buffer, offset, 2); // absolute tile id of first tile - offset += 2 * 4; - this.grid_size = Uint32Array(buffer, offset, 2); // tiles width and height - offset += 2 * 4; - this.start_coordinates = Float64Array(buffer, offset, 2); // min x and y coordinates - offset += 2 * 8; - let side_array = Float64Array(buffer, offset, 1); // side of a tile - this.side = side_array[0]; - offset += 8; - - let res = new TilesOffsets(buffer, offset); - offset = res[1]; - this.offsets = res[0]; - let end = this.offsets.end_offset(); - this.binary_interests = new Uint8Array(end); - let binary_interests = Uint8Array(buffer, offset, end); - for (let i = 0; i < end; i++) { - this.binary_interests[i] = binary_interests[i]; - } - offset += end; - this.points_cache = []; - return [this, offset]; + constructor(buffer, offset) { + this.first_tile = Int32Array(buffer, offset, 2); // absolute tile id of first tile + offset += 2 * 4; + this.grid_size = Uint32Array(buffer, offset, 2); // tiles width and height + offset += 2 * 4; + this.start_coordinates = Float64Array(buffer, offset, 2); // min x and y coordinates + offset += 2 * 8; + let side_array = Float64Array(buffer, offset, 1); // side of a tile + this.side = side_array[0]; + offset += 8; + + let res = new TilesOffsets(buffer, offset); + offset = res[1]; + this.offsets = res[0]; + let end = this.offsets.end_offset(); + this.binary_interests = new Uint8Array(end); + let binary_interests = Uint8Array(buffer, offset, end); + for (let i = 0; i < end; i++) { + this.binary_interests[i] = binary_interests[i]; } - - display( - displayed_x, - displayed_y, - scale_factor, - cos_direction, - sin_direction - ) { - 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 - ); - } + offset += end; + this.points_cache = []; + return [this, offset]; + } + + display( + displayed_x, + displayed_y, + scale_factor, + cos_direction, + sin_direction + ) { + 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 upper_limit = this.offsets.tile_end_offset(tile_num); - - let tile_interests = []; - for (let i = offset; i < upper_limit; i += 3) { - let interest = this.binary_interests[i]; - let x = (tile_x + this.binary_interests[i + 1] / 255) * scaled_side; - let y = (tile_y + this.binary_interests[i + 2] / 255) * scaled_side; - 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]; - if (type == 0) { - g.setColor(0, 0, 0).fillCircle(final_x, final_y, 6); - } - g.setColor(color).fillCircle(final_x, final_y, 5); - } + } + + tile_points(tile_num, tile_x, tile_y, scaled_side) { + let offset = this.offsets.tile_start_offset(tile_num); + let upper_limit = this.offsets.tile_end_offset(tile_num); + + let tile_interests = []; + for (let i = offset; i < upper_limit; i += 3) { + let interest = this.binary_interests[i]; + let x = (tile_x + this.binary_interests[i + 1] / 255) * scaled_side; + let y = (tile_y + this.binary_interests[i + 2] / 255) * scaled_side; + 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]; + if (type == 0) { + g.setColor(0, 0, 0).fillCircle(final_x, final_y, 6); + } + g.setColor(color).fillCircle(final_x, final_y, 5); + } + } } class Status { - constructor(path, maps, interests, heights) { - this.path = path; - this.default_options = true; // do we still have default options ? - this.active = false; // should we have screen on - this.last_activity = getTime(); - this.maps = maps; - this.interests = interests; - this.heights = heights; - 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.position = null; // where we are - this.adjusted_cos_direction = 1; // cos of where we look at - this.adjusted_sin_direction = 0; // sin of where we look at - this.current_segment = null; // which segment is closest - this.reaching = null; // which waypoint are we reaching ? - this.distance_to_next_point = null; // how far are we from next point ? - this.projected_point = null; - - if (this.path !== null) { - let r = [0]; - // let's do a reversed prefix computations on all distances: - // loop on all segments in reversed order - let previous_point = null; - for (let i = this.path.len - 1; i >= 0; i--) { - let point = this.path.point(i); - if (previous_point !== null) { - r.unshift(r[0] + point.distance(previous_point)); - } - previous_point = point; - } - this.remaining_distances = r; // how much distance remains at start of each segment - } - this.starting_time = null; // time we start - this.advanced_distance = 0.0; - this.gps_coordinates_counter = 0; // how many coordinates did we receive - this.old_points = []; // record previous points but only when enough distance between them - this.old_times = []; // the corresponding times - } - activate() { - this.last_activity = getTime(); - if (this.active) { - return; - } else { - this.active = true; - Bangle.setLCDBrightness(settings.brightness); - Bangle.setLocked(false); - if (settings.power_lcd_off) { - Bangle.setLCDPower(true); - } + constructor(path, maps, interests, heights) { + this.path = path; + this.default_options = true; // do we still have default options ? + this.active = false; // should we have screen on + this.last_activity = getTime(); + this.maps = maps; + this.interests = interests; + this.heights = heights; + 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.position = null; // where we are + this.adjusted_cos_direction = 1; // cos of where we look at + this.adjusted_sin_direction = 0; // sin of where we look at + this.current_segment = null; // which segment is closest + this.reaching = null; // which waypoint are we reaching ? + this.distance_to_next_point = null; // how far are we from next point ? + this.projected_point = null; + + if (this.path !== null) { + let r = [0]; + // let's do a reversed prefix computations on all distances: + // loop on all segments in reversed order + let previous_point = null; + for (let i = this.path.len - 1; i >= 0; i--) { + let point = this.path.point(i); + if (previous_point !== null) { + r.unshift(r[0] + point.distance(previous_point)); } + previous_point = point; + } + this.remaining_distances = r; // how much distance remains at start of each segment } - check_activity() { - if (!this.active || !powersaving) { - return; - } - if (getTime() - this.last_activity > 30) { - this.active = false; - Bangle.setLCDBrightness(0); - if (settings.power_lcd_off) { - Bangle.setLCDPower(false); - } - } + this.starting_time = null; // time we start + this.advanced_distance = 0.0; + this.gps_coordinates_counter = 0; // how many coordinates did we receive + this.old_points = []; // record previous points but only when enough distance between them + this.old_times = []; // the corresponding times + } + activate() { + this.last_activity = getTime(); + if (this.active) { + return; + } else { + this.active = true; + Bangle.setLCDBrightness(settings.brightness); + Bangle.setLocked(false); + if (settings.power_lcd_off) { + Bangle.setLCDPower(true); + } } - invalidate_caches() { - for (let i = 0; i < this.maps.length; i++) { - this.maps[i].invalidate_caches(); - } - if (this.interests !== null) { - this.interests.invalidate_caches(); - } + } + check_activity() { + if (!this.active || !powersaving) { + return; } - new_position_reached(position) { - // we try to figure out direction by looking at previous points - // instead of the gps course which is not very nice. - - let now = getTime(); - - if (this.old_points.length == 0) { - this.gps_coordinates_counter += 1; - this.old_points.push(position); - this.old_times.push(now); - return null; - } else { - let previous_point = this.old_points[this.old_points.length - 1]; - let distance_to_previous = previous_point.distance(position); - // gps signal is noisy but rarely above 5 meters - if (distance_to_previous < 5) { - // update instant speed and return - let oldest_point = this.old_points[0]; - let distance_to_oldest = oldest_point.distance(position); - this.instant_speed = distance_to_oldest / (now - this.old_times[0]); - return null; - } - } - this.gps_coordinates_counter += 1; - this.old_points.push(position); - this.old_times.push(now); - + if (getTime() - this.last_activity > 30) { + this.active = false; + Bangle.setLCDBrightness(0); + if (settings.power_lcd_off) { + Bangle.setLCDPower(false); + } + } + } + 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) { + // we try to figure out direction by looking at previous points + // instead of the gps course which is not very nice. + + let now = getTime(); + + if (this.old_points.length == 0) { + this.gps_coordinates_counter += 1; + this.old_points.push(position); + this.old_times.push(now); + return null; + } else { + let previous_point = this.old_points[this.old_points.length - 1]; + let distance_to_previous = previous_point.distance(position); + // gps signal is noisy but rarely above 5 meters + if (distance_to_previous < 5) { + // update instant speed and return let oldest_point = this.old_points[0]; let distance_to_oldest = oldest_point.distance(position); - - // every 3 points we count the distance - if (this.gps_coordinates_counter % 3 == 0) { - if (distance_to_oldest < 150.0) { - // to avoid gps glitches - this.advanced_distance += distance_to_oldest; - } - } - this.instant_speed = distance_to_oldest / (now - this.old_times[0]); + return null; + } + } + this.gps_coordinates_counter += 1; + this.old_points.push(position); + this.old_times.push(now); + + let oldest_point = this.old_points[0]; + let distance_to_oldest = oldest_point.distance(position); + + // every 3 points we count the distance + if (this.gps_coordinates_counter % 3 == 0) { + if (distance_to_oldest < 150.0) { + // to avoid gps glitches + this.advanced_distance += distance_to_oldest; + } + } - if (this.old_points.length == 4) { - this.old_points.shift(); - this.old_times.shift(); - } - // let's just take angle of segment between newest point and a point a bit before - let previous_index = this.old_points.length - 3; - if (previous_index < 0) { - previous_index = 0; - } - let diff = position.minus(this.old_points[previous_index]); - let angle = Math.atan2(diff.lat, diff.lon); - return angle; - } - update_position(new_position) { - let direction = this.new_position_reached(new_position); - if (direction === null) { - if (this.old_points.length > 1) { - this.display(); // re-display because speed has changed - } - return; - } - if (in_menu) { - return; - } - if (this.instant_speed * 3.6 < 13) { - this.activate(); // if we go too slow turn on, we might be looking for the direction to follow - if (!this.default_options) { - this.default_options = true; - - Bangle.setOptions({ - lockTimeout: 10000, - backlightTimeout: 10000, - wakeOnTwist: true, - powerSave: true, - }); - } - } else { - if (this.default_options) { - this.default_options = false; - - Bangle.setOptions({ - lockTimeout: 0, - backlightTimeout: 0, - lcdPowerTimeout: 0, - hrmSportMode: 2, - wakeOnTwist: false, // if true watch will never sleep due to speed and road bumps. tried several tresholds. - wakeOnFaceUp: false, - wakeOnTouch: true, - powerSave: false, - }); - Bangle.setPollInterval(2000); // disable accelerometer as much as we can (a value of 4000 seem to cause hard reboot crashes (segfaults ?) so keep 2000) - } - - } - this.check_activity(); // if we don't move or are in menu we should stay on - - this.adjusted_cos_direction = Math.cos(-direction - Math.PI / 2.0); - this.adjusted_sin_direction = Math.sin(-direction - Math.PI / 2.0); - this.angle = direction; - let cos_direction = Math.cos(direction); - let sin_direction = Math.sin(direction); - this.position = new_position; - - // we will display position of where we'll be at in a few seconds - // and not where we currently are. - // this is because the display has more than 1sec duration. - this.displayed_position = new Point( - new_position.lon + cos_direction * this.instant_speed * 0.00001, - new_position.lat + sin_direction * this.instant_speed * 0.00001 - ); - - if (this.path !== null) { - // detect segment we are on now - let res = this.path.nearest_segment( - this.displayed_position, - Math.max(0, this.current_segment - 1), - Math.min(this.current_segment + 2, this.path.len - 1), - cos_direction, - sin_direction - ); - let orientation = res[0]; - let next_segment = res[1]; - - if (this.is_lost(next_segment)) { - // start_profiling(); - // it did not work, try anywhere - res = this.path.nearest_segment( - this.displayed_position, - 0, - this.path.len - 1, - cos_direction, - sin_direction - ); - orientation = res[0]; - next_segment = res[1]; - // end_profiling("repositioning"); - } - // now check if we strayed away from path or back to it - let lost = this.is_lost(next_segment); - if (this.on_path == lost) { - this.activate(); - // if status changes - if (lost) { - Bangle.buzz(); // we lost path - setTimeout(() => Bangle.buzz(), 500); - setTimeout(() => Bangle.buzz(), 1000); - setTimeout(() => Bangle.buzz(), 1500); - } - this.on_path = !lost; - } + this.instant_speed = distance_to_oldest / (now - this.old_times[0]); - this.current_segment = next_segment; + if (this.old_points.length == 4) { + this.old_points.shift(); + this.old_times.shift(); + } + // let's just take angle of segment between newest point and a point a bit before + let previous_index = this.old_points.length - 3; + if (previous_index < 0) { + previous_index = 0; + } + let diff = position.minus(this.old_points[previous_index]); + let angle = Math.atan2(diff.lat, diff.lon); + return angle; + } + update_position(new_position) { + let direction = this.new_position_reached(new_position); + if (direction === null) { + if (this.old_points.length > 1) { + this.display(); // re-display because speed has changed + } + return; + } + if (in_menu) { + return; + } + if (this.instant_speed * 3.6 < 13) { + this.activate(); // if we go too slow turn on, we might be looking for the direction to follow + if (!this.default_options) { + this.default_options = true; + + Bangle.setOptions({ + lockTimeout: 10000, + backlightTimeout: 10000, + wakeOnTwist: true, + powerSave: true, + }); + } + } else { + if (this.default_options) { + this.default_options = false; + + Bangle.setOptions({ + lockTimeout: 0, + backlightTimeout: 0, + lcdPowerTimeout: 0, + hrmSportMode: 2, + wakeOnTwist: false, // if true watch will never sleep due to speed and road bumps. tried several tresholds. + wakeOnFaceUp: false, + wakeOnTouch: true, + powerSave: false, + }); + Bangle.setPollInterval(2000); // disable accelerometer as much as we can (a value of 4000 seem to cause hard reboot crashes (segfaults ?) so keep 2000) + } + } + this.check_activity(); // if we don't move or are in menu we should stay on + + this.adjusted_cos_direction = Math.cos(-direction - Math.PI / 2.0); + this.adjusted_sin_direction = Math.sin(-direction - Math.PI / 2.0); + this.angle = direction; + let cos_direction = Math.cos(direction); + let sin_direction = Math.sin(direction); + this.position = new_position; + + // we will display position of where we'll be at in a few seconds + // and not where we currently are. + // this is because the display has more than 1sec duration. + this.displayed_position = new Point( + new_position.lon + cos_direction * this.instant_speed * 0.00001, + new_position.lat + sin_direction * this.instant_speed * 0.00001 + ); - // check if we are nearing the next point on our path and alert the user - let next_point = this.current_segment + (1 - orientation); - this.distance_to_next_point = Math.ceil( - this.position.distance(this.path.point(next_point)) - ); + if (this.path !== null) { + // detect segment we are on now + let res = this.path.nearest_segment( + this.displayed_position, + Math.max(0, this.current_segment - 1), + Math.min(this.current_segment + 2, this.path.len - 1), + cos_direction, + sin_direction + ); + let orientation = res[0]; + let next_segment = res[1]; - // disable gps when far from next point and locked - // if (Bangle.isLocked() && !settings.keep_gps_alive) { - // let time_to_next_point = - // (this.distance_to_next_point * 3.6) / settings.max_speed; - // if (time_to_next_point > 60) { - // Bangle.setGPSPower(false, "gipy"); - // setTimeout(function () { - // Bangle.setGPSPower(true, "gipy"); - // }, time_to_next_point); - // } - // } - if (this.reaching != next_point && this.distance_to_next_point <= 100) { - this.activate(); - this.reaching = next_point; - let reaching_waypoint = this.path.is_waypoint(next_point); - if (reaching_waypoint) { - if (settings.buzz_on_turns) { - Bangle.buzz(); - setTimeout(() => Bangle.buzz(), 500); - setTimeout(() => Bangle.buzz(), 1000); - setTimeout(() => Bangle.buzz(), 1500); - } - } - } + if (this.is_lost(next_segment)) { + // start_profiling(); + // it did not work, try anywhere + res = this.path.nearest_segment( + this.displayed_position, + 0, + this.path.len - 1, + cos_direction, + sin_direction + ); + orientation = res[0]; + next_segment = res[1]; + // end_profiling("repositioning"); + } + // now check if we strayed away from path or back to it + let lost = this.is_lost(next_segment); + if (this.on_path == lost) { + this.activate(); + // if status changes + if (lost) { + Bangle.buzz(); // we lost path + setTimeout(() => Bangle.buzz(), 500); + setTimeout(() => Bangle.buzz(), 1000); + setTimeout(() => Bangle.buzz(), 1500); } - - // abort most frames if inactive - if (!this.active && this.gps_coordinates_counter % 5 != 0) { - return; + this.on_path = !lost; + } + + this.current_segment = next_segment; + + // check if we are nearing the next point on our path and alert the user + let next_point = this.current_segment + (1 - orientation); + this.distance_to_next_point = Math.ceil( + this.position.distance(this.path.point(next_point)) + ); + + // disable gps when far from next point and locked + // if (Bangle.isLocked() && !settings.keep_gps_alive) { + // let time_to_next_point = + // (this.distance_to_next_point * 3.6) / settings.max_speed; + // if (time_to_next_point > 60) { + // Bangle.setGPSPower(false, "gipy"); + // setTimeout(function () { + // Bangle.setGPSPower(true, "gipy"); + // }, time_to_next_point); + // } + // } + if (this.reaching != next_point && this.distance_to_next_point <= 100) { + this.activate(); + this.reaching = next_point; + let reaching_waypoint = this.path.is_waypoint(next_point); + if (reaching_waypoint) { + if (settings.buzz_on_turns) { + Bangle.buzz(); + setTimeout(() => Bangle.buzz(), 500); + setTimeout(() => Bangle.buzz(), 1000); + setTimeout(() => Bangle.buzz(), 1500); + } } + } + } - // re-display - this.display(); + // abort most frames if inactive + if (!this.active && this.gps_coordinates_counter % 5 != 0) { + return; } - display_direction() { - //TODO: go towards point on path at 20 meter - if (this.current_segment === null) { - return; - } - let next_point = this.path.point(this.current_segment + (1 - go_backwards)); - let distance_to_next_point = Math.ceil( - this.projected_point.distance(next_point) - ); - let towards; - if (distance_to_next_point < 20) { - towards = this.path.point(this.current_segment + 2 * (1 - go_backwards)); - } else { - towards = next_point; - } - let diff = towards.minus(this.projected_point); - direction = Math.atan2(diff.lat, diff.lon); + // re-display + this.display(); + } + display_direction() { + //TODO: go towards point on path at 20 meter + if (this.current_segment === null) { + return; + } + let next_point = this.path.point(this.current_segment + (1 - go_backwards)); - 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 distance_to_next_point = Math.ceil( + this.projected_point.distance(next_point) + ); + let towards; + if (distance_to_next_point < 20) { + towards = this.path.point(this.current_segment + 2 * (1 - go_backwards)); + } else { + towards = next_point; + } + let diff = towards.minus(this.projected_point); + direction = Math.atan2(diff.lat, diff.lon); - let scale; - if (zoomed) { - scale = this.scale_factor; - } else { - scale = this.scale_factor / 2; - } + 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); - c = this.projected_point.coordinates( - this.displayed_position, - this.adjusted_cos_direction, - this.adjusted_sin_direction, - scale - ); + let scale; + if (zoomed) { + scale = this.scale_factor; + } else { + scale = this.scale_factor / 2; + } - let cos1 = Math.cos(full_angle + 0.6 + Math.PI / 2); - let cos2 = Math.cos(full_angle + Math.PI / 2); - let cos3 = Math.cos(full_angle - 0.6 + Math.PI / 2); - let sin1 = Math.sin(-full_angle - 0.6 - Math.PI / 2); - let sin2 = Math.sin(-full_angle - Math.PI / 2); - let sin3 = Math.sin(-full_angle + 0.6 - Math.PI / 2); - g.setColor(0, 1, 0).fillPoly([ - c[0] + cos1 * 15, - c[1] + sin1 * 15, - c[0] + cos2 * 20, - c[1] + sin2 * 20, - c[0] + cos3 * 15, - c[1] + sin3 * 15, - c[0] + cos3 * 10, - c[1] + sin3 * 10, - c[0] + cos2 * 15, - c[1] + sin2 * 15, - c[0] + cos1 * 10, - c[1] + sin1 * 10, - ]); - } - remaining_distance() { - let remaining_in_correct_orientation = - this.remaining_distances[this.current_segment + 1] + - this.position.distance(this.path.point(this.current_segment + 1)); + c = this.projected_point.coordinates( + this.displayed_position, + this.adjusted_cos_direction, + this.adjusted_sin_direction, + scale + ); + let cos1 = Math.cos(full_angle + 0.6 + Math.PI / 2); + let cos2 = Math.cos(full_angle + Math.PI / 2); + let cos3 = Math.cos(full_angle - 0.6 + Math.PI / 2); + let sin1 = Math.sin(-full_angle - 0.6 - Math.PI / 2); + let sin2 = Math.sin(-full_angle - Math.PI / 2); + let sin3 = Math.sin(-full_angle + 0.6 - Math.PI / 2); + g.setColor(0, 1, 0).fillPoly([ + c[0] + cos1 * 15, + c[1] + sin1 * 15, + c[0] + cos2 * 20, + c[1] + sin2 * 20, + c[0] + cos3 * 15, + c[1] + sin3 * 15, + c[0] + cos3 * 10, + c[1] + sin3 * 10, + c[0] + cos2 * 15, + c[1] + sin2 * 15, + c[0] + cos1 * 10, + c[1] + sin1 * 10, + ]); + } + remaining_distance() { + let remaining_in_correct_orientation = + this.remaining_distances[this.current_segment + 1] + + this.position.distance(this.path.point(this.current_segment + 1)); + + if (go_backwards) { + return this.remaining_distances[0] - remaining_in_correct_orientation; + } else { + return remaining_in_correct_orientation; + } + } + // check if we are lost (too far from segment we think we are on) + // if we are adjust scale so that path will still be displayed. + // we do the scale adjustment here to avoid recomputations later on. + is_lost(segment) { + let projection = this.displayed_position.closest_segment_point( + this.path.point(segment), + this.path.point(segment + 1) + ); + this.projected_point = projection; // save this info for display + let distance_to_projection = this.displayed_position.distance(projection); + if (distance_to_projection > settings.lost_distance) { + return true; + } else { + return false; + } + } + display() { + if (displaying || in_menu) { + return; // don't draw on drawings + } + displaying = true; + g.clear(); + if (this.screen == MAP) { + this.display_map(); + } else { + let current_position = 0; + if (this.current_segment !== null) { + current_position = + this.remaining_distances[0] - this.remaining_distance(); + } + if (this.screen == HEIGHTS_FULL) { + this.display_heights(0, current_position, this.remaining_distances[0]); + } else { + // only display 2500m + let start; if (go_backwards) { - return this.remaining_distances[0] - remaining_in_correct_orientation; + start = Math.max(0, current_position - 2000); } else { - return remaining_in_correct_orientation; + start = Math.max(0, current_position - 500); } + let length = Math.min(2500, this.remaining_distances[0] - start); + this.display_heights(start, current_position, length); + } } - // check if we are lost (too far from segment we think we are on) - // if we are adjust scale so that path will still be displayed. - // we do the scale adjustment here to avoid recomputations later on. - is_lost(segment) { - let projection = this.displayed_position.closest_segment_point( - this.path.point(segment), - this.path.point(segment + 1) - ); - this.projected_point = projection; // save this info for display - let distance_to_projection = this.displayed_position.distance(projection); - if (distance_to_projection > settings.lost_distance) { - return true; - } else { - return false; - } + Bangle.drawWidgets(); + displaying = false; + } + display_heights(display_start, current_position, displayed_length) { + let path_length = this.remaining_distances[0]; + let widgets_height = 24; + let graph_width = g.getWidth(); + let graph_height = g.getHeight() - 20 - widgets_height; + + let distance_per_pixel = displayed_length / graph_width; + + let start_point_index = 0; + let end_point_index = this.remaining_distances.length - 1; + for (let i = 0; i < this.remaining_distances.length; i++) { + let point_distance = path_length - this.remaining_distances[i]; + if (point_distance <= display_start) { + start_point_index = i; + } + if (point_distance >= display_start + displayed_length) { + end_point_index = i; + break; + } + } + let max_height = Number.NEGATIVE_INFINITY; + let min_height = Number.POSITIVE_INFINITY; + for (let i = start_point_index; i <= end_point_index; i++) { + let height = this.heights[i]; + max_height = Math.max(max_height, height); + min_height = Math.min(min_height, height); } - display() { - if (displaying || in_menu) { - return; // don't draw on drawings - } - displaying = true; - g.clear(); - 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 + let displayed_height = max_height - min_height; + let height_per_pixel = displayed_height / graph_height; + // g.setColor(0, 0, 0).drawRect(0, widgets_height, graph_width, graph_height + widgets_height); + + let previous_x = null; + let previous_y = null; + let previous_height = null; + let previous_distance = null; + let current_x; + let current_y; + for (let i = start_point_index; i < end_point_index; i++) { + let point_distance = path_length - this.remaining_distances[i]; + let height = this.heights[i]; + let x = Math.round((point_distance - display_start) / distance_per_pixel); + if (go_backwards) { + x = graph_width - x; + } + let y = + widgets_height + + graph_height - + Math.round((height - min_height) / height_per_pixel); + if (x != previous_x) { + if (previous_x !== null) { + let steepness = + (height - previous_height) / (point_distance - previous_distance); + if (go_backwards) { + steepness *= -1; + } + let color; + if (steepness > 0.15) { + color = "#ff0000"; + } else if (steepness > 0.8) { + color = "#aa0000"; + } else if (steepness > 0.03) { + color = "#ffff00"; + } else if (steepness > -0.03) { + color = "#00ff00"; + } else if (steepness > -0.08) { + color = "#00aa44"; + } else if (steepness > -0.015) { + color = "#0044aa"; + } else { + color = "#0000ff"; + } + g.setColor(color); + g.fillPoly([ + previous_x, + previous_y, + x, + y, + x, + widgets_height + graph_height, + previous_x, + widgets_height + graph_height, + ]); + if ( + current_position >= previous_distance && + current_position < point_distance + ) { + let current_height = + previous_height + + ((current_position - previous_distance) / + (point_distance - previous_distance)) * + (height - previous_height); + current_x = Math.round( + (current_position - display_start) / distance_per_pixel ); + if (go_backwards) { + current_x = graph_width - current_x; + } + current_y = + widgets_height + + graph_height - + Math.round((current_height - min_height) / height_per_pixel); + } } - // 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(); - Bangle.drawWidgets(); - displaying = false; + previous_distance = point_distance; + previous_height = height; + previous_x = x; + previous_y = y; + } } - display_stats() { - let now = new Date(); - let minutes = now.getMinutes().toString(); - if (minutes.length < 2) { - minutes = "0" + minutes; - } - let hours = now.getHours().toString(); - - // display the clock - g.setFont("6x8:2") - .setFontAlign(-1, -1, 0) - .setColor(g.theme.fg) - .drawString(hours + ":" + minutes, 0, 24); - - let approximate_speed; - // display speed (avg and instant) - if (this.old_times.length > 0) { - let point_time = this.old_times[this.old_times.length - 1]; - let done_in = point_time - this.starting_time; - approximate_speed = Math.round( - (this.advanced_distance * 3.6) / done_in - ); - let approximate_instant_speed = Math.round(this.instant_speed * 3.6); - g.setFont("6x8:2") - .setFontAlign(-1, -1, 0) - .drawString( - "" + - approximate_speed + - "km/h", - 0, - g.getHeight() - 15 - ); - - g.setFont("6x8:3") - .setFontAlign(1, -1, 0) - .drawString( - "" + approximate_instant_speed, - g.getWidth(), - g.getHeight() - 22 - ); - } - - if (this.path === null || this.position === null) { - return; - } - - let remaining_distance = this.remaining_distance(); - let rounded_distance = Math.round(remaining_distance / 100) / 10; - let total = Math.round(this.remaining_distances[0] / 100) / 10; - // now, distance to next point in meters - g.setFont("6x8:2") - .setFontAlign(-1, -1, 0) - .setColor(g.theme.fg) - .drawString( - "" + this.distance_to_next_point + "m", - 0, - g.getHeight() - 49 - ); + g.setColor(0, 0, 0); + g.fillCircle(current_x, current_y, 5); + + // display min dist/max dist and min height/max height + g.setColor(g.theme.fg); + g.setFont("6x8:2"); + g.setFontAlign(-1, 1, 0).drawString( + Math.ceil(display_start / 100) / 10, + 0, + g.getHeight() + ); - let forward_eta = compute_eta( - now.getHours(), - now.getMinutes(), - approximate_speed, - remaining_distance / 1000 - ); + g.setFontAlign(1, 1, 0).drawString( + Math.ceil((display_start + displayed_length) / 100) / 10, + g.getWidth(), + g.getHeight() + ); - // now display ETA - g.setFont("6x8:2") - .setFontAlign(-1, -1, 0) - .setColor(g.theme.fg) - .drawString(forward_eta, 0, 42); - - // display distance on path - g.setFont("6x8:2").drawString( - "" + rounded_distance + "/" + total, - 0, - g.getHeight() - 32 - ); + g.setFontAlign(1, 1, 0).drawString( + min_height, + g.getWidth(), + widgets_height + graph_height + ); + g.setFontAlign(1, -1, 0).drawString( + max_height, + g.getWidth(), + widgets_height + ); + } + display_map() { + let scale_factor = this.scale_factor; + if (!zoomed) { + scale_factor /= 2; + } - // display various indicators - if (this.distance_to_next_point <= 100) { - if (this.path.is_waypoint(this.reaching)) { - g.setColor(0.0, 1.0, 0.0) - .setFont("6x15") - .drawString("turn", g.getWidth() - 50, 30); - } - } - if (!this.on_path) { - g.setColor(1.0, 0.0, 0.0) - .setFont("6x15") - .drawString("lost", g.getWidth() - 55, 35); - } + // 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(); } - display_path() { - // don't display all segments, only those neighbouring current segment - // this is most likely to be the correct display - // while lowering the cost a lot - // - // note that all code is inlined here to speed things up - let cos = this.adjusted_cos_direction; - let sin = this.adjusted_sin_direction; - let displayed_x = this.displayed_position.lon; - let displayed_y = this.displayed_position.lat; - let width = g.getWidth(); - let height = g.getHeight(); - let half_width = width / 2; - let half_height = height / 2 + Y_OFFSET; - let scale_factor = this.scale_factor; - if (!zoomed) { - scale_factor /= 2; - } - if (this.path !== null) { - // compute coordinate for projection on path - let tx = (this.projected_point.lon - displayed_x) * scale_factor; - let ty = (this.projected_point.lat - displayed_y) * scale_factor; - let rotated_x = tx * cos - ty * sin; - let rotated_y = tx * sin + ty * cos; - let projected_x = half_width - Math.round(rotated_x); // x is inverted - let projected_y = half_height + Math.round(rotated_y); - - // display direction to next point if lost - if (!this.on_path) { - let next_point = this.path.point(this.current_segment + 1); - let previous_point = this.path.point(this.current_segment); - let nearest_point; - if ( - previous_point.fake_distance(this.position) < - next_point.fake_distance(this.position) - ) { - nearest_point = previous_point; - } else { - nearest_point = next_point; - } - let tx = (nearest_point.lon - displayed_x) * scale_factor; - let ty = (nearest_point.lat - displayed_y) * scale_factor; - let rotated_x = tx * cos - ty * sin; - let rotated_y = tx * sin + ty * cos; - let x = half_width - Math.round(rotated_x); // x is inverted - let y = half_height + Math.round(rotated_y); - g.setColor(1, 0, 1).drawLine(half_width, half_height, x, y); - } + this.display_direction(); + this.display_stats(); + } + display_stats() { + let now = new Date(); + let minutes = now.getMinutes().toString(); + if (minutes.length < 2) { + minutes = "0" + minutes; + } + let hours = now.getHours().toString(); - // display current-segment's projection - g.setColor(0, 0, 0); - g.fillCircle(projected_x, projected_y, 4); - } + // display the clock + g.setFont("6x8:2") + .setFontAlign(-1, -1, 0) + .setColor(g.theme.fg) + .drawString(hours + ":" + minutes, 0, 24); + + let approximate_speed; + // display speed (avg and instant) + if (this.old_times.length > 0) { + let point_time = this.old_times[this.old_times.length - 1]; + let done_in = point_time - this.starting_time; + approximate_speed = Math.round((this.advanced_distance * 3.6) / done_in); + let approximate_instant_speed = Math.round(this.instant_speed * 3.6); + g.setFont("6x8:2") + .setFontAlign(-1, -1, 0) + .drawString("" + approximate_speed + "km/h", 0, g.getHeight() - 15); + + g.setFont("6x8:3") + .setFontAlign(1, -1, 0) + .drawString( + "" + approximate_instant_speed, + g.getWidth(), + g.getHeight() - 22 + ); + } - // now display ourselves - g.setColor(0, 0, 0); - g.fillCircle(half_width, half_height, 5); + if (this.path === null || this.position === null) { + return; } -} -function load_gps(filename) { - // let's display splash screen while loading file + let remaining_distance = this.remaining_distance(); + let rounded_distance = Math.round(remaining_distance / 100) / 10; + let total = Math.round(this.remaining_distances[0] / 100) / 10; + // now, distance to next point in meters + g.setFont("6x8:2") + .setFontAlign(-1, -1, 0) + .setColor(g.theme.fg) + .drawString( + "" + this.distance_to_next_point + "m", + 0, + g.getHeight() - 49 + ); + + let forward_eta = compute_eta( + now.getHours(), + now.getMinutes(), + approximate_speed, + remaining_distance / 1000 + ); - let splashscreen = require("heatshrink").decompress( - atob( - "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" - ) + // now display ETA + g.setFont("6x8:2") + .setFontAlign(-1, -1, 0) + .setColor(g.theme.fg) + .drawString(forward_eta, 0, 42); + + // display distance on path + g.setFont("6x8:2").drawString( + "" + rounded_distance + "/" + total, + 0, + g.getHeight() - 32 ); - g.clear(); + // display various indicators + if (this.distance_to_next_point <= 100) { + if (this.path.is_waypoint(this.reaching)) { + g.setColor(0.0, 1.0, 0.0) + .setFont("6x15") + .drawString("turn", g.getWidth() - 50, 30); + } + } + if (!this.on_path) { + g.setColor(1.0, 0.0, 0.0) + .setFont("6x15") + .drawString("lost", g.getWidth() - 55, 35); + } + } + display_path() { + // don't display all segments, only those neighbouring current segment + // this is most likely to be the correct display + // while lowering the cost a lot + // + // note that all code is inlined here to speed things up + let cos = this.adjusted_cos_direction; + let sin = this.adjusted_sin_direction; + let displayed_x = this.displayed_position.lon; + let displayed_y = this.displayed_position.lat; + let width = g.getWidth(); + let height = g.getHeight(); + let half_width = width / 2; + let half_height = height / 2 + Y_OFFSET; + let scale_factor = this.scale_factor; + if (!zoomed) { + scale_factor /= 2; + } - g.drawImage(splashscreen, 0, 0); - g.setFont("6x8:2") - .setFontAlign(-1, -1, 0) - .setColor(0xf800) - .drawString(filename, 0, g.getHeight() - 30); - g.flip(); - - let buffer = s.readArrayBuffer(filename); - let file_size = buffer.length; - let offset = 0; - - let path = null; - let heights = null; - let maps = []; - let interests = null; - while (offset < file_size) { - let block_type = Uint8Array(buffer, offset, 1)[0]; - offset += 1; - if (block_type == 0) { - // it's a map - console.log("loading map"); - let res = new Map(buffer, offset, filename); - let map = res[0]; - offset = res[1]; - maps.push(map); - } else if (block_type == 2) { - console.log("loading path"); - let res = new Path(buffer, offset); - path = res[0]; - offset = res[1]; - } else if (block_type == 3) { - console.log("loading interests"); - let res = new Interests(buffer, offset); - interests = res[0]; - offset = res[1]; - } else if (block_type == 4) { - console.log("loading heights"); - let heights_number = path.points.length / 2; - heights = Float64Array(buffer, offset, heights_number); - offset += 8 * heights_number; + if (this.path !== null) { + // compute coordinate for projection on path + let tx = (this.projected_point.lon - displayed_x) * scale_factor; + let ty = (this.projected_point.lat - displayed_y) * scale_factor; + let rotated_x = tx * cos - ty * sin; + let rotated_y = tx * sin + ty * cos; + let projected_x = half_width - Math.round(rotated_x); // x is inverted + let projected_y = half_height + Math.round(rotated_y); + + // display direction to next point if lost + if (!this.on_path) { + let next_point = this.path.point(this.current_segment + 1); + let previous_point = this.path.point(this.current_segment); + let nearest_point; + if ( + previous_point.fake_distance(this.position) < + next_point.fake_distance(this.position) + ) { + nearest_point = previous_point; } else { - console.log("todo : block type", block_type); + nearest_point = next_point; } + let tx = (nearest_point.lon - displayed_x) * scale_factor; + let ty = (nearest_point.lat - displayed_y) * scale_factor; + let rotated_x = tx * cos - ty * sin; + let rotated_y = tx * sin + ty * cos; + let x = half_width - Math.round(rotated_x); // x is inverted + let y = half_height + Math.round(rotated_y); + g.setColor(1, 0, 1).drawLine(half_width, half_height, x, y); + } + + // display current-segment's projection + g.setColor(0, 0, 0); + g.fillCircle(projected_x, projected_y, 4); } - // checksum file size - if (offset != file_size) { - console.log("invalid file size", file_size, "expected", offset); - let msg = "invalid file\nsize " + file_size + "\ninstead of" + offset; - E.showAlert(msg).then(function() { - E.showAlert(); - start_gipy(path, maps, interests, heights); - }); + // now display ourselves + g.setColor(0, 0, 0); + g.fillCircle(half_width, half_height, 5); + } +} + +function load_gps(filename) { + // let's display splash screen while loading file + + let splashscreen = require("heatshrink").decompress( + atob( + "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" + ) + ); + + g.clear(); + + g.drawImage(splashscreen, 0, 0); + g.setFont("6x8:2") + .setFontAlign(-1, -1, 0) + .setColor(0xf800) + .drawString(filename, 0, g.getHeight() - 30); + g.flip(); + + let buffer = s.readArrayBuffer(filename); + let file_size = buffer.length; + let offset = 0; + + let path = null; + let heights = null; + let maps = []; + let interests = null; + while (offset < file_size) { + let block_type = Uint8Array(buffer, offset, 1)[0]; + offset += 1; + if (block_type == 0) { + // it's a map + console.log("loading map"); + let res = new Map(buffer, offset, filename); + let map = res[0]; + offset = res[1]; + maps.push(map); + } else if (block_type == 2) { + console.log("loading path"); + let res = new Path(buffer, offset); + path = res[0]; + offset = res[1]; + } else if (block_type == 3) { + console.log("loading interests"); + let res = new Interests(buffer, offset); + interests = res[0]; + offset = res[1]; + } else if (block_type == 4) { + console.log("loading heights"); + let heights_number = path.points.length / 2; + heights = Int16Array(buffer, offset, heights_number); + offset += 2 * heights_number; } else { - start_gipy(path, maps, interests, heights); + console.log("todo : block type", block_type); } + } + + // checksum file size + if (offset != file_size) { + console.log("invalid file size", file_size, "expected", offset); + let msg = "invalid file\nsize " + file_size + "\ninstead of" + offset; + E.showAlert(msg).then(function () { + E.showAlert(); + start_gipy(path, maps, interests, heights); + }); + } else { + start_gipy(path, maps, interests, heights); + } } class Path { - constructor(buffer, offset) { - // let p = Uint16Array(buffer, offset, 1); - // console.log(p); - let points_number = Uint16Array(buffer, offset, 1)[0]; - offset += 2; - - // path points - this.points = Float64Array(buffer, offset, points_number * 2); - offset += 8 * points_number * 2; - - // path waypoints - let waypoints_len = Math.ceil(points_number / 8.0); - this.waypoints = Uint8Array(buffer, offset, waypoints_len); - offset += waypoints_len; - - return [this, offset]; - } - - is_waypoint(point_index) { - let i = Math.floor(point_index / 8); - let subindex = point_index % 8; - let r = this.waypoints[i] & (1 << subindex); - return r != 0; - } - - // return point at given index - point(index) { - let lon = this.points[2 * index]; - let lat = this.points[2 * index + 1]; - return new Point(lon, lat); - } - - // return index of segment which is nearest from point. - // we need a direction because we need there is an ambiguity - // for overlapping segments which are taken once to go and once to come back. - // (in the other direction). - nearest_segment(point, start, end, cos_direction, sin_direction) { - // we are going to compute two min distances, one for each direction. - let indices = [0, 0]; - let mins = [Number.MAX_VALUE, Number.MAX_VALUE]; - - let p1 = new Point(this.points[2 * start], this.points[2 * start + 1]); - for (let i = start + 1; i < end + 1; i++) { - let p2 = new Point(this.points[2 * i], this.points[2 * i + 1]); - - let closest_point = point.closest_segment_point(p1, p2); - let distance = point.length_squared(closest_point); - - let dot = - cos_direction * (p2.lon - p1.lon) + sin_direction * (p2.lat - p1.lat); - let orientation = +(dot < 0); // index 0 is good orientation - if (distance <= mins[orientation]) { - mins[orientation] = distance; - indices[orientation] = i - 1; - } - - p1 = p2; - } - - // by default correct orientation (0) wins - // but if other one is really closer, return other one - if (mins[1] < mins[0] / 100.0) { - return [1, indices[1]]; - } else { - return [0, indices[0]]; - } + constructor(buffer, offset) { + // let p = Uint16Array(buffer, offset, 1); + // console.log(p); + let points_number = Uint16Array(buffer, offset, 1)[0]; + offset += 2; + + // path points + this.points = Float64Array(buffer, offset, points_number * 2); + offset += 8 * points_number * 2; + + // path waypoints + let waypoints_len = Math.ceil(points_number / 8.0); + this.waypoints = Uint8Array(buffer, offset, waypoints_len); + offset += waypoints_len; + + return [this, offset]; + } + + is_waypoint(point_index) { + let i = Math.floor(point_index / 8); + let subindex = point_index % 8; + let r = this.waypoints[i] & (1 << subindex); + return r != 0; + } + + // return point at given index + point(index) { + let lon = this.points[2 * index]; + let lat = this.points[2 * index + 1]; + return new Point(lon, lat); + } + + // return index of segment which is nearest from point. + // we need a direction because we need there is an ambiguity + // for overlapping segments which are taken once to go and once to come back. + // (in the other direction). + nearest_segment(point, start, end, cos_direction, sin_direction) { + // we are going to compute two min distances, one for each direction. + let indices = [0, 0]; + let mins = [Number.MAX_VALUE, Number.MAX_VALUE]; + + let p1 = new Point(this.points[2 * start], this.points[2 * start + 1]); + for (let i = start + 1; i < end + 1; i++) { + let p2 = new Point(this.points[2 * i], this.points[2 * i + 1]); + + let closest_point = point.closest_segment_point(p1, p2); + let distance = point.length_squared(closest_point); + + let dot = + cos_direction * (p2.lon - p1.lon) + sin_direction * (p2.lat - p1.lat); + let orientation = +(dot < 0); // index 0 is good orientation + if (distance <= mins[orientation]) { + mins[orientation] = distance; + indices[orientation] = i - 1; + } + + p1 = p2; } - get len() { - return this.points.length / 2; + + // by default correct orientation (0) wins + // but if other one is really closer, return other one + if (mins[1] < mins[0] / 100.0) { + return [1, indices[1]]; + } else { + return [0, indices[0]]; } + } + get len() { + return this.points.length / 2; + } } class Point { - constructor(lon, lat) { - this.lon = lon; - this.lat = lat; - } - coordinates(current_position, cos_direction, sin_direction, scale_factor) { - let translated = this.minus(current_position).times(scale_factor); - let rotated_x = - translated.lon * cos_direction - translated.lat * sin_direction; - let rotated_y = - translated.lon * sin_direction + translated.lat * cos_direction; - return [ - g.getWidth() / 2 - Math.round(rotated_x), // x is inverted - g.getHeight() / 2 + Math.round(rotated_y) + Y_OFFSET, - ]; - } - minus(other_point) { - let xdiff = this.lon - other_point.lon; - let ydiff = this.lat - other_point.lat; - return new Point(xdiff, ydiff); - } - plus(other_point) { - return new Point(this.lon + other_point.lon, this.lat + other_point.lat); - } - length_squared(other_point) { - let londiff = this.lon - other_point.lon; - let latdiff = this.lat - other_point.lat; - return londiff * londiff + latdiff * latdiff; - } - times(scalar) { - return new Point(this.lon * scalar, this.lat * scalar); - } - // dot(other_point) { - // return this.lon * other_point.lon + this.lat * other_point.lat; - // } - distance(other_point) { - //see https://www.movable-type.co.uk/scripts/latlong.html - const R = 6371e3; // metres - const phi1 = (this.lat * Math.PI) / 180; - const phi2 = (other_point.lat * Math.PI) / 180; - const deltaphi = ((other_point.lat - this.lat) * Math.PI) / 180; - const deltalambda = ((other_point.lon - this.lon) * Math.PI) / 180; - - const a = - Math.sin(deltaphi / 2) * Math.sin(deltaphi / 2) + - Math.cos(phi1) * - Math.cos(phi2) * - Math.sin(deltalambda / 2) * - Math.sin(deltalambda / 2); - const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - - return R * c; // in meters - } - fake_distance(other_point) { - return Math.sqrt(this.length_squared(other_point)); - } - // return closest point from 'this' on [v,w] segment. - // since this function is critical we inline all code here. - closest_segment_point(v, w) { - // from : https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment - // Return minimum distance between line segment vw and point p - let segment_londiff = w.lon - v.lon; - let segment_latdiff = w.lat - v.lat; - let l2 = - segment_londiff * segment_londiff + segment_latdiff * segment_latdiff; // i.e. |w-v|^2 - avoid a sqrt - if (l2 == 0.0) { - return v; // v == w case - } - // Consider the line extending the segment, parameterized as v + t (w - v). - // We find projection of point p onto the line. - // It falls where t = [(p-v) . (w-v)] / |w-v|^2 - // We clamp t from [0,1] to handle points outside the segment vw. - - // let t = Math.max(0, Math.min(1, this.minus(v).dot(w.minus(v)) / l2)); //inlined below - let start_londiff = this.lon - v.lon; - let start_latdiff = this.lat - v.lat; - let t = - (start_londiff * segment_londiff + start_latdiff * segment_latdiff) / l2; - if (t < 0) { - t = 0; - } else { - if (t > 1) { - t = 1; - } - } - let lon = v.lon + segment_londiff * t; - let lat = v.lat + segment_latdiff * t; - return new Point(lon, lat); + constructor(lon, lat) { + this.lon = lon; + this.lat = lat; + } + coordinates(current_position, cos_direction, sin_direction, scale_factor) { + let translated = this.minus(current_position).times(scale_factor); + let rotated_x = + translated.lon * cos_direction - translated.lat * sin_direction; + let rotated_y = + translated.lon * sin_direction + translated.lat * cos_direction; + return [ + g.getWidth() / 2 - Math.round(rotated_x), // x is inverted + g.getHeight() / 2 + Math.round(rotated_y) + Y_OFFSET, + ]; + } + minus(other_point) { + let xdiff = this.lon - other_point.lon; + let ydiff = this.lat - other_point.lat; + return new Point(xdiff, ydiff); + } + plus(other_point) { + return new Point(this.lon + other_point.lon, this.lat + other_point.lat); + } + length_squared(other_point) { + let londiff = this.lon - other_point.lon; + let latdiff = this.lat - other_point.lat; + return londiff * londiff + latdiff * latdiff; + } + times(scalar) { + return new Point(this.lon * scalar, this.lat * scalar); + } + // dot(other_point) { + // return this.lon * other_point.lon + this.lat * other_point.lat; + // } + distance(other_point) { + //see https://www.movable-type.co.uk/scripts/latlong.html + const R = 6371e3; // metres + const phi1 = (this.lat * Math.PI) / 180; + const phi2 = (other_point.lat * Math.PI) / 180; + const deltaphi = ((other_point.lat - this.lat) * Math.PI) / 180; + const deltalambda = ((other_point.lon - this.lon) * Math.PI) / 180; + + const a = + Math.sin(deltaphi / 2) * Math.sin(deltaphi / 2) + + Math.cos(phi1) * + Math.cos(phi2) * + Math.sin(deltalambda / 2) * + Math.sin(deltalambda / 2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return R * c; // in meters + } + fake_distance(other_point) { + return Math.sqrt(this.length_squared(other_point)); + } + // return closest point from 'this' on [v,w] segment. + // since this function is critical we inline all code here. + closest_segment_point(v, w) { + // from : https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment + // Return minimum distance between line segment vw and point p + let segment_londiff = w.lon - v.lon; + let segment_latdiff = w.lat - v.lat; + let l2 = + segment_londiff * segment_londiff + segment_latdiff * segment_latdiff; // i.e. |w-v|^2 - avoid a sqrt + if (l2 == 0.0) { + return v; // v == w case + } + // Consider the line extending the segment, parameterized as v + t (w - v). + // We find projection of point p onto the line. + // It falls where t = [(p-v) . (w-v)] / |w-v|^2 + // We clamp t from [0,1] to handle points outside the segment vw. + + // let t = Math.max(0, Math.min(1, this.minus(v).dot(w.minus(v)) / l2)); //inlined below + let start_londiff = this.lon - v.lon; + let start_latdiff = this.lat - v.lat; + let t = + (start_londiff * segment_londiff + start_latdiff * segment_latdiff) / l2; + if (t < 0) { + t = 0; + } else { + if (t > 1) { + t = 1; + } } + let lon = v.lon + segment_londiff * t; + let lat = v.lat + segment_latdiff * t; + return new Point(lon, lat); + } } let fake_gps_point = 0; - function drawMenu() { - const menu = { - "": { - title: "choose trace" - }, - }; - var files = s.list(".gps"); - for (var i = 0; i < files.length; ++i) { - menu[files[i]] = start.bind(null, files[i]); - } - menu["Exit"] = function() { - load(); - }; - E.showMenu(menu); + const menu = { + "": { + title: "choose trace", + }, + }; + var files = s.list(".gps"); + for (var i = 0; i < files.length; ++i) { + menu[files[i]] = start.bind(null, files[i]); + } + menu["Exit"] = function () { + load(); + }; + E.showMenu(menu); } function start(fn) { - E.showMenu(); - console.log("loading", fn); + E.showMenu(); + console.log("loading", fn); - load_gps(fn); + load_gps(fn); } function start_gipy(path, maps, interests, heights) { - console.log("starting"); - - if (!simulated && settings.disable_bluetooth) { - NRF.sleep(); // disable bluetooth completely - } - - status = new Status(path, maps, interests, heights); - - setWatch( - function() { - status.activate(); - if (in_menu) { - return; - } - in_menu = true; - const menu = { - "": { - title: "choose action" - }, - "Go Backward": { - value: go_backwards, - format: (v) => (v ? "On" : "Off"), - onchange: (v) => { - go_backwards = v; - }, - }, - Zoom: { - value: zoomed, - format: (v) => (v ? "In" : "Out"), - onchange: (v) => { - status.invalidate_caches(); - zoomed = v; - }, - }, - /*LANG*/ - "powersaving": { - value: powersaving, - onchange: (v) => { - powersaving = v; - } - }, - "back to map": function() { - in_menu = false; - E.showMenu(); - g.clear(); - g.flip(); - if (status !== null) { - status.display(); - } - }, - }; - E.showMenu(menu); + console.log("starting"); + + if (!simulated && settings.disable_bluetooth) { + NRF.sleep(); // disable bluetooth completely + } + + status = new Status(path, maps, interests, heights); + + setWatch( + function () { + status.activate(); + if (in_menu) { + return; + } + in_menu = true; + const menu = { + "": { + title: "choose action", }, - BTN1, { - repeat: true - } + "Go Backward": { + value: go_backwards, + format: (v) => (v ? "On" : "Off"), + onchange: (v) => { + go_backwards = v; + }, + }, + Zoom: { + value: zoomed, + format: (v) => (v ? "In" : "Out"), + onchange: (v) => { + status.invalidate_caches(); + zoomed = v; + }, + }, + /*LANG*/ + powersaving: { + value: powersaving, + onchange: (v) => { + powersaving = v; + }, + }, + "back to map": function () { + in_menu = false; + E.showMenu(); + g.clear(); + g.flip(); + if (status !== null) { + status.display(); + } + }, + }; + E.showMenu(menu); + }, + BTN1, + { + repeat: true, + } + ); + + if (status.path !== null) { + let start = status.path.point(0); + status.displayed_position = start; + } else { + let first_map = maps[0]; + status.displayed_position = new Point( + first_map.start_coordinates[0] + + (first_map.side * first_map.grid_size[0]) / 2, + first_map.start_coordinates[1] + + (first_map.side * first_map.grid_size[1]) / 2 ); + } + status.display(); + Bangle.on("touch", () => { + status.activate(); + if (in_menu) { + return; + } + if (status.heights !== null) { + status.screen = (status.screen + 1) % 3; + status.display(); + } + }); - if (status.path !== null) { - let start = status.path.point(0); - status.displayed_position = start; - } else { - let first_map = maps[0]; - status.displayed_position = new Point( - first_map.start_coordinates[0] + - (first_map.side * first_map.grid_size[0]) / 2, - first_map.start_coordinates[1] + - (first_map.side * first_map.grid_size[1]) / 2); + Bangle.on("stroke", (o) => { + status.activate(); + if (in_menu) { + return; } + // we move display according to stroke + let first_x = o.xy[0]; + let first_y = o.xy[1]; + let last_x = o.xy[o.xy.length - 2]; + let last_y = o.xy[o.xy.length - 1]; + let xdiff = last_x - first_x; + let ydiff = last_y - first_y; + + let c = status.adjusted_cos_direction; + let s = status.adjusted_sin_direction; + let rotated_x = xdiff * c - ydiff * s; + let rotated_y = xdiff * s + ydiff * c; + status.displayed_position.lon += (1.3 * rotated_x) / status.scale_factor; + status.displayed_position.lat -= (1.3 * rotated_y) / status.scale_factor; status.display(); - - Bangle.on("stroke", (o) => { - status.activate(); - if (in_menu) { - return; + }); + + if (simulated) { + status.starting_time = getTime(); + // let's keep the screen on in simulations + Bangle.setLCDTimeout(0); + Bangle.setLCDPower(1); + Bangle.loadWidgets(); // i don't know why i cannot load them at start : they would display on splash screen + + function simulate_gps(status) { + if (status.path === null) { + let map = status.maps[0]; + let p1 = new Point(map.start_coordinates[0], map.start_coordinates[1]); + let p2 = new Point( + map.start_coordinates[0] + map.side * map.grid_size[0], + map.start_coordinates[1] + map.side * map.grid_size[1] + ); + let pos = p1.times(1 - fake_gps_point).plus(p2.times(fake_gps_point)); + if (fake_gps_point < 1) { + fake_gps_point += 0.05; } - // we move display according to stroke - let first_x = o.xy[0]; - let first_y = o.xy[1]; - let last_x = o.xy[o.xy.length - 2]; - let last_y = o.xy[o.xy.length - 1]; - let xdiff = last_x - first_x; - let ydiff = last_y - first_y; - - let c = status.adjusted_cos_direction; - let s = status.adjusted_sin_direction; - let rotated_x = xdiff * c - ydiff * s; - let rotated_y = xdiff * s + ydiff * c; - status.displayed_position.lon += 1.3 * rotated_x / status.scale_factor; - status.displayed_position.lat -= 1.3 * rotated_y / status.scale_factor; - status.display(); - }); - - if (simulated) { - status.starting_time = getTime(); - // let's keep the screen on in simulations - Bangle.setLCDTimeout(0); - Bangle.setLCDPower(1); - Bangle.loadWidgets(); // i don't know why i cannot load them at start : they would display on splash screen - - - function simulate_gps(status) { - if (status.path === null) { - let map = status.maps[0]; - let p1 = new Point(map.start_coordinates[0], map.start_coordinates[1]); - let p2 = new Point( - map.start_coordinates[0] + map.side * map.grid_size[0], - map.start_coordinates[1] + map.side * map.grid_size[1] - ); - let pos = p1.times(1 - fake_gps_point).plus(p2.times(fake_gps_point)); - if (fake_gps_point < 1) { - fake_gps_point += 0.05; - } - status.update_position(pos); - } else { - if (fake_gps_point > status.path.len - 1 || fake_gps_point < 0) { - return; - } - let point_index = Math.floor(fake_gps_point); - if (point_index >= status.path.len / 2 - 1) { - return; - } - let p1 = status.path.point(2 * point_index); // use these to approximately follow path - let p2 = status.path.point(2 * (point_index + 1)); - //let p1 = status.path.point(point_index); // use these to strictly follow path - //let p2 = status.path.point(point_index + 1); - - let alpha = fake_gps_point - point_index; - let pos = p1.times(1 - alpha).plus(p2.times(alpha)); - - if (go_backwards) { - fake_gps_point -= 0.05; // advance simulation - } else { - fake_gps_point += 0.05; // advance simulation - } - status.update_position(pos); - } + status.update_position(pos); + } else { + if (fake_gps_point > status.path.len - 1 || fake_gps_point < 0) { + return; + } + let point_index = Math.floor(fake_gps_point); + if (point_index >= status.path.len / 2 - 1) { + return; } + let p1 = status.path.point(2 * point_index); // use these to approximately follow path + let p2 = status.path.point(2 * (point_index + 1)); + //let p1 = status.path.point(point_index); // use these to strictly follow path + //let p2 = status.path.point(point_index + 1); - setInterval(simulate_gps, 500, status); - } else { - status.activate(); - - let frame = 0; - let set_coordinates = function(data) { - frame += 1; - // 0,0 coordinates are considered invalid since we sometimes receive them out of nowhere - let valid_coordinates = !isNaN(data.lat) && - !isNaN(data.lon) && - (data.lat != 0.0 || data.lon != 0.0); - if (valid_coordinates) { - if (status.starting_time === null) { - status.starting_time = getTime(); - Bangle.loadWidgets(); // load them even in simulation to eat mem - } - status.update_position(new Point(data.lon, data.lat)); - } - let gps_status_color; - if (frame % 2 == 0 || valid_coordinates) { - gps_status_color = g.theme.bg; - } else { - gps_status_color = g.theme.fg; - } - if (!in_menu) { - g.setColor(gps_status_color) - .setFont("6x8:2") - .drawString("gps", g.getWidth() - 40, 30); - } - }; + let alpha = fake_gps_point - point_index; + let pos = p1.times(1 - alpha).plus(p2.times(alpha)); - Bangle.setGPSPower(true, "gipy"); - Bangle.on("GPS", set_coordinates); + if (go_backwards) { + fake_gps_point -= 0.2; // advance simulation + } else { + fake_gps_point += 0.2; // advance simulation + } + status.update_position(pos); + } } + + setInterval(simulate_gps, 500, status); + } else { + status.activate(); + + let frame = 0; + let set_coordinates = function (data) { + frame += 1; + // 0,0 coordinates are considered invalid since we sometimes receive them out of nowhere + let valid_coordinates = + !isNaN(data.lat) && + !isNaN(data.lon) && + (data.lat != 0.0 || data.lon != 0.0); + if (valid_coordinates) { + if (status.starting_time === null) { + status.starting_time = getTime(); + Bangle.loadWidgets(); // load them even in simulation to eat mem + } + status.update_position(new Point(data.lon, data.lat)); + } + let gps_status_color; + if (frame % 2 == 0 || valid_coordinates) { + gps_status_color = g.theme.bg; + } else { + gps_status_color = g.theme.fg; + } + if (!in_menu) { + g.setColor(gps_status_color) + .setFont("6x8:2") + .drawString("gps", g.getWidth() - 40, 30); + } + }; + + Bangle.setGPSPower(true, "gipy"); + Bangle.on("GPS", set_coordinates); + } } let files = s.list(".gps"); if (files.length <= 1) { - if (files.length == 0) { - load(); - } else { - start(files[0]); - } + if (files.length == 0) { + load(); + } else { + start(files[0]); + } } else { - drawMenu(); -} \ No newline at end of file + drawMenu(); +} diff --git a/apps/gipy/pkg/gps.d.ts b/apps/gipy/pkg/gps.d.ts index c881052f4f..3f1c8f372a 100644 --- a/apps/gipy/pkg/gps.d.ts +++ b/apps/gipy/pkg/gps.d.ts @@ -12,6 +12,11 @@ export function get_gps_map_svg(gps: Gps): string; export function get_polygon(gps: Gps): Float64Array; /** * @param {Gps} gps +* @returns {boolean} +*/ +export function has_heights(gps: Gps): boolean; +/** +* @param {Gps} gps * @returns {Float64Array} */ export function get_polyline(gps: Gps): Float64Array; @@ -51,46 +56,3 @@ export function gps_from_area(xmin: number, ymin: number, xmax: number, ymax: nu export class Gps { free(): void; } - -export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; - -export interface InitOutput { - readonly memory: WebAssembly.Memory; - readonly __wbg_gps_free: (a: number) => void; - readonly get_gps_map_svg: (a: number, b: number) => void; - readonly get_polygon: (a: number, b: number) => void; - readonly get_polyline: (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 load_gps_from_string: (a: number, b: number) => number; - readonly gps_from_area: (a: number, b: number, c: number, d: number) => number; - readonly __wbindgen_malloc: (a: number) => number; - readonly __wbindgen_realloc: (a: number, b: number, c: number) => number; - readonly __wbindgen_export_2: WebAssembly.Table; - readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__heb2f4d39a212d7d1: (a: number, b: number, c: number) => void; - readonly __wbindgen_add_to_stack_pointer: (a: number) => number; - readonly __wbindgen_free: (a: number, b: number) => void; - readonly __wbindgen_exn_store: (a: number) => void; - readonly wasm_bindgen__convert__closures__invoke2_mut__h362f82c7669db137: (a: number, b: number, c: number, d: number) => void; -} - -export type SyncInitInput = BufferSource | WebAssembly.Module; -/** -* Instantiates the given `module`, which can either be bytes or -* a precompiled `WebAssembly.Module`. -* -* @param {SyncInitInput} module -* -* @returns {InitOutput} -*/ -export function initSync(module: SyncInitInput): InitOutput; - -/** -* If `module_or_path` is {RequestInfo} or {URL}, makes a request and -* for everything else, calls `WebAssembly.instantiate` directly. -* -* @param {InitInput | Promise} module_or_path -* -* @returns {Promise} -*/ -export default function init (module_or_path?: InitInput | Promise): Promise; diff --git a/apps/gipy/pkg/gps.js b/apps/gipy/pkg/gps.js index 39c2a68045..5c9bfc9bdd 100644 --- a/apps/gipy/pkg/gps.js +++ b/apps/gipy/pkg/gps.js @@ -1,733 +1,2 @@ - -let wasm; - -const heap = new Array(32).fill(undefined); - -heap.push(undefined, null, true, false); - -function getObject(idx) { return heap[idx]; } - -let WASM_VECTOR_LEN = 0; - -let cachedUint8Memory0 = new Uint8Array(); - -function getUint8Memory0() { - if (cachedUint8Memory0.byteLength === 0) { - cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); - } - return cachedUint8Memory0; -} - -const cachedTextEncoder = new TextEncoder('utf-8'); - -const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' - ? function (arg, view) { - return cachedTextEncoder.encodeInto(arg, view); -} - : function (arg, view) { - const buf = cachedTextEncoder.encode(arg); - view.set(buf); - return { - read: arg.length, - written: buf.length - }; -}); - -function passStringToWasm0(arg, malloc, realloc) { - - if (realloc === undefined) { - const buf = cachedTextEncoder.encode(arg); - const ptr = malloc(buf.length); - getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); - WASM_VECTOR_LEN = buf.length; - return ptr; - } - - let len = arg.length; - let ptr = malloc(len); - - const mem = getUint8Memory0(); - - let offset = 0; - - for (; offset < len; offset++) { - const code = arg.charCodeAt(offset); - if (code > 0x7F) break; - mem[ptr + offset] = code; - } - - if (offset !== len) { - if (offset !== 0) { - arg = arg.slice(offset); - } - ptr = realloc(ptr, len, len = offset + arg.length * 3); - const view = getUint8Memory0().subarray(ptr + offset, ptr + len); - const ret = encodeString(arg, view); - - offset += ret.written; - } - - WASM_VECTOR_LEN = offset; - return ptr; -} - -function isLikeNone(x) { - return x === undefined || x === null; -} - -let cachedInt32Memory0 = new Int32Array(); - -function getInt32Memory0() { - if (cachedInt32Memory0.byteLength === 0) { - cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); - } - return cachedInt32Memory0; -} - -let heap_next = heap.length; - -function dropObject(idx) { - if (idx < 36) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - 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) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} - -function debugString(val) { - // primitive types - const type = typeof val; - if (type == 'number' || type == 'boolean' || val == null) { - return `${val}`; - } - if (type == 'string') { - return `"${val}"`; - } - if (type == 'symbol') { - const description = val.description; - if (description == null) { - return 'Symbol'; - } else { - return `Symbol(${description})`; - } - } - if (type == 'function') { - const name = val.name; - if (typeof name == 'string' && name.length > 0) { - return `Function(${name})`; - } else { - return 'Function'; - } - } - // objects - if (Array.isArray(val)) { - const length = val.length; - let debug = '['; - if (length > 0) { - debug += debugString(val[0]); - } - for(let i = 1; i < length; i++) { - debug += ', ' + debugString(val[i]); - } - debug += ']'; - return debug; - } - // Test for built-in - const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); - let className; - if (builtInMatches.length > 1) { - className = builtInMatches[1]; - } else { - // Failed to match the standard '[object ClassName]' - return toString.call(val); - } - if (className == 'Object') { - // we're a user defined class or Object - // JSON.stringify avoids problems with cycles, and is generally much - // easier than looping through ownProperties of `val`. - try { - return 'Object(' + JSON.stringify(val) + ')'; - } catch (_) { - return 'Object'; - } - } - // errors - if (val instanceof Error) { - return `${val.name}: ${val.message}\n${val.stack}`; - } - // TODO we could test for more things here, like `Set`s and `Map`s. - return className; -} - -function makeMutClosure(arg0, arg1, dtor, f) { - const state = { a: arg0, b: arg1, cnt: 1, dtor }; - const real = (...args) => { - // First up with a closure we increment the internal reference - // count. This ensures that the Rust closure environment won't - // be deallocated while we're invoking it. - state.cnt++; - const a = state.a; - state.a = 0; - try { - return f(a, state.b, ...args); - } finally { - if (--state.cnt === 0) { - wasm.__wbindgen_export_2.get(state.dtor)(a, state.b); - - } else { - state.a = a; - } - } - }; - real.original = state; - - return real; -} -function __wbg_adapter_24(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__heb2f4d39a212d7d1(arg0, arg1, addHeapObject(arg2)); -} - -function _assertClass(instance, klass) { - if (!(instance instanceof klass)) { - throw new Error(`expected instance of ${klass.name}`); - } - return instance.ptr; -} -/** -* @param {Gps} gps -* @returns {string} -*/ -export function get_gps_map_svg(gps) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - _assertClass(gps, Gps); - wasm.get_gps_map_svg(retptr, gps.ptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - return getStringFromWasm0(r0, r1); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - wasm.__wbindgen_free(r0, r1); - } -} - -let cachedFloat64Memory0 = new Float64Array(); - -function getFloat64Memory0() { - if (cachedFloat64Memory0.byteLength === 0) { - cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer); - } - return cachedFloat64Memory0; -} - -function getArrayF64FromWasm0(ptr, len) { - return getFloat64Memory0().subarray(ptr / 8, ptr / 8 + len); -} -/** -* @param {Gps} gps -* @returns {Float64Array} -*/ -export function get_polygon(gps) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - _assertClass(gps, Gps); - wasm.get_polygon(retptr, gps.ptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var v0 = getArrayF64FromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 8); - return v0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* @param {Gps} gps -* @returns {Float64Array} -*/ -export function get_polyline(gps) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - _assertClass(gps, Gps); - wasm.get_polyline(retptr, gps.ptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var v0 = getArrayF64FromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 8); - return v0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -function getArrayU8FromWasm0(ptr, len) { - return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); -} -/** -* @param {Gps} gps -* @returns {Uint8Array} -*/ -export function get_gps_content(gps) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - _assertClass(gps, Gps); - wasm.get_gps_content(retptr, gps.ptr); - var r0 = getInt32Memory0()[retptr / 4 + 0]; - var r1 = getInt32Memory0()[retptr / 4 + 1]; - var v0 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 1); - return v0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } -} - -/** -* @param {Gps} gps -* @param {string} key1 -* @param {string} value1 -* @param {string} key2 -* @param {string} value2 -* @param {string} key3 -* @param {string} value3 -* @param {string} key4 -* @param {string} value4 -* @returns {Promise} -*/ -export function request_map(gps, key1, value1, key2, value2, key3, value3, key4, value4) { - _assertClass(gps, Gps); - const ptr0 = passStringToWasm0(key1, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ptr1 = passStringToWasm0(value1, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len1 = WASM_VECTOR_LEN; - const ptr2 = passStringToWasm0(key2, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len2 = WASM_VECTOR_LEN; - const ptr3 = passStringToWasm0(value2, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len3 = WASM_VECTOR_LEN; - const ptr4 = passStringToWasm0(key3, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len4 = WASM_VECTOR_LEN; - const ptr5 = passStringToWasm0(value3, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len5 = WASM_VECTOR_LEN; - const ptr6 = passStringToWasm0(key4, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len6 = WASM_VECTOR_LEN; - const ptr7 = passStringToWasm0(value4, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len7 = WASM_VECTOR_LEN; - const ret = wasm.request_map(gps.ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, ptr6, len6, ptr7, len7); - return takeObject(ret); -} - -/** -* @param {string} input -* @returns {Gps} -*/ -export function load_gps_from_string(input) { - const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.load_gps_from_string(ptr0, len0); - return Gps.__wrap(ret); -} - -/** -* @param {number} xmin -* @param {number} ymin -* @param {number} xmax -* @param {number} ymax -* @returns {Gps} -*/ -export function gps_from_area(xmin, ymin, xmax, ymax) { - const ret = wasm.gps_from_area(xmin, ymin, xmax, ymax); - return Gps.__wrap(ret); -} - -function handleError(f, args) { - try { - return f.apply(this, args); - } catch (e) { - wasm.__wbindgen_exn_store(addHeapObject(e)); - } -} -function __wbg_adapter_84(arg0, arg1, arg2, arg3) { - wasm.wasm_bindgen__convert__closures__invoke2_mut__h362f82c7669db137(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3)); -} - -/** -*/ -export class Gps { - - static __wrap(ptr) { - const obj = Object.create(Gps.prototype); - obj.ptr = ptr; - - return obj; - } - - __destroy_into_raw() { - const ptr = this.ptr; - this.ptr = 0; - - return ptr; - } - - free() { - const ptr = this.__destroy_into_raw(); - wasm.__wbg_gps_free(ptr); - } -} - -async function load(module, imports) { - if (typeof Response === 'function' && module instanceof Response) { - if (typeof WebAssembly.instantiateStreaming === 'function') { - try { - return await WebAssembly.instantiateStreaming(module, imports); - - } catch (e) { - if (module.headers.get('Content-Type') != 'application/wasm') { - console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); - - } else { - throw e; - } - } - } - - const bytes = await module.arrayBuffer(); - return await WebAssembly.instantiate(bytes, imports); - - } else { - const instance = await WebAssembly.instantiate(module, imports); - - if (instance instanceof WebAssembly.Instance) { - return { instance, module }; - - } else { - return instance; - } - } -} - -function getImports() { - const imports = {}; - imports.wbg = {}; - imports.wbg.__wbg_log_d04343b58be82b0f = function(arg0, arg1) { - console.log(getStringFromWasm0(arg0, arg1)); - }; - imports.wbg.__wbindgen_string_get = function(arg0, arg1) { - const obj = getObject(arg1); - const ret = typeof(obj) === 'string' ? obj : undefined; - var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len0 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len0; - getInt32Memory0()[arg0 / 4 + 0] = ptr0; - }; - imports.wbg.__wbindgen_object_drop_ref = function(arg0) { - takeObject(arg0); - }; - imports.wbg.__wbindgen_string_new = function(arg0, arg1) { - const ret = getStringFromWasm0(arg0, arg1); - return addHeapObject(ret); - }; - imports.wbg.__wbg_fetch_57429b87be3dcc33 = function(arg0) { - const ret = fetch(getObject(arg0)); - 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_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_2d0053ee81e4dd2a = function() { return handleError(function () { - const ret = new Headers(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_append_de37df908812970d = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { - getObject(arg0).append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4)); - }, arguments) }; - imports.wbg.__wbg_instanceof_Response_eaa426220848a39e = function(arg0) { - let result; - try { - result = getObject(arg0) instanceof Response; - } catch { - result = false; - } - const ret = result; - return ret; - }; - imports.wbg.__wbg_url_74285ddf2747cb3d = function(arg0, arg1) { - const ret = getObject(arg1).url; - const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len0; - getInt32Memory0()[arg0 / 4 + 0] = ptr0; - }; - imports.wbg.__wbg_status_c4ef3dd591e63435 = function(arg0) { - const ret = getObject(arg0).status; - return ret; - }; - imports.wbg.__wbg_headers_fd64ad685cf22e5d = function(arg0) { - const ret = getObject(arg0).headers; - return addHeapObject(ret); - }; - imports.wbg.__wbg_text_1169d752cc697903 = function() { return handleError(function (arg0) { - const ret = getObject(arg0).text(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_new_abda76e883ba8a5f = function() { - const ret = new Error(); - return addHeapObject(ret); - }; - imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { - const ret = getObject(arg1).stack; - const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len0; - getInt32Memory0()[arg0 / 4 + 0] = ptr0; - }; - imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { - try { - console.error(getStringFromWasm0(arg0, arg1)); - } finally { - wasm.__wbindgen_free(arg0, arg1); - } - }; - imports.wbg.__wbindgen_cb_drop = function(arg0) { - const obj = takeObject(arg0).original; - if (obj.cnt-- == 1) { - obj.a = 0; - return true; - } - const ret = false; - return ret; - }; - imports.wbg.__wbindgen_is_object = function(arg0) { - const val = getObject(arg0); - const ret = typeof(val) === 'object' && val !== null; - return ret; - }; - imports.wbg.__wbg_newnoargs_b5b063fc6c2f0376 = function(arg0, arg1) { - const ret = new Function(getStringFromWasm0(arg0, arg1)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_next_579e583d33566a86 = function(arg0) { - const ret = getObject(arg0).next; - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_is_function = function(arg0) { - const ret = typeof(getObject(arg0)) === 'function'; - return ret; - }; - imports.wbg.__wbg_value_1ccc36bc03462d71 = function(arg0) { - const ret = getObject(arg0).value; - return addHeapObject(ret); - }; - imports.wbg.__wbg_iterator_6f9d4f28845f426c = function() { - const ret = Symbol.iterator; - return addHeapObject(ret); - }; - imports.wbg.__wbg_new_0b9bfdd97583284e = function() { - const ret = new Object(); - return addHeapObject(ret); - }; - imports.wbg.__wbg_self_6d479506f72c6a71 = function() { return handleError(function () { - const ret = self.self; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_window_f2557cc78490aceb = function() { return handleError(function () { - const ret = window.window; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_globalThis_7f206bda628d5286 = function() { return handleError(function () { - const ret = globalThis.globalThis; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_global_ba75c50d1cf384f4 = function() { return handleError(function () { - const ret = global.global; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbindgen_is_undefined = function(arg0) { - const ret = getObject(arg0) === undefined; - return ret; - }; - imports.wbg.__wbg_call_97ae9d8645dc388b = function() { return handleError(function (arg0, arg1) { - const ret = getObject(arg0).call(getObject(arg1)); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_call_168da88779e35f61 = function() { return handleError(function (arg0, arg1, arg2) { - const ret = getObject(arg0).call(getObject(arg1), getObject(arg2)); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_next_aaef7c8aa5e212ac = function() { return handleError(function (arg0) { - const ret = getObject(arg0).next(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_done_1b73b0672e15f234 = function(arg0) { - const ret = getObject(arg0).done; - return ret; - }; - imports.wbg.__wbg_new_9962f939219f1820 = function(arg0, arg1) { - try { - var state0 = {a: arg0, b: arg1}; - var cb0 = (arg0, arg1) => { - const a = state0.a; - state0.a = 0; - try { - return __wbg_adapter_84(a, state0.b, arg0, arg1); - } finally { - state0.a = a; - } - }; - const ret = new Promise(cb0); - return addHeapObject(ret); - } finally { - state0.a = state0.b = 0; - } - }; - imports.wbg.__wbg_resolve_99fe17964f31ffc0 = function(arg0) { - const ret = Promise.resolve(getObject(arg0)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_then_11f7a54d67b4bfad = function(arg0, arg1) { - const ret = getObject(arg0).then(getObject(arg1)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_then_cedad20fbbd9418a = function(arg0, arg1, arg2) { - const ret = getObject(arg0).then(getObject(arg1), getObject(arg2)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_buffer_3f3d764d4747d564 = function(arg0) { - const ret = getObject(arg0).buffer; - return addHeapObject(ret); - }; - imports.wbg.__wbg_newwithbyteoffsetandlength_d9aa266703cb98be = function(arg0, arg1, arg2) { - const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); - return addHeapObject(ret); - }; - imports.wbg.__wbg_new_8c3f0052272a457a = function(arg0) { - const ret = new Uint8Array(getObject(arg0)); - return addHeapObject(ret); - }; - imports.wbg.__wbg_get_765201544a2b6869 = function() { return handleError(function (arg0, arg1) { - const ret = Reflect.get(getObject(arg0), getObject(arg1)); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_has_8359f114ce042f5a = function() { return handleError(function (arg0, arg1) { - const ret = Reflect.has(getObject(arg0), getObject(arg1)); - return ret; - }, arguments) }; - imports.wbg.__wbg_set_bf3f89b92d5a34bf = function() { return handleError(function (arg0, arg1, arg2) { - const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2)); - return ret; - }, 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) { - const ret = debugString(getObject(arg1)); - const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - const len0 = WASM_VECTOR_LEN; - getInt32Memory0()[arg0 / 4 + 1] = len0; - getInt32Memory0()[arg0 / 4 + 0] = ptr0; - }; - imports.wbg.__wbindgen_throw = function(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); - }; - imports.wbg.__wbindgen_memory = function() { - const ret = wasm.memory; - return addHeapObject(ret); - }; - imports.wbg.__wbindgen_closure_wrapper2245 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 267, __wbg_adapter_24); - return addHeapObject(ret); - }; - - return imports; -} - -function initMemory(imports, maybe_memory) { - -} - -function finalizeInit(instance, module) { - wasm = instance.exports; - init.__wbindgen_wasm_module = module; - cachedFloat64Memory0 = new Float64Array(); - cachedInt32Memory0 = new Int32Array(); - cachedUint8Memory0 = new Uint8Array(); - - - return wasm; -} - -function initSync(module) { - const imports = getImports(); - - initMemory(imports); - - if (!(module instanceof WebAssembly.Module)) { - module = new WebAssembly.Module(module); - } - - const instance = new WebAssembly.Instance(module, imports); - - return finalizeInit(instance, module); -} - -async function init(input) { - if (typeof input === 'undefined') { - input = new URL('gps_bg.wasm', import.meta.url); - } - const imports = getImports(); - - if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { - input = fetch(input); - } - - initMemory(imports); - - const { instance, module } = await load(await input, imports); - - return finalizeInit(instance, module); -} - -export { initSync } -export default init; +import * as wasm from "./gps_bg.wasm"; +export * from "./gps_bg.js"; \ No newline at end of file diff --git a/apps/gipy/pkg/gps_bg.wasm b/apps/gipy/pkg/gps_bg.wasm index 8e0fbc07eb7d7cf8a96dd646305f808eda4e49cc..bbc9ce6a7449547ed257a72d61207453d2938894 100644 GIT binary patch delta 266102 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

TJG^>?hdH_6c@S?gTq2z>y|_+OqblLj;B} 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≧ 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 HW$^z40Wg=I delta 269785 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 LH>yJtsZW|`>zn~@3T*DPr*(nRfOHn23 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 diff --git a/apps/gipy/pkg/gps_bg.wasm.d.ts b/apps/gipy/pkg/gps_bg.wasm.d.ts index b4303ee301..3b95ada789 100644 --- a/apps/gipy/pkg/gps_bg.wasm.d.ts +++ b/apps/gipy/pkg/gps_bg.wasm.d.ts @@ -4,6 +4,7 @@ export const memory: WebAssembly.Memory; export function __wbg_gps_free(a: number): void; export function get_gps_map_svg(a: number, b: number): void; export function get_polygon(a: number, b: number): void; +export function has_heights(a: number): number; export function get_polyline(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; @@ -12,8 +13,8 @@ export function gps_from_area(a: number, b: number, c: number, d: number): numbe export function __wbindgen_malloc(a: number): number; export function __wbindgen_realloc(a: number, b: number, c: number): number; export const __wbindgen_export_2: WebAssembly.Table; -export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__heb2f4d39a212d7d1(a: number, b: number, c: number): void; +export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb15c13006e54cdd7(a: number, b: number, c: number): void; export function __wbindgen_add_to_stack_pointer(a: number): number; export function __wbindgen_free(a: number, b: number): void; export function __wbindgen_exn_store(a: number): void; -export function wasm_bindgen__convert__closures__invoke2_mut__h362f82c7669db137(a: number, b: number, c: number, d: number): void; +export function wasm_bindgen__convert__closures__invoke2_mut__h4d77bafb1e69a027(a: number, b: number, c: number, d: number): void; diff --git a/apps/gipy/pkg/package.json b/apps/gipy/pkg/package.json index 0f6ae6a751..57fbc33523 100644 --- a/apps/gipy/pkg/package.json +++ b/apps/gipy/pkg/package.json @@ -4,6 +4,7 @@ "files": [ "gps_bg.wasm", "gps.js", + "gps_bg.js", "gps.d.ts" ], "module": "gps.js", From b9dc5a11ced52b20c1caa9b81a18632933701028 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Tue, 22 Aug 2023 14:50:37 +0200 Subject: [PATCH 04/12] gipy: wasm fix --- apps/gipy/ChangeLog | 1 + apps/gipy/pkg/gps.d.ts | 44 +++ apps/gipy/pkg/gps.js | 745 ++++++++++++++++++++++++++++++++++++- apps/gipy/pkg/gps_bg.wasm | Bin 743877 -> 743453 bytes apps/gipy/pkg/package.json | 1 - 5 files changed, 788 insertions(+), 3 deletions(-) diff --git a/apps/gipy/ChangeLog b/apps/gipy/ChangeLog index 3ca699a4fe..ac67eafda4 100644 --- a/apps/gipy/ChangeLog +++ b/apps/gipy/ChangeLog @@ -101,3 +101,4 @@ 0.21: * Jit is back for display functions (10% speed increase) + * Store, parse and display elevation data diff --git a/apps/gipy/pkg/gps.d.ts b/apps/gipy/pkg/gps.d.ts index 3f1c8f372a..e4644f74fd 100644 --- a/apps/gipy/pkg/gps.d.ts +++ b/apps/gipy/pkg/gps.d.ts @@ -56,3 +56,47 @@ export function gps_from_area(xmin: number, ymin: number, xmax: number, ymax: nu export class Gps { free(): void; } + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly __wbg_gps_free: (a: number) => void; + readonly get_gps_map_svg: (a: number, b: number) => void; + readonly get_polygon: (a: number, b: number) => void; + readonly has_heights: (a: number) => number; + readonly get_polyline: (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 load_gps_from_string: (a: number, b: number) => number; + readonly gps_from_area: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_malloc: (a: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number) => number; + readonly __wbindgen_export_2: WebAssembly.Table; + readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb15c13006e54cdd7: (a: number, b: number, c: number) => void; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; + readonly __wbindgen_free: (a: number, b: number) => void; + readonly __wbindgen_exn_store: (a: number) => void; + readonly wasm_bindgen__convert__closures__invoke2_mut__h4d77bafb1e69a027: (a: number, b: number, c: number, d: number) => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {SyncInitInput} module +* +* @returns {InitOutput} +*/ +export function initSync(module: SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {InitInput | Promise} module_or_path +* +* @returns {Promise} +*/ +export default function init (module_or_path?: InitInput | Promise): Promise; diff --git a/apps/gipy/pkg/gps.js b/apps/gipy/pkg/gps.js index 5c9bfc9bdd..563bf6251c 100644 --- a/apps/gipy/pkg/gps.js +++ b/apps/gipy/pkg/gps.js @@ -1,2 +1,743 @@ -import * as wasm from "./gps_bg.wasm"; -export * from "./gps_bg.js"; \ No newline at end of file + +let wasm; + +const heap = new Array(32).fill(undefined); + +heap.push(undefined, null, true, false); + +function getObject(idx) { return heap[idx]; } + +let WASM_VECTOR_LEN = 0; + +let cachedUint8Memory0 = new Uint8Array(); + +function getUint8Memory0() { + if (cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} + +const cachedTextEncoder = new TextEncoder('utf-8'); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length); + getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len); + + const mem = getUint8Memory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3); + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +let cachedInt32Memory0 = new Int32Array(); + +function getInt32Memory0() { + if (cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} + +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 36) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + 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) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } + } + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } + } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +function makeMutClosure(arg0, arg1, dtor, f) { + const state = { a: arg0, b: arg1, cnt: 1, dtor }; + const real = (...args) => { + // First up with a closure we increment the internal reference + // count. This ensures that the Rust closure environment won't + // be deallocated while we're invoking it. + state.cnt++; + const a = state.a; + state.a = 0; + try { + return f(a, state.b, ...args); + } finally { + if (--state.cnt === 0) { + wasm.__wbindgen_export_2.get(state.dtor)(a, state.b); + + } else { + state.a = a; + } + } + }; + real.original = state; + + return real; +} +function __wbg_adapter_24(arg0, arg1, arg2) { + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb15c13006e54cdd7(arg0, arg1, addHeapObject(arg2)); +} + +function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); + } + return instance.ptr; +} +/** +* @param {Gps} gps +* @returns {string} +*/ +export function get_gps_map_svg(gps) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(gps, Gps); + wasm.get_gps_map_svg(retptr, gps.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(r0, r1); + } +} + +let cachedFloat64Memory0 = new Float64Array(); + +function getFloat64Memory0() { + if (cachedFloat64Memory0.byteLength === 0) { + cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer); + } + return cachedFloat64Memory0; +} + +function getArrayF64FromWasm0(ptr, len) { + return getFloat64Memory0().subarray(ptr / 8, ptr / 8 + len); +} +/** +* @param {Gps} gps +* @returns {Float64Array} +*/ +export function get_polygon(gps) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(gps, Gps); + wasm.get_polygon(retptr, gps.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var v0 = getArrayF64FromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 8); + return v0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* @param {Gps} gps +* @returns {boolean} +*/ +export function has_heights(gps) { + _assertClass(gps, Gps); + const ret = wasm.has_heights(gps.ptr); + return ret !== 0; +} + +/** +* @param {Gps} gps +* @returns {Float64Array} +*/ +export function get_polyline(gps) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(gps, Gps); + wasm.get_polyline(retptr, gps.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var v0 = getArrayF64FromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 8); + return v0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +function getArrayU8FromWasm0(ptr, len) { + return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); +} +/** +* @param {Gps} gps +* @returns {Uint8Array} +*/ +export function get_gps_content(gps) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(gps, Gps); + wasm.get_gps_content(retptr, gps.ptr); + var r0 = getInt32Memory0()[retptr / 4 + 0]; + var r1 = getInt32Memory0()[retptr / 4 + 1]; + var v0 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 1); + return v0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** +* @param {Gps} gps +* @param {string} key1 +* @param {string} value1 +* @param {string} key2 +* @param {string} value2 +* @param {string} key3 +* @param {string} value3 +* @param {string} key4 +* @param {string} value4 +* @returns {Promise} +*/ +export function request_map(gps, key1, value1, key2, value2, key3, value3, key4, value4) { + _assertClass(gps, Gps); + const ptr0 = passStringToWasm0(key1, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(value1, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(key2, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len2 = WASM_VECTOR_LEN; + const ptr3 = passStringToWasm0(value2, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len3 = WASM_VECTOR_LEN; + const ptr4 = passStringToWasm0(key3, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len4 = WASM_VECTOR_LEN; + const ptr5 = passStringToWasm0(value3, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len5 = WASM_VECTOR_LEN; + const ptr6 = passStringToWasm0(key4, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len6 = WASM_VECTOR_LEN; + const ptr7 = passStringToWasm0(value4, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len7 = WASM_VECTOR_LEN; + const ret = wasm.request_map(gps.ptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5, ptr6, len6, ptr7, len7); + return takeObject(ret); +} + +/** +* @param {string} input +* @returns {Gps} +*/ +export function load_gps_from_string(input) { + const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.load_gps_from_string(ptr0, len0); + return Gps.__wrap(ret); +} + +/** +* @param {number} xmin +* @param {number} ymin +* @param {number} xmax +* @param {number} ymax +* @returns {Gps} +*/ +export function gps_from_area(xmin, ymin, xmax, ymax) { + const ret = wasm.gps_from_area(xmin, ymin, xmax, ymax); + return Gps.__wrap(ret); +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + wasm.__wbindgen_exn_store(addHeapObject(e)); + } +} +function __wbg_adapter_85(arg0, arg1, arg2, arg3) { + wasm.wasm_bindgen__convert__closures__invoke2_mut__h4d77bafb1e69a027(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3)); +} + +/** +*/ +export class Gps { + + static __wrap(ptr) { + const obj = Object.create(Gps.prototype); + obj.ptr = ptr; + + return obj; + } + + __destroy_into_raw() { + const ptr = this.ptr; + this.ptr = 0; + + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_gps_free(ptr); + } +} + +async function load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function getImports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbg_log_d04343b58be82b0f = function(arg0, arg1) { + console.log(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }; + imports.wbg.__wbg_fetch_57429b87be3dcc33 = function(arg0) { + const ret = fetch(getObject(arg0)); + 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 () { + const ret = new Headers(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_append_de37df908812970d = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4)); + }, arguments) }; + imports.wbg.__wbg_instanceof_Response_eaa426220848a39e = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof Response; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_url_74285ddf2747cb3d = function(arg0, arg1) { + const ret = getObject(arg1).url; + const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbg_status_c4ef3dd591e63435 = function(arg0) { + const ret = getObject(arg0).status; + return ret; + }; + imports.wbg.__wbg_headers_fd64ad685cf22e5d = function(arg0) { + const ret = getObject(arg0).headers; + return addHeapObject(ret); + }; + imports.wbg.__wbg_text_1169d752cc697903 = function() { return handleError(function (arg0) { + const ret = getObject(arg0).text(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_new_abda76e883ba8a5f = function() { + const ret = new Error(); + return addHeapObject(ret); + }; + imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { + const ret = getObject(arg1).stack; + const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { + try { + console.error(getStringFromWasm0(arg0, arg1)); + } finally { + wasm.__wbindgen_free(arg0, arg1); + } + }; + imports.wbg.__wbindgen_cb_drop = function(arg0) { + const obj = takeObject(arg0).original; + if (obj.cnt-- == 1) { + obj.a = 0; + return true; + } + const ret = false; + return ret; + }; + imports.wbg.__wbindgen_is_object = function(arg0) { + const val = getObject(arg0); + const ret = typeof(val) === 'object' && val !== null; + return ret; + }; + imports.wbg.__wbg_newnoargs_b5b063fc6c2f0376 = function(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_next_579e583d33566a86 = function(arg0) { + const ret = getObject(arg0).next; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_is_function = function(arg0) { + const ret = typeof(getObject(arg0)) === 'function'; + return ret; + }; + imports.wbg.__wbg_value_1ccc36bc03462d71 = function(arg0) { + const ret = getObject(arg0).value; + return addHeapObject(ret); + }; + imports.wbg.__wbg_iterator_6f9d4f28845f426c = function() { + const ret = Symbol.iterator; + return addHeapObject(ret); + }; + imports.wbg.__wbg_new_0b9bfdd97583284e = function() { + const ret = new Object(); + return addHeapObject(ret); + }; + imports.wbg.__wbg_self_6d479506f72c6a71 = function() { return handleError(function () { + const ret = self.self; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_window_f2557cc78490aceb = function() { return handleError(function () { + const ret = window.window; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_globalThis_7f206bda628d5286 = function() { return handleError(function () { + const ret = globalThis.globalThis; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_global_ba75c50d1cf384f4 = function() { return handleError(function () { + const ret = global.global; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbindgen_is_undefined = function(arg0) { + const ret = getObject(arg0) === undefined; + return ret; + }; + imports.wbg.__wbg_call_97ae9d8645dc388b = function() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).call(getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_call_168da88779e35f61 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).call(getObject(arg1), getObject(arg2)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_next_aaef7c8aa5e212ac = function() { return handleError(function (arg0) { + const ret = getObject(arg0).next(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_done_1b73b0672e15f234 = function(arg0) { + const ret = getObject(arg0).done; + return ret; + }; + imports.wbg.__wbg_new_9962f939219f1820 = function(arg0, arg1) { + try { + var state0 = {a: arg0, b: arg1}; + var cb0 = (arg0, arg1) => { + const a = state0.a; + state0.a = 0; + try { + return __wbg_adapter_85(a, state0.b, arg0, arg1); + } finally { + state0.a = a; + } + }; + const ret = new Promise(cb0); + return addHeapObject(ret); + } finally { + state0.a = state0.b = 0; + } + }; + imports.wbg.__wbg_resolve_99fe17964f31ffc0 = function(arg0) { + const ret = Promise.resolve(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_then_11f7a54d67b4bfad = function(arg0, arg1) { + const ret = getObject(arg0).then(getObject(arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_then_cedad20fbbd9418a = function(arg0, arg1, arg2) { + const ret = getObject(arg0).then(getObject(arg1), getObject(arg2)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_buffer_3f3d764d4747d564 = function(arg0) { + const ret = getObject(arg0).buffer; + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_d9aa266703cb98be = function(arg0, arg1, arg2) { + const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_new_8c3f0052272a457a = function(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_get_765201544a2b6869 = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(getObject(arg0), getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_has_8359f114ce042f5a = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.has(getObject(arg0), getObject(arg1)); + return ret; + }, arguments) }; + imports.wbg.__wbg_set_bf3f89b92d5a34bf = function() { return handleError(function (arg0, arg1, arg2) { + const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2)); + return ret; + }, 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) { + const ret = debugString(getObject(arg1)); + const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len0; + getInt32Memory0()[arg0 / 4 + 0] = ptr0; + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper2214 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 268, __wbg_adapter_24); + return addHeapObject(ret); + }; + + return imports; +} + +function initMemory(imports, maybe_memory) { + +} + +function finalizeInit(instance, module) { + wasm = instance.exports; + init.__wbindgen_wasm_module = module; + cachedFloat64Memory0 = new Float64Array(); + cachedInt32Memory0 = new Int32Array(); + cachedUint8Memory0 = new Uint8Array(); + + + return wasm; +} + +function initSync(module) { + const imports = getImports(); + + initMemory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return finalizeInit(instance, module); +} + +async function init(input) { + if (typeof input === 'undefined') { + input = new URL('gps_bg.wasm', import.meta.url); + } + const imports = getImports(); + + if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { + input = fetch(input); + } + + initMemory(imports); + + const { instance, module } = await load(await input, imports); + + return finalizeInit(instance, module); +} + +export { initSync } +export default init; diff --git a/apps/gipy/pkg/gps_bg.wasm b/apps/gipy/pkg/gps_bg.wasm index bbc9ce6a7449547ed257a72d61207453d2938894..7a42fb564e0b20e7bbc6645e7ef0725ff06f8bec 100644 GIT binary patch delta 906 zcmZ8f%Zk)M6z%DBC*2W5#TTRLhvN&RC6B63Wh3rnKonPko1&iSXeN>FG>vN)et=6I z5Ix9Zf!1BTc?qo+iJyno-A8_B%$i>`b)gXxsX} zZCTy1Zu#ATCeOOwt$Nl~?Q&5O_5x2K3gbiy03ZmMoEo1;-65*A=Nc9m#e81A)Hgrh zXk-hl?HN;^y{9KWv6u3Mfqm*yoUIi@6r4EkI-ix7~&9RKF*{#{Ut8Od{;#6%<)i0jYAPY8AiYuI_#M}o%F`dGu2GJmLQNZfq+kA3aBL9 z%<=kLNBym%KKMTk#3JeYFbw0602mW9?`Pj@DraPYQ3Mki1b_)2gc1@n<*sXP_SD^b zQpa_vu^BGtGBvMRKZ7%kZZ(^iD_uU@C?AM}a{fx^`g-lYS-U$5Z3RoAqtI2b6&!`0 OLSMoCymn9hc=QJjUK!~C delta 1363 zcmZ`(J#W)c6m{doPTCHXPpLpcp$k+gv7h~HZ|q1wCRotJ@53goYge{IKp=HMf{7_3 zs>F_jDlsqu0}BH23m8~f`3c}89^QQ_!&%Nd@A%$x@AKhN|I7RS(T&Ez*EM%#`+B@z z5E^gq6lVyT&{4``k&>d!M`=uAQEHm3S)XZQl4LRA0|z;Xx;_=YO$X62!rCmOJA##j z=h;5VMWpEq$7}!nY$_(&lKk1}=SC09#CfUK+MXp@D(3!%tehHpZxs+%^({!;(=S2d znSK!xhpNXXRq;#pXf^vF-8#8(o)FKmeV6md_8gB<#9?yNyG^B>r_Bvm&YNcUf!tE< zUByO1%0mwe-$yj`LpRcvW#NUz_=+-Qy9B$w?FEr=9M`c}gq1RkR_~5{_oNg#qw{HM zAnDVRU{sLBSfFHjzjft6Hl5EgCaHK_64wia>m!bki*e{mq9+_|9Rxc)c6Z9O5W%7=M2fyZmo@t)Yr@+a_J nbft5aJRf#m4m(Q~8Wr>k%?hmwMg_A%yTVMf{9)Kx`F86cBxtWp diff --git a/apps/gipy/pkg/package.json b/apps/gipy/pkg/package.json index 57fbc33523..0f6ae6a751 100644 --- a/apps/gipy/pkg/package.json +++ b/apps/gipy/pkg/package.json @@ -4,7 +4,6 @@ "files": [ "gps_bg.wasm", "gps.js", - "gps_bg.js", "gps.d.ts" ], "module": "gps.js", From e6f30b9dc0df975b188f93792786b1840d889e10 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Tue, 22 Aug 2023 16:52:28 +0200 Subject: [PATCH 05/12] gipy: removed 'lost' message --- apps/gipy/ChangeLog | 1 + apps/gipy/README.md | 5 ++--- apps/gipy/TODO | 2 -- apps/gipy/app.js | 17 ++++++++++------- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/gipy/ChangeLog b/apps/gipy/ChangeLog index ac67eafda4..a5384c0c80 100644 --- a/apps/gipy/ChangeLog +++ b/apps/gipy/ChangeLog @@ -102,3 +102,4 @@ 0.21: * Jit is back for display functions (10% speed increase) * Store, parse and display elevation data + * Removed 'lost' indicator (we now change position to purple when lost) diff --git a/apps/gipy/README.md b/apps/gipy/README.md index ac65f8c3ff..dc260fd70d 100644 --- a/apps/gipy/README.md +++ b/apps/gipy/README.md @@ -79,17 +79,16 @@ On your screen you can see: * green: artwork - a *turn* indicator on the top right when you reach a turning point - a *gps* indicator (blinking) on the top right if you lose gps signal -- a *lost* indicator on the top right if you stray too far away from path ### Lost If you stray away from path we will rescale the display to continue displaying nearby segments and -display the direction to follow as a purple segment. +display the direction to follow as a purple segment. Your main position will also turn to purple. Note that while lost, the app will slow down a lot since it will start scanning all possible points to figure out where you are. On path it just needed to scan a few points ahead and behind. -The distance to next point displayed corresponds to the length of the black segment. +The distance to next point displayed corresponds to the length of the purple segment. ### Menu diff --git a/apps/gipy/TODO b/apps/gipy/TODO index ef1df3dc5f..b642b5cf6a 100644 --- a/apps/gipy/TODO +++ b/apps/gipy/TODO @@ -45,8 +45,6 @@ JIT: array declaration in jit is buggy + when lost we still get powersaving + try disabling gps for more powersaving -+ remove "lost" indicator and change position point's color instead - + when you walk the direction still has a tendency to shift + put back foot only ways diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 70c1aafd36..2aec35429f 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -1126,7 +1126,11 @@ class Status { previous_y = y; } } - g.setColor(0, 0, 0); + if (this.on_path) { + g.setColor(0, 0, 0); + } else { + g.setColor(1, 0, 1); + } g.fillCircle(current_x, current_y, 5); // display min dist/max dist and min height/max height @@ -1267,11 +1271,6 @@ class Status { .drawString("turn", g.getWidth() - 50, 30); } } - if (!this.on_path) { - g.setColor(1.0, 0.0, 0.0) - .setFont("6x15") - .drawString("lost", g.getWidth() - 55, 35); - } } display_path() { // don't display all segments, only those neighbouring current segment @@ -1329,7 +1328,11 @@ class Status { } // now display ourselves - g.setColor(0, 0, 0); + if (this.on_path) { + g.setColor(0, 0, 0); + } else { + g.setColor(1, 0, 1); + } g.fillCircle(half_width, half_height, 5); } } From 7baa0d21739caeb79a29fec4a31e3ce8069ecbdf Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Tue, 22 Aug 2023 17:05:41 +0200 Subject: [PATCH 06/12] gipy: small fixes --- apps/gipy/ChangeLog | 2 ++ apps/gipy/TODO | 2 -- apps/gipy/app.js | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/gipy/ChangeLog b/apps/gipy/ChangeLog index a5384c0c80..73164dbd38 100644 --- a/apps/gipy/ChangeLog +++ b/apps/gipy/ChangeLog @@ -103,3 +103,5 @@ * Jit is back for display functions (10% speed increase) * Store, parse and display elevation data * Removed 'lost' indicator (we now change position to purple when lost) + * Powersaving fix : don't powersave when lost + * Bugfix for negative remaining distance when going backwards diff --git a/apps/gipy/TODO b/apps/gipy/TODO index b642b5cf6a..8c767c4639 100644 --- a/apps/gipy/TODO +++ b/apps/gipy/TODO @@ -41,8 +41,6 @@ JIT: array declaration in jit is buggy ************************** -+ there is still a bug with negative remaining distances (when lost and nearest point is endpoint ?) -+ when lost we still get powersaving + try disabling gps for more powersaving + when you walk the direction still has a tendency to shift diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 2aec35429f..0ccdff36b8 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -847,7 +847,6 @@ class Status { // now check if we strayed away from path or back to it let lost = this.is_lost(next_segment); if (this.on_path == lost) { - this.activate(); // if status changes if (lost) { Bangle.buzz(); // we lost path @@ -857,6 +856,9 @@ class Status { } this.on_path = !lost; } + if (!this.on_path) { + this.activate(); + } this.current_segment = next_segment; @@ -959,14 +961,12 @@ class Status { ]); } remaining_distance() { - let remaining_in_correct_orientation = - this.remaining_distances[this.current_segment + 1] + - this.position.distance(this.path.point(this.current_segment + 1)); - if (go_backwards) { - return this.remaining_distances[0] - remaining_in_correct_orientation; + return this.remaining_distances[0] - this.remaining_distances[this.current_segment] + + this.position.distance(this.path.point(this.current_segment)); } else { - return remaining_in_correct_orientation; + return this.remaining_distances[this.current_segment + 1] + + this.position.distance(this.path.point(this.current_segment + 1)); } } // check if we are lost (too far from segment we think we are on) From 463bba49968102907baf231bd7a084bf688605d5 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Wed, 23 Aug 2023 08:00:05 +0200 Subject: [PATCH 07/12] gipy: min height --- apps/gipy/app.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 0ccdff36b8..674771293c 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -1043,6 +1043,12 @@ class Status { max_height = Math.max(max_height, height); min_height = Math.min(min_height, height); } + // we'll set the displayed height to a minimum value of 100m + // if we don't, then we'll see too much noise + if (max_height - min_height < 100) { + min_height = min_height - 10; + max_height = min_height + 110; + } let displayed_height = max_height - min_height; let height_per_pixel = displayed_height / graph_height; From b8e29f397dd7ced3ab9b544f8c5e4cab9e5d2db1 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Wed, 23 Aug 2023 08:29:21 +0200 Subject: [PATCH 08/12] gipy: doc change --- apps/gipy/README.md | 4 ++++ apps/gipy/app.js | 2 +- apps/gipy/heights.png | Bin 0 -> 3627 bytes 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 apps/gipy/heights.png diff --git a/apps/gipy/README.md b/apps/gipy/README.md index dc260fd70d..0df008b38e 100644 --- a/apps/gipy/README.md +++ b/apps/gipy/README.md @@ -101,6 +101,10 @@ If you touch the screen you will switch between display modes. The first one displays the map, the second one the nearby elevation and the last one the elevation for the whole path. +![Screenshot](heights.png) + +Colors correspond to slopes. + ### Settings Few settings for now (feel free to suggest me more) : diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 674771293c..4fa51f779d 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -1082,7 +1082,7 @@ class Status { if (steepness > 0.15) { color = "#ff0000"; } else if (steepness > 0.8) { - color = "#aa0000"; + color = "#ff8000"; } else if (steepness > 0.03) { color = "#ffff00"; } else if (steepness > -0.03) { diff --git a/apps/gipy/heights.png b/apps/gipy/heights.png new file mode 100644 index 0000000000000000000000000000000000000000..07f82511b7d9f731f2cd059123feeb9af62ecc17 GIT binary patch literal 3627 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 Ezcg}uFaQ7m literal 0 HcmV?d00001 From cf0695c3eb5a39fc7ecd5fb77ab909486e1f760d Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Thu, 24 Aug 2023 10:01:50 +0200 Subject: [PATCH 09/12] gipy : fix for backwards position in heights --- apps/gipy/app.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 4fa51f779d..56137ae58d 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -996,8 +996,12 @@ class Status { } else { let current_position = 0; if (this.current_segment !== null) { + if (go_backwards) { + current_position = this.remaining_distance(); + } else { current_position = this.remaining_distances[0] - this.remaining_distance(); + } } if (this.screen == HEIGHTS_FULL) { this.display_heights(0, current_position, this.remaining_distances[0]); From 1aa7a4d7b50ae4989faa68f14a870a00c7ef8840 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Wed, 30 Aug 2023 18:29:36 +0200 Subject: [PATCH 10/12] gipy: powersaving changes + fix for heights --- apps/gipy/ChangeLog | 2 ++ apps/gipy/README.md | 4 +++- apps/gipy/app.js | 18 +++++++++++------- apps/gipy/settings.js | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/apps/gipy/ChangeLog b/apps/gipy/ChangeLog index 73164dbd38..09637df1ba 100644 --- a/apps/gipy/ChangeLog +++ b/apps/gipy/ChangeLog @@ -105,3 +105,5 @@ * Removed 'lost' indicator (we now change position to purple when lost) * Powersaving fix : don't powersave when lost * Bugfix for negative remaining distance when going backwards + * New settings for powersaving + * Adjustments to powersaving algorithm diff --git a/apps/gipy/README.md b/apps/gipy/README.md index 0df008b38e..d96461dfe5 100644 --- a/apps/gipy/README.md +++ b/apps/gipy/README.md @@ -109,9 +109,11 @@ Colors correspond to slopes. Few settings for now (feel free to suggest me more) : -- lost distance : at which distance from path are you considered to be lost ? - buzz on turns : should the watch buzz when reaching a waypoint ? - disable bluetooth : turn bluetooth off completely to try to save some power. +- lost distance : at which distance from path are you considered to be lost ? +- wake-up speed : if you drive below this speed powersaving will disable itself +- active-time : how long (in seconds) the screen should be turned on if activated before going back to sleep. - brightness : how bright should screen be ? (by default 0.5, again saving power) - 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. diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 56137ae58d..46e29c3597 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -26,6 +26,8 @@ let s = require("Storage"); var settings = Object.assign( { lost_distance: 50, + wake_up_speed: 13, + active_time: 10, brightness: 0.5, buzz_on_turns: false, disable_bluetooth: true, @@ -692,7 +694,7 @@ class Status { if (!this.active || !powersaving) { return; } - if (getTime() - this.last_activity > 30) { + if (getTime() - this.last_activity > settings.active_time) { this.active = false; Bangle.setLCDBrightness(0); if (settings.power_lcd_off) { @@ -772,13 +774,13 @@ class Status { if (in_menu) { return; } - if (this.instant_speed * 3.6 < 13) { + if (this.instant_speed * 3.6 < settings.wake_up_speed) { this.activate(); // if we go too slow turn on, we might be looking for the direction to follow if (!this.default_options) { this.default_options = true; Bangle.setOptions({ - lockTimeout: 10000, + lockTimeout: 0, backlightTimeout: 10000, wakeOnTwist: true, powerSave: true, @@ -798,7 +800,6 @@ class Status { wakeOnTouch: true, powerSave: false, }); - Bangle.setPollInterval(2000); // disable accelerometer as much as we can (a value of 4000 seem to cause hard reboot crashes (segfaults ?) so keep 2000) } } this.check_activity(); // if we don't move or are in menu we should stay on @@ -879,8 +880,10 @@ class Status { // }, time_to_next_point); // } // } - if (this.reaching != next_point && this.distance_to_next_point <= 100) { + if (this.distance_to_next_point <= 100) { this.activate(); + } + if (this.reaching != next_point && this.distance_to_next_point <= 100) { this.reaching = next_point; let reaching_waypoint = this.path.is_waypoint(next_point); if (reaching_waypoint) { @@ -1029,8 +1032,8 @@ class Status { let distance_per_pixel = displayed_length / graph_width; let start_point_index = 0; - let end_point_index = this.remaining_distances.length - 1; - for (let i = 0; i < this.remaining_distances.length; i++) { + let end_point_index = this.path.len - 1; + for (let i = 0; i < this.path.len; i++) { let point_distance = path_length - this.remaining_distances[i]; if (point_distance <= display_start) { start_point_index = i; @@ -1040,6 +1043,7 @@ class Status { break; } } + end_point_index = Math.min(end_point_index+1, this.path.len -1); let max_height = Number.NEGATIVE_INFINITY; let min_height = Number.POSITIVE_INFINITY; for (let i = start_point_index; i <= end_point_index; i++) { diff --git a/apps/gipy/settings.js b/apps/gipy/settings.js index 395b1ac936..1b030f5cd5 100644 --- a/apps/gipy/settings.js +++ b/apps/gipy/settings.js @@ -3,6 +3,8 @@ // Load settings var settings = Object.assign({ lost_distance: 50, + wake_up_speed: 13, + active_time: 10, buzz_on_turns: false, disable_bluetooth: true, brightness: 0.5, @@ -44,6 +46,24 @@ writeSettings(); }, }, + "wake-up speed": { + value: settings.wake_up_speed, + min: 0, + max: 30, + onchange: (v) => { + settings.wake_up_speed = v; + writeSettings(); + }, + }, + "active time": { + value: settings.active_time, + min: 5, + max: 60, + onchange: (v) => { + settings.active_time = v; + writeSettings(); + }, + }, "brightness": { value: settings.brightness, min: 0, From 30de2cc6b2e9bc2f1fa268f1d3352c3f7f3b0723 Mon Sep 17 00:00:00 2001 From: frederic wagner Date: Thu, 31 Aug 2023 09:32:55 +0200 Subject: [PATCH 11/12] gipy: documentation update --- apps/gipy/README.md | 36 +++++++++++++++++++++++++++++++++--- apps/gipy/metadata.json | 2 +- apps/gipy/shot.png | Bin 0 -> 4703 bytes 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 apps/gipy/shot.png diff --git a/apps/gipy/README.md b/apps/gipy/README.md index d96461dfe5..f4c68d0270 100644 --- a/apps/gipy/README.md +++ b/apps/gipy/README.md @@ -42,7 +42,7 @@ also a nice open source option. Note that *mapstogpx* has a super nice feature in its advanced settings. You can turn on 'next turn info' and be warned by the watch when you need to turn. -Once you have your gpx file you need to convert it to *gpc* which is my custom file format. +Once you have your gpx file you need to convert it to *gps* which is my custom file format. They are smaller than gpx and reduce the number of computations left to be done on the watch. Just click the disk icon and select your gpx file. @@ -82,8 +82,7 @@ On your screen you can see: ### Lost -If you stray away from path we will rescale the display to continue displaying nearby segments and -display the direction to follow as a purple segment. Your main position will also turn to purple. +If you stray away from path we will display the direction to follow as a purple segment. Your main position will also turn to purple. Note that while lost, the app will slow down a lot since it will start scanning all possible points to figure out where you are. On path it just needed to scan a few points ahead and behind. @@ -104,6 +103,11 @@ for the whole path. ![Screenshot](heights.png) Colors correspond to slopes. +Above 15% will be red, above 8% orange, above 3% yellow, below 3% and -3% is green and shades of blue +are for descents. + +You should note that the precision is not very good. The input data is not very precise and you only get the +slopes between path points. Don't expect to see small bumps on the road. ### Settings @@ -118,6 +122,32 @@ 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, when you touch the screen and when speed is below 13km/h. +### Powersaving + +Starting with release 0.20 we experiment with power saving. + +There are now two display modes : + +- active : the screen is lit back (default at 50% light but can be configured with the *brightness* setting) +- inactive : by default the screen is not lit but you can also power it off completely (with the *power lcd off* setting) + +The algorithm works in the following ways : + +- some events will *activate* : the display will turn *active* +- if no activation event occur for at least 10 seconds (or *active-time* setting) we switch back to *inactive* + +Activation events are the following : + +- you are near (< 100m) the next point on path +- you are slow (< *wake-up speed* setting (13 km/h by default)) +- you press the button / touch the screen + + +Power saving has been tested on a very long trip with several benefits + +- longer battery life +- waking up near path points will attract your attention more easily when needed + ### Caveats It is good to use but you should know : diff --git a/apps/gipy/metadata.json b/apps/gipy/metadata.json index 3526e1afa5..d6b5e1405d 100644 --- a/apps/gipy/metadata.json +++ b/apps/gipy/metadata.json @@ -8,7 +8,7 @@ "icon": "gipy.png", "type": "app", "tags": "tool,outdoors,gps", - "screenshots": [{"url":"splash.png"}], + "screenshots": [{"url":"splash.png"}, {"url":"heights.png"}, {"url":"shot.png"}], "supports": ["BANGLEJS2"], "readme": "README.md", "interface": "interface.html", diff --git a/apps/gipy/shot.png b/apps/gipy/shot.png new file mode 100644 index 0000000000000000000000000000000000000000..c2ffea7241be4305f60e338965c3a4f78131cbad GIT binary patch literal 4703 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 hxtE Date: Thu, 31 Aug 2023 10:36:02 +0200 Subject: [PATCH 12/12] gipy: typo fix --- apps/gipy/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/gipy/README.md b/apps/gipy/README.md index f4c68d0270..8539167e1c 100644 --- a/apps/gipy/README.md +++ b/apps/gipy/README.md @@ -103,7 +103,7 @@ for the whole path. ![Screenshot](heights.png) Colors correspond to slopes. -Above 15% will be red, above 8% orange, above 3% yellow, below 3% and -3% is green and shades of blue +Above 15% will be red, above 8% orange, above 3% yellow, between 3% and -3% is green and shades of blue are for descents. You should note that the precision is not very good. The input data is not very precise and you only get the