diff --git a/apps/gipy/gpconv/src/main.rs b/apps/gipy/gpconv/src/main.rs index 6794b5c2e..2b463d312 100644 --- a/apps/gipy/gpconv/src/main.rs +++ b/apps/gipy/gpconv/src/main.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use osmio::ObjId; use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{BufReader, BufWriter, Write}; @@ -549,7 +550,7 @@ fn save_svg<'a, P: AsRef, I: IntoIterator>( waypoints.iter().try_for_each(|p| { writeln!( &mut writer, - "", + "", p.x, p.y, ) })?; @@ -558,27 +559,40 @@ fn save_svg<'a, P: AsRef, I: IntoIterator>( Ok(()) } -fn detect_waypoints(points: &[Point], osm_waypoints: &HashSet) -> HashSet { +fn detect_waypoints( + points: &[Point], + osm_waypoints: &HashMap>, +) -> HashSet { points .first() .into_iter() - .chain(points.iter().tuple_windows().filter_map(|(p1, p2, p3)| { - if !osm_waypoints.contains(&p2) { - return None; - } - 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 / 3.0 || a >= std::f64::consts::PI * 5.0 / 3.0 { - None - } else { - Some(p2) - } - })) + .chain( + points + .iter() + .filter_map(|p: &Point| -> Option<(&Point, &Vec)> { + osm_waypoints.get(p).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) + } + } else { + None + } + }), + ) .chain(points.last().into_iter()) .copied() .collect::>() @@ -640,19 +654,20 @@ fn position_interests_along_path( async fn main() { let input_file = std::env::args().nth(1).unwrap_or("m.gpx".to_string()); let osm_file = std::env::args().nth(2); - eprintln!("input is {}", input_file); - let p = points(&input_file); - - eprintln!("initialy we have {} points", p.len()); - let rp = simplify_path(&p, 0.00015); - eprintln!("we now have {} points", rp.len()); let (mut interests, osm_waypoints) = if let Some(osm) = osm_file { parse_osm_data(osm) } else { - (Vec::new(), HashSet::new()) + (Vec::new(), HashMap::new()) }; + eprintln!("input is {}", input_file); + let p = points(&input_file); + eprintln!("initialy we have {} points", p.len()); + + let rp = simplify_path(&p, 0.00015); + eprintln!("we now have {} points", rp.len()); + let waypoints = detect_waypoints(&rp, &osm_waypoints); eprintln!("we found {} waypoints", waypoints.len()); diff --git a/apps/gipy/gpconv/src/osm.rs b/apps/gipy/gpconv/src/osm.rs index a862a3638..69e417b23 100644 --- a/apps/gipy/gpconv/src/osm.rs +++ b/apps/gipy/gpconv/src/osm.rs @@ -150,9 +150,9 @@ async fn get_openstreetmap_data(points: &[(f64, f64)]) -> HashSet interest_points } -pub fn parse_osm_data>(path: P) -> (Vec, HashSet) { +pub fn parse_osm_data>(path: P) -> (Vec, HashMap>) { let reader = osmio::read_pbf(path).ok(); - let mut crossroads: HashMap = HashMap::new(); + let mut crossroads: HashMap> = HashMap::new(); let mut coordinates: HashMap = HashMap::new(); let interests = reader .map(|mut reader| { @@ -175,7 +175,7 @@ pub fn parse_osm_data>(path: P) -> (Vec, HashSet

{ if !w.is_area() { for node in w.nodes() { - *crossroads.entry(*node).or_default() += 1; + crossroads.entry(*node).or_default().push(w.id()); } } } @@ -188,9 +188,9 @@ pub fn parse_osm_data>(path: P) -> (Vec, HashSet

= 3) - .filter_map(|(id, _)| coordinates.get(&id).copied()) + .into_iter() + .filter(|(_, r)| r.len() >= 2) + .filter_map(|(id, l)| coordinates.get(&id).copied().map(|c| (c, l))) .collect(), ) }