//! Bridge from route-layer geometry to the standard's address space. use map_index::volume::TimeTier; use map_schema::{CellKey, Lod, TimeBucket}; use crate::Coordinate; /// The [`CellKey`] for a WGS84 coordinate at a horizontal `level`. Uses the /// coordinate's altitude (if any) for the band, and an atemporal time bucket /// (use [`coordinate_cell_key_at`] for a timestamped observation). pub fn coordinate_cell_key(coord: &Coordinate, level: u8) -> CellKey { map_index::cell_key( coord.lat, coord.lng, level, map_index::alt_band(coord.altitude.unwrap_or(0.0)), TimeBucket::ATEMPORAL, Lod(0), ) } /// The [`CellKey`] for a coordinate observed at `time_secs` (epoch seconds) at /// the given time `tier`. pub fn coordinate_cell_key_at(coord: &Coordinate, level: u8, time_secs: i64, tier: TimeTier) -> CellKey { map_index::cell_key( coord.lat, coord.lng, level, map_index::alt_band(coord.altitude.unwrap_or(0.0)), map_index::time_bucket(time_secs, tier), Lod(0), ) } #[cfg(test)] mod tests { use super::*; #[test] fn surface_coordinate_maps_to_band_zero() { let c = Coordinate::new(37.7749, -122.4194); let k = coordinate_cell_key(&c, 14); assert_eq!(k.alt, map_schema::AltBand(0)); assert_eq!(k.s2.level(), Some(14)); assert!(k.time.is_atemporal()); } #[test] fn timestamped_coordinate_gets_time_bucket() { let c = Coordinate::new(0.0, 0.0); let k = coordinate_cell_key_at(&c, 10, 3_600 + 5, TimeTier::Recent); assert_eq!(k.time.width_ms, 3_600_000); assert_eq!(k.time.start_tai_ms, 3_600_000); } }