//! 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 color_eyre::eyre::Result; use crossbeam_channel::Sender; use fnv::FnvHashSet; use super::{ super::{ gpx::Coordinates, layer::{TILE_HEIGHT, TILE_WIDTH}, }, RenderedTile, }; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Renderer; impl super::Renderer for Renderer { type Prepared = FnvHashSet<(u64, u64)>; fn prepare( &self, zoom: u32, tracks: &[Vec], tick: Sender<()>, ) -> Result { let mut marked = FnvHashSet::default(); for track in tracks { for point in track { let merc = point.web_mercator(zoom); let tile_x = merc.0 / TILE_WIDTH; let tile_y = merc.1 / TILE_HEIGHT; marked.insert((tile_x, tile_y)); } tick.send(()).unwrap(); } Ok(marked) } fn colorize(&self, layer: Self::Prepared, tx: Sender) -> Result<()> { // The tile is hand-crafted to be very small. See // for a reference, and of course the actual // PNG specification . static IMAGE_DATA: &[u8] = include_bytes!("tile-marked.png"); for (tile_x, tile_y) in layer { tx.send(RenderedTile { x: tile_x, y: tile_y, data: IMAGE_DATA.to_vec(), })?; } Ok(()) } fn tile_count(&self, layer: &Self::Prepared) -> Result { Ok(layer.len().try_into().unwrap()) } }