mirror of https://github.com/espruino/BangleApps
another non working waypoints detection algorithm
parent
cb4ee0d8e9
commit
e022f5894f
|
@ -14,26 +14,38 @@ use osm::{parse_osm_data, InterestPoint};
|
|||
const KEY: u16 = 47490;
|
||||
const FILE_VERSION: u16 = 3;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Point {
|
||||
x: f64,
|
||||
y: f64,
|
||||
}
|
||||
|
||||
impl PartialEq for Point {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(self.x - other.x).abs() < 0.0005 && (self.y - other.y).abs() < 0.0005
|
||||
}
|
||||
}
|
||||
impl Eq for Point {}
|
||||
impl std::hash::Hash for Point {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let x = format!("{:.4}", self.x);
|
||||
let y = format!("{:.4}", self.y);
|
||||
unsafe { std::mem::transmute::<f64, u64>(self.x) }.hash(state);
|
||||
unsafe { std::mem::transmute::<f64, u64>(self.y) }.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct APoint {
|
||||
x: f64,
|
||||
y: f64,
|
||||
}
|
||||
|
||||
impl PartialEq for APoint {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(self.x - other.x).abs() < 0.00005 && (self.y - other.y).abs() < 0.00005
|
||||
}
|
||||
}
|
||||
impl Eq for APoint {}
|
||||
impl std::hash::Hash for APoint {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
let x = format!("{:.5}", self.x);
|
||||
let y = format!("{:.5}", self.y);
|
||||
x.hash(state);
|
||||
y.hash(state);
|
||||
// unsafe { std::mem::transmute::<f64, u64>(self.x) }.hash(state);
|
||||
// unsafe { std::mem::transmute::<f64, u64>(self.y) }.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,7 +591,7 @@ fn save_svg<'a, P: AsRef<Path>, I: IntoIterator<Item = &'a InterestPoint>>(
|
|||
|
||||
fn detect_waypoints(
|
||||
points: &[Point],
|
||||
osm_waypoints: &HashMap<Point, Vec<ObjId>>,
|
||||
osm_waypoints: &HashMap<APoint, Vec<ObjId>>,
|
||||
) -> HashSet<Point> {
|
||||
points
|
||||
.first()
|
||||
|
@ -588,24 +600,26 @@ fn detect_waypoints(
|
|||
points
|
||||
.iter()
|
||||
.filter_map(|p: &Point| -> Option<(&Point, &Vec<ObjId>)> {
|
||||
osm_waypoints.get(p).map(|l| (p, l))
|
||||
osm_waypoints
|
||||
.get(&APoint { x: p.x, y: p.y })
|
||||
.map(|l| (p, l))
|
||||
})
|
||||
.tuple_windows()
|
||||
.filter_map(|((p1, l1), (p2, _), (p3, l2))| {
|
||||
if l1.iter().all(|e| !l2.contains(e)) {
|
||||
let x1 = p2.x - p1.x;
|
||||
let y1 = p2.y - p1.y;
|
||||
let a1 = y1.atan2(x1);
|
||||
let x2 = p3.x - p2.x;
|
||||
let y2 = p3.y - p2.y;
|
||||
let a2 = y2.atan2(x2);
|
||||
let a = (a2 - a1).abs();
|
||||
if a <= std::f64::consts::PI / 4.0 || a >= std::f64::consts::PI * 7.0 / 4.0
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(p2)
|
||||
}
|
||||
// let x1 = p2.x - p1.x;
|
||||
// let y1 = p2.y - p1.y;
|
||||
// let a1 = y1.atan2(x1);
|
||||
// let x2 = p3.x - p2.x;
|
||||
// let y2 = p3.y - p2.y;
|
||||
// let a2 = y2.atan2(x2);
|
||||
// let a = (a2 - a1).abs();
|
||||
// if a <= std::f64::consts::PI / 4.0 || a >= std::f64::consts::PI * 7.0 / 4.0
|
||||
// {
|
||||
// None
|
||||
// } else {
|
||||
Some(p2)
|
||||
// }
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::Point;
|
||||
use super::{APoint, Point};
|
||||
use itertools::Itertools;
|
||||
use lazy_static::lazy_static;
|
||||
use openstreetmap_api::{
|
||||
|
@ -150,10 +150,12 @@ async fn get_openstreetmap_data(points: &[(f64, f64)]) -> HashSet<InterestPoint>
|
|||
interest_points
|
||||
}
|
||||
|
||||
pub fn parse_osm_data<P: AsRef<Path>>(path: P) -> (Vec<InterestPoint>, HashMap<Point, Vec<ObjId>>) {
|
||||
pub fn parse_osm_data<P: AsRef<Path>>(
|
||||
path: P,
|
||||
) -> (Vec<InterestPoint>, HashMap<APoint, Vec<ObjId>>) {
|
||||
let reader = osmio::read_pbf(path).ok();
|
||||
let mut crossroads: HashMap<ObjId, Vec<ObjId>> = HashMap::new();
|
||||
let mut coordinates: HashMap<ObjId, Point> = HashMap::new();
|
||||
let mut coordinates: HashMap<ObjId, APoint> = HashMap::new();
|
||||
let interests = reader
|
||||
.map(|mut reader| {
|
||||
let mut interests = Vec::new();
|
||||
|
@ -169,7 +171,7 @@ pub fn parse_osm_data<P: AsRef<Path>>(path: P) -> (Vec<InterestPoint>, HashMap<P
|
|||
}) {
|
||||
interests.push(p);
|
||||
}
|
||||
coordinates.insert(n.id(), Point { x: lon, y: lat });
|
||||
coordinates.insert(n.id(), APoint { x: lon, y: lat });
|
||||
});
|
||||
}
|
||||
osmio::obj_types::ArcOSMObj::Way(w) => {
|
||||
|
@ -185,12 +187,12 @@ pub fn parse_osm_data<P: AsRef<Path>>(path: P) -> (Vec<InterestPoint>, HashMap<P
|
|||
interests
|
||||
})
|
||||
.unwrap_or_default();
|
||||
(
|
||||
interests,
|
||||
crossroads
|
||||
.into_iter()
|
||||
.filter(|(_, r)| r.len() >= 2)
|
||||
.filter_map(|(id, l)| coordinates.get(&id).copied().map(|c| (c, l)))
|
||||
.collect(),
|
||||
)
|
||||
|
||||
let mut osm_waypoints: HashMap<APoint, Vec<ObjId>> = HashMap::new();
|
||||
for (node_id, ways) in crossroads.into_iter().filter(|(_, r)| r.len() >= 2) {
|
||||
if let Some(c) = coordinates.get(&node_id).copied() {
|
||||
osm_waypoints.entry(c).or_default().extend(ways)
|
||||
}
|
||||
}
|
||||
(interests, osm_waypoints)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue