use crate::convert::{coord_to_mesh, mesh_to_center};
use crate::types::{Direction, MeshCode};
pub fn neighbor(mesh: MeshCode, direction: Direction) -> Option<MeshCode> {
let center = mesh_to_center(mesh);
let level = mesh.level();
let lat_size = level.lat_size_degrees();
let lon_size = level.lon_size_degrees();
let (dx, dy) = direction.offset();
let new_lat = center.lat() + dy as f64 * lat_size;
let new_lon = center.lon() + dx as f64 * lon_size;
if !(20.0..=46.0).contains(&new_lat) || !(122.0..=154.0).contains(&new_lon) {
return None;
}
let new_coord = crate::types::Coordinate::new_unchecked(new_lat, new_lon);
coord_to_mesh(new_coord, level).ok()
}
pub fn neighbors(mesh: MeshCode) -> Vec<MeshCode> {
Direction::ALL
.iter()
.filter_map(|&dir| neighbor(mesh, dir))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_neighbor_north() {
let mesh = MeshCode::from_str("53393599").unwrap();
let north = neighbor(mesh, Direction::North);
assert!(north.is_some());
}
#[test]
fn test_neighbors() {
let mesh = MeshCode::from_str("53393599").unwrap();
let all_neighbors = neighbors(mesh);
assert!(all_neighbors.len() <= 8);
assert!(all_neighbors.len() > 0);
}
}