aboutsummaryrefslogtreecommitdiff
path: root/src/renderer/marktile.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2023-03-13 22:08:48 +0100
committerDaniel Schadt <kingdread@gmx.de>2023-03-13 22:08:48 +0100
commit3e694d68a685b6e22d6ab59f34090e4681849ebc (patch)
tree0e9d817d38d8d3524b459c5e8ebe4c55876e322b /src/renderer/marktile.rs
parent3bec9ff1bcb7fb8b93693c0c93b8d42797f95e1c (diff)
downloadhittekaart-3e694d68a685b6e22d6ab59f34090e4681849ebc.tar.gz
hittekaart-3e694d68a685b6e22d6ab59f34090e4681849ebc.tar.bz2
hittekaart-3e694d68a685b6e22d6ab59f34090e4681849ebc.zip
implement "proper" tile hunter mode
Now with fixed zoom level for the hunting.
Diffstat (limited to 'src/renderer/marktile.rs')
-rw-r--r--src/renderer/marktile.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/renderer/marktile.rs b/src/renderer/marktile.rs
new file mode 100644
index 0000000..1e3020f
--- /dev/null
+++ b/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 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<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())
+ }
+}