diff options
Diffstat (limited to 'hittekaart/src/renderer/marktile.rs')
-rw-r--r-- | hittekaart/src/renderer/marktile.rs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/hittekaart/src/renderer/marktile.rs b/hittekaart/src/renderer/marktile.rs new file mode 100644 index 0000000..3523e69 --- /dev/null +++ b/hittekaart/src/renderer/marktile.rs @@ -0,0 +1,65 @@ +//! 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 crossbeam_channel::Sender; +use fnv::FnvHashSet; + +use super::{ + super::{ + error::Result, + 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<Coordinates>], + tick: Sender<()>, + ) -> Result<Self::Prepared> { + 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<RenderedTile>) -> Result<()> { + // The tile is hand-crafted to be very small. See + // <https://www.mjt.me.uk/posts/smallest-png/> for a reference, and of course the actual + // PNG specification <http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html>. + 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<u64> { + Ok(layer.len().try_into().unwrap()) + } +} |