diff --git a/README.md b/README.md index 719631d..738a02d 100644 --- a/README.md +++ b/README.md @@ -418,6 +418,9 @@ tokio::spawn(async move { RoutingProgress::ComputingMatrix { percent, row, total } => { println!("[{:3}%] Computing matrix row {}/{}", percent, row, total); } + RoutingProgress::Complete => { + println!("[100%] Done"); + } _ => {} } } @@ -437,7 +440,6 @@ let matrix = network.compute_matrix(&locations, Some(&tx)).await; | `BuildingGraph { percent }` | Building routing graph | | `ComputingMatrix { percent, row, total }` | Computing travel time matrix | | `ComputingGeometries { percent, pair, total }` | Computing route geometries | -| `EncodingGeometries { percent }` | Encoding geometries to polylines | | `Complete` | Operation finished | --- diff --git a/src/routing/fetch.rs b/src/routing/fetch.rs index 8f6a07c..3d4f2f1 100644 --- a/src/routing/fetch.rs +++ b/src/routing/fetch.rs @@ -191,6 +191,7 @@ out body;"#, let _ = tx .send(RoutingProgress::BuildingGraph { percent: 50 }) .await; + let _ = tx.send(RoutingProgress::Complete).await; } Ok(network) @@ -557,13 +558,6 @@ fn is_retryable_error(error: &reqwest::Error) -> bool { error.is_timeout() || error.is_connect() || error.is_request() } -impl RoadNetwork { - #[doc(hidden)] - pub async fn load_or_fetch_simple(bbox: &BoundingBox) -> Result { - Self::load_or_fetch(bbox, &NetworkConfig::default(), None).await - } -} - async fn acquire_in_flight_slot(cache_key: &str) -> (Arc>, OwnedMutexGuard<()>) { let slot = { let mut in_flight = in_flight_loads().lock().await; diff --git a/src/routing/matrix.rs b/src/routing/matrix.rs index cb1b9fc..1e84204 100644 --- a/src/routing/matrix.rs +++ b/src/routing/matrix.rs @@ -2,7 +2,7 @@ use rayon::prelude::*; use std::collections::HashMap; -use tokio::sync::mpsc::Sender; +use tokio::sync::mpsc::{self, Sender}; use super::algo::dijkstra; use super::coord::Coord; @@ -195,8 +195,29 @@ impl RoadNetwork { }) .collect(); + let row_progress = progress.map(|tx| { + let (progress_tx, mut progress_rx) = mpsc::unbounded_channel::(); + let tx = tx.clone(); + let handle = tokio::spawn(async move { + let mut completed_rows = 0usize; + while progress_rx.recv().await.is_some() { + completed_rows += 1; + let percent = 55 + ((completed_rows * 44) / n.max(1)) as u8; + let _ = tx + .send(RoutingProgress::ComputingMatrix { + percent, + row: completed_rows, + total: n, + }) + .await; + } + }); + (progress_tx, handle) + }); + // Compute rows in parallel via rayon - each row runs Dijkstra from source endpoints let graph = &self.graph; + let progress_tx = row_progress.as_ref().map(|(tx, _)| tx.clone()); let rows: Vec> = (0..n) .into_par_iter() .map(|i| { @@ -208,6 +229,9 @@ impl RoadNetwork { *cell = UNREACHABLE; } } + if let Some(tx) = &progress_tx { + let _ = tx.send(i); + } return row; }; @@ -230,18 +254,20 @@ impl RoadNetwork { }; } + if let Some(tx) = &progress_tx { + let _ = tx.send(i); + } row }) .collect(); + if let Some((progress_tx, handle)) = row_progress { + drop(progress_tx); + let _ = handle.await; + } + if let Some(tx) = progress { - let _ = tx - .send(RoutingProgress::ComputingMatrix { - percent: 80, - row: n, - total: n, - }) - .await; + let _ = tx.send(RoutingProgress::Complete).await; } let data: Vec = rows.into_iter().flatten().collect(); @@ -283,6 +309,10 @@ impl RoadNetwork { } } + if let Some(tx) = progress { + let _ = tx.send(RoutingProgress::Complete).await; + } + geometries } } diff --git a/src/routing/progress.rs b/src/routing/progress.rs index 69e8e36..5ffcc01 100644 --- a/src/routing/progress.rs +++ b/src/routing/progress.rs @@ -30,9 +30,6 @@ pub enum RoutingProgress { pair: usize, total: usize, }, - EncodingGeometries { - percent: u8, - }, Complete, } @@ -45,7 +42,6 @@ impl RoutingProgress { Self::BuildingGraph { percent } => *percent, Self::ComputingMatrix { percent, .. } => *percent, Self::ComputingGeometries { percent, .. } => *percent, - Self::EncodingGeometries { percent } => *percent, Self::Complete => 100, } } @@ -58,7 +54,6 @@ impl RoutingProgress { Self::BuildingGraph { .. } => ("building", "Building routing graph..."), Self::ComputingMatrix { .. } => ("matrix", "Computing travel times..."), Self::ComputingGeometries { .. } => ("geometry", "Computing route geometries..."), - Self::EncodingGeometries { .. } => ("encoding", "Encoding geometries..."), Self::Complete => ("complete", "Ready!"), } }