diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2025-06-26 22:10:31 +0200 | 
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2025-06-26 22:10:31 +0200 | 
| commit | 99150875308e0cac89f4de2996cfd1954305dcfe (patch) | |
| tree | f19224064543aed367522b05778a992d7385c712 /src/renderer/tilehunt.rs | |
| parent | 6adcd94a6747fe7ec6f1ad1073453636847a0bff (diff) | |
| download | hittekaart-99150875308e0cac89f4de2996cfd1954305dcfe.tar.gz hittekaart-99150875308e0cac89f4de2996cfd1954305dcfe.tar.bz2 hittekaart-99150875308e0cac89f4de2996cfd1954305dcfe.zip  | |
split crate into core and cli
Diffstat (limited to 'src/renderer/tilehunt.rs')
| -rw-r--r-- | src/renderer/tilehunt.rs | 153 | 
1 files changed, 0 insertions, 153 deletions
diff --git a/src/renderer/tilehunt.rs b/src/renderer/tilehunt.rs deleted file mode 100644 index 9081523..0000000 --- a/src/renderer/tilehunt.rs +++ /dev/null @@ -1,153 +0,0 @@ -//! Actual rendering functions for tile hunts. -//! -//! This renders a tile as "transparent green" if any track passes through it. -//! -//! Note that is version of "tile hunt" is a bit silly, as the tile size changes with the zoom -//! level. For a better version, the "tile hunt size" should be fixed to a given zoom. -use std::cmp::Ordering; - -use color_eyre::eyre::Result; -use crossbeam_channel::Sender; -use fnv::{FnvHashMap, FnvHashSet}; -use image::RgbaImage; -use imageproc::{drawing::draw_filled_rect_mut, rect::Rect}; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; - -use super::{ -    super::{ -        gpx::Coordinates, -        layer::{self, TILE_HEIGHT, TILE_WIDTH}, -    }, -    RenderedTile, -}; - -fn render_squares(grid: u32, inner: Vec<(u8, u8)>) -> Result<Vec<u8>> { -    // We re-use the tiny PNG if possible -    static FULL_TILE: &[u8] = include_bytes!("tile-marked.png"); -    if grid == 1 && !inner.is_empty() { -        return Ok(FULL_TILE.to_vec()); -    } -    let mut base = -        RgbaImage::from_pixel(TILE_WIDTH as u32, TILE_HEIGHT as u32, [0, 0, 0, 0].into()); -    let patch_size = TILE_WIDTH as u32 / grid; - -    for (patch_x, patch_y) in inner { -        draw_filled_rect_mut( -            &mut base, -            Rect::at( -                patch_x as i32 * patch_size as i32, -                patch_y as i32 * patch_size as i32, -            ) -            .of_size(patch_size, patch_size), -            [0, 255, 0, 128].into(), -        ); -    } - -    layer::compress_png_as_bytes(&base) -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Renderer(u32); - -impl Renderer { -    pub fn new(hunter_zoom: u32) -> Self { -        Renderer(hunter_zoom) -    } - -    #[inline] -    pub fn hunter_zoom(&self) -> u32 { -        self.0 -    } -} - -impl super::Renderer for Renderer { -    type Prepared = (u32, FnvHashMap<(u64, u64), Vec<(u8, u8)>>); - -    fn prepare( -        &self, -        zoom: u32, -        tracks: &[Vec<Coordinates>], -        tick: Sender<()>, -    ) -> Result<Self::Prepared> { -        let mut marked = FnvHashSet::default(); - -        for track in tracks { -            for point in track { -                let merc = point.web_mercator(self.hunter_zoom()); -                let tile_x = merc.0 / TILE_WIDTH; -                let tile_y = merc.1 / TILE_HEIGHT; -                marked.insert((tile_x, tile_y)); -            } - -            tick.send(()).unwrap(); -        } - -        let scale = i32::try_from(zoom).unwrap() - i32::try_from(self.hunter_zoom()).unwrap(); -        let grid = if scale >= 0 { -            1 -        } else { -            2u64.pow(scale.abs().min(8) as u32) -        }; - -        let mut result = FnvHashMap::<(u64, u64), Vec<(u8, u8)>>::default(); - -        for (tile_x, tile_y) in marked { -            match scale.cmp(&0) { -                Ordering::Equal => -                // The current zoom level is the same as the hunter level, so the tiles have a 1:1 -                // mapping -                { -                    result.entry((tile_x, tile_y)).or_default().push((0u8, 0u8)) -                } -                Ordering::Less => -                // In this case we are "zoomed out" further than the hunter level, so a marked tile -                // has to be scaled down and we need to figure out where in the "big tile" our -                // marked tile is -                { -                    result -                        .entry((tile_x / grid, tile_y / grid)) -                        .or_default() -                        .push(( -                            (tile_x % grid).try_into().unwrap(), -                            (tile_y % grid).try_into().unwrap(), -                        )) -                } -                Ordering::Greater => { -                    // In this case, we are zoomed in more than the hunter level. Each marked tile -                    // expands to multiple tiles. -                    let multiplier = 2u64.pow(scale as u32); -                    for dx in 0..multiplier { -                        for dy in 0..multiplier { -                            result -                                .entry((tile_x * multiplier + dx, tile_y * multiplier + dy)) -                                .or_default() -                                .push((0u8, 0u8)); -                        } -                    } -                } -            } -        } - -        Ok((grid.try_into().unwrap(), result)) -    } - -    fn colorize(&self, layer: Self::Prepared, tx: Sender<RenderedTile>) -> Result<()> { -        let grid = layer.0; -        layer -            .1 -            .into_par_iter() -            .try_for_each_with(tx, |tx, ((tile_x, tile_y), inner)| { -                let data = render_squares(grid, inner)?; -                tx.send(RenderedTile { -                    x: tile_x, -                    y: tile_y, -                    data, -                })?; -                Ok(()) -            }) -    } - -    fn tile_count(&self, layer: &Self::Prepared) -> Result<u64> { -        Ok(layer.1.len().try_into().unwrap()) -    } -}  | 
