forked from FOSS/BangleApps
gipy: v007
parent
f1c204c77a
commit
e6b76cde31
|
@ -10,3 +10,8 @@
|
||||||
* Special display for points with steep turns
|
* Special display for points with steep turns
|
||||||
* Buzz on points with steep turns and unlock
|
* Buzz on points with steep turns and unlock
|
||||||
* Losing gps is now displayed
|
* Losing gps is now displayed
|
||||||
|
|
||||||
|
0.07:
|
||||||
|
* We now use orientation to detect current segment
|
||||||
|
when segments overlap going in both directions.
|
||||||
|
* File format is now versioned.
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
- nearest_segment : use direction to disambiguate
|
|
||||||
- gps direction is weak when speed is low
|
- gps direction is weak when speed is low
|
||||||
- add a version number to gpc files
|
|
||||||
- water points
|
- water points
|
||||||
---> we group them following path by groups of cst_size and record segments ids marking limits
|
---> we group them following path by groups of cst_size and record segments ids marking limits
|
||||||
|
|
||||||
- store several tracks
|
|
||||||
- turn off gps when moving to next waypoint
|
- turn off gps when moving to next waypoint
|
||||||
|
|
||||||
|
- store several tracks
|
||||||
- display average speed
|
- display average speed
|
||||||
- dynamic map rescale
|
- dynamic map rescale
|
||||||
- display scale (100m)
|
- display scale (100m)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
|
||||||
let simulated = false;
|
let simulated = true;
|
||||||
|
let code_version = 7;
|
||||||
|
let code_key = 47490;
|
||||||
|
|
||||||
class Status {
|
class Status {
|
||||||
constructor(path) {
|
constructor(path) {
|
||||||
|
@ -36,11 +38,11 @@ class Status {
|
||||||
this.position = new_position;
|
this.position = new_position;
|
||||||
|
|
||||||
// detect segment we are on now
|
// detect segment we are on now
|
||||||
let next_segment = this.path.nearest_segment(this.position, Math.max(0, this.current_segment-1), Math.min(this.current_segment+2, path.len - 1));
|
let next_segment = this.path.nearest_segment(this.position, Math.max(0, this.current_segment-1), Math.min(this.current_segment+2, path.len - 1), this.cos_direction, this.sin_direction);
|
||||||
|
|
||||||
if (this.is_lost(next_segment)) {
|
if (this.is_lost(next_segment)) {
|
||||||
// it did not work, try anywhere
|
// it did not work, try anywhere
|
||||||
next_segment = this.path.nearest_segment(this.position, 0, path.len - 1);
|
next_segment = this.path.nearest_segment(this.position, 0, path.len - 1, this.cos_direction, this.sin_direction);
|
||||||
}
|
}
|
||||||
// now check if we strayed away from path or back to it
|
// now check if we strayed away from path or back to it
|
||||||
let lost = this.is_lost(next_segment);
|
let lost = this.is_lost(next_segment);
|
||||||
|
@ -147,7 +149,15 @@ class Status {
|
||||||
class Path {
|
class Path {
|
||||||
constructor(filename) {
|
constructor(filename) {
|
||||||
let buffer = require("Storage").readArrayBuffer(filename);
|
let buffer = require("Storage").readArrayBuffer(filename);
|
||||||
this.points = Float64Array(buffer);
|
let header = Uint16Array(buffer, 0, 3);
|
||||||
|
let key = header[0];
|
||||||
|
let version = header[1];
|
||||||
|
let points_number = header[2];
|
||||||
|
if ((key != code_key)||(version>code_version)) {
|
||||||
|
E.showMessage("Invalid gpc file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.points = Float64Array(buffer, 3*2, points_number*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if start, end or steep direction change
|
// if start, end or steep direction change
|
||||||
|
@ -189,18 +199,32 @@ class Path {
|
||||||
return new Point(lon, lat);
|
return new Point(lon, lat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return index of segment which is nearest from point
|
// return index of segment which is nearest from point.
|
||||||
nearest_segment(point, start, end) {
|
// we need a direction because we need there is an ambiguity
|
||||||
let min_index = 0;
|
// for overlapping segments which are taken once to go and once to come back.
|
||||||
let min_distance = Number.MAX_VALUE;
|
// (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];
|
||||||
this.on_segments(function(p1, p2, i) {
|
this.on_segments(function(p1, p2, i) {
|
||||||
|
// we use the dot product to figure out if oriented correctly
|
||||||
let distance = point.fake_distance_to_segment(p1, p2);
|
let distance = point.fake_distance_to_segment(p1, p2);
|
||||||
if (distance <= min_distance) {
|
let diff = p2.minus(p1);
|
||||||
min_distance = distance;
|
let dot = cos_direction * diff.lon + sin_direction * diff.lat;
|
||||||
min_index = i - 1;
|
let orientation = + (dot < 0); // index 0 is good orientation
|
||||||
|
if (distance <= mins[orientation]) {
|
||||||
|
mins[orientation] = distance;
|
||||||
|
indices[orientation] = i - 1;
|
||||||
}
|
}
|
||||||
}, start, end);
|
}, start, end);
|
||||||
return min_index;
|
// by default correct orientation (0) wins
|
||||||
|
// but if other one is really closer, return other one
|
||||||
|
if (mins[1] < mins[0] / 10.0) {
|
||||||
|
return indices[1];
|
||||||
|
} else {
|
||||||
|
return indices[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
get len() {
|
get len() {
|
||||||
return this.points.length / 2;
|
return this.points.length / 2;
|
||||||
|
|
|
@ -10,6 +10,9 @@ use gpx::Gpx;
|
||||||
mod osm;
|
mod osm;
|
||||||
use osm::InterestPoint;
|
use osm::InterestPoint;
|
||||||
|
|
||||||
|
const KEY: u16 = 47490;
|
||||||
|
const VERSION: u16 = 7;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
x: f64,
|
x: f64,
|
||||||
|
@ -328,8 +331,9 @@ fn save_coordinates<P: AsRef<Path>>(path: P, points: &[Point]) -> std::io::Resul
|
||||||
let mut writer = BufWriter::new(File::create(path)?);
|
let mut writer = BufWriter::new(File::create(path)?);
|
||||||
|
|
||||||
eprintln!("saving {} points", points.len());
|
eprintln!("saving {} points", points.len());
|
||||||
// writer.write_all(&xmin.to_be_bytes())?;
|
writer.write_all(&KEY.to_le_bytes())?;
|
||||||
// writer.write_all(&ymin.to_be_bytes())?;
|
writer.write_all(&VERSION.to_le_bytes())?;
|
||||||
|
writer.write_all(&(points.len() as u16).to_le_bytes())?;
|
||||||
points
|
points
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|p| [p.x, p.y])
|
.flat_map(|p| [p.x, p.y])
|
||||||
|
@ -502,7 +506,6 @@ fn detect_waypoints(points: &[Point]) -> HashSet<Point> {
|
||||||
if a <= std::f64::consts::PI / 3.0 || a >= std::f64::consts::PI * 5.0 / 3.0 {
|
if a <= std::f64::consts::PI / 3.0 || a >= std::f64::consts::PI * 5.0 / 3.0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
eprintln!("we have {}", (a2 - a1).abs());
|
|
||||||
Some(p2)
|
Some(p2)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
Loading…
Reference in New Issue