aboutsummaryrefslogtreecommitdiff
path: root/src/renderer.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2023-01-12 23:59:46 +0100
committerDaniel Schadt <kingdread@gmx.de>2023-01-12 23:59:46 +0100
commit7bbba155f10ce1344724ea00ca70c4d3bb469272 (patch)
treea370a39a8ad226e27bc1c4f3957c993ed17ad816 /src/renderer.rs
parentdef44c6e969f1027da82e4130a82db7e4916ba86 (diff)
downloadhittekaart-7bbba155f10ce1344724ea00ca70c4d3bb469272.tar.gz
hittekaart-7bbba155f10ce1344724ea00ca70c4d3bb469272.tar.bz2
hittekaart-7bbba155f10ce1344724ea00ca70c4d3bb469272.zip
parallelize PNG encoding
This gives a massive speedup
Diffstat (limited to 'src/renderer.rs')
-rw-r--r--src/renderer.rs40
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());