another non working waypoints detection algorithm

pull/2234/head
frederic wagner 2022-07-26 09:02:52 +02:00
parent cb4ee0d8e9
commit e022f5894f
2 changed files with 53 additions and 37 deletions

View File

@ -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
}

View File

@ -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)
}