diff options
Diffstat (limited to 'src/renderer.rs')
-rw-r--r-- | src/renderer.rs | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/renderer.rs b/src/renderer.rs index cece8f3..2f29828 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -3,6 +3,7 @@ use std::{fs, path::Path}; use color_eyre::eyre::{bail, Result}; use image::{ImageBuffer, Luma, Pixel, RgbaImage}; use nalgebra::{vector, Vector2}; +use rayon::iter::ParallelIterator; use super::{ gpx::Coordinates, @@ -131,10 +132,10 @@ fn colorize_tile(tile: &ImageBuffer<Luma<u8>, Vec<u8>>, max: u32) -> RgbaImage { /// rendering the next one. /// /// This has a way lower memory usage than [`colorize_heatcounter`]. -pub fn lazy_colorization<P: AsRef<Path>, F: FnMut(usize)>( - layer: &HeatCounter, +pub fn lazy_colorization<P: AsRef<Path>, F: Fn(usize) + Send + Sync>( + layer: HeatCounter, base_dir: P, - mut progress_callback: F, + progress_callback: F, ) -> Result<()> { let base_dir = base_dir.as_ref(); let max = layer.pixels().map(|l| l.0[0]).max().unwrap_or_default(); @@ -142,27 +143,30 @@ pub fn lazy_colorization<P: AsRef<Path>, F: FnMut(usize)>( return Ok(()); } - for (tile_x, tile_y, tile) in layer.enumerate_tiles() { - let colorized = colorize_tile(tile, max.into()); - let folder = base_dir.join(tile_x.to_string()); - let metadata = folder.metadata(); - match metadata { - Err(_) => fs::create_dir(&folder)?, - Ok(m) if !m.is_dir() => bail!("Output path is not a directory"), - _ => {} - } - let file = folder.join(format!("{tile_y}.png")); - layer::compress_png(&colorized, file)?; - progress_callback(1); - } + layer + .into_parallel_tiles() + .try_for_each(|(tile_x, tile_y, tile)| { + let colorized = colorize_tile(&tile, max.into()); + let folder = base_dir.join(tile_x.to_string()); + let metadata = folder.metadata(); + match metadata { + Err(_) => fs::create_dir_all(&folder)?, + Ok(m) if !m.is_dir() => bail!("Output path is not a directory"), + _ => {} + } + let file = folder.join(format!("{tile_y}.png")); + layer::compress_png(&colorized, file)?; + progress_callback(1); + Ok(()) + })?; Ok(()) } /// Renders the heat counter for the given zoom level and track points. -pub fn render_heatcounter<F: FnMut(usize)>( +pub fn render_heatcounter<F: Fn(usize) + Send + Sync>( zoom: u32, tracks: &[Vec<Coordinates>], - mut progress_callback: F, + progress_callback: F, ) -> HeatCounter { let mut heatcounter = TileLayer::from_pixel([0].into()); |