use std::fmt::Debug;
use std::hash::Hash;
#[cfg(feature = "gpu")]
use std::sync::Arc;
#[cfg(feature = "gpu")]
use crate::data::Name;
#[cfg(feature = "gpu")]
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Tiles {
pub(crate) name: Name,
pub(crate) url: Arc<str>,
}
#[cfg(feature = "gpu")]
impl Tiles {
pub fn new(name: impl Into<Name>, url: impl Into<Arc<str>>) -> Tiles {
Tiles { name: name.into(), url: url.into() }
}
pub fn name(&self) -> &Name {
&self.name
}
pub fn url(&self) -> &str {
&self.url
}
}
pub(crate) const ARCHIVE_FIRST: u64 = 16_384;
pub(crate) trait Key: Copy + Eq + Hash + Ord + Debug {
fn parent(self) -> Option<Self>;
}
pub(crate) fn ancestry<K: Key>(key: K) -> impl Iterator<Item = K> {
std::iter::successors(Some(key), |k| k.parent())
}
impl Key for TileKey {
fn parent(self) -> Option<TileKey> {
(self.z > 0).then(|| self.ancestor(1))
}
}
#[cfg(feature = "gpu")]
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub(crate) struct Span {
pub(crate) level: u8,
pub(crate) index: u64,
}
#[cfg(feature = "gpu")]
impl Key for Span {
fn parent(self) -> Option<Span> {
(u32::from(self.level) < crate::data::MAX_LEVEL).then(|| Span { level: self.level + 1, index: self.index / 8 })
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub(crate) struct TileKey {
pub(crate) z: u8,
pub(crate) x: u32,
pub(crate) y: u32,
}
impl TileKey {
pub(crate) fn bounds(self) -> [f64; 4] {
let n = f64::from(1_u32 << self.z);
let latitude = |t: f64| (std::f64::consts::PI * (1.0 - 2.0 * t)).sinh().atan().to_degrees();
let (x, y) = (f64::from(self.x), f64::from(self.y));
[x / n * 360.0 - 180.0, latitude((y + 1.0) / n), (x + 1.0) / n * 360.0 - 180.0, latitude(y / n)]
}
pub(crate) fn ancestor(self, levels: u8) -> TileKey {
TileKey { z: self.z - levels, x: self.x >> levels, y: self.y >> levels }
}
pub(crate) fn children(self) -> [TileKey; 4] {
let (z, x, y) = (self.z + 1, self.x * 2, self.y * 2);
[TileKey { z, x, y }, TileKey { z, x: x + 1, y }, TileKey { z, x, y: y + 1 }, TileKey { z, x: x + 1, y: y + 1 }]
}
}