this_algorithm/src/conversions.rs
2023-03-21 23:22:29 -04:00

49 lines
1.6 KiB
Rust

mod wrap;
use std::ops::RangeInclusive;
use s2::{cellid::CellID, latlng::LatLng};
use words::Word;
pub(crate) const TWELVE_BITS: u64 = 0b1111_1111_1111;
pub(crate) const THIRTEEN_BITS: u64 = 0b1_1111_1111_1111;
use crate::Error;
pub fn lat_lon_to_cellid(lat: f64, lon: f64) -> Result<CellID, Error> {
// Wrap the latitudes and longitudes
let (lat, lon) = wrap::wrap_latlon(lat, lon);
if !lat.is_finite() || !lon.is_finite() {
return Err(Error::NaNLatLng);
}
Ok(CellID::from(LatLng::from_degrees(lat, lon)))
}
pub fn extract_binary(number: u64, range: RangeInclusive<usize>) -> u64 {
(number >> range.start()) & (u64::MAX >> (63 - (range.end() - range.start())))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_binary() {
assert_eq!(extract_binary(0b0, 0..=0), 0b0);
assert_eq!(extract_binary(0b11_1111_11, 2..=5), 0b1111);
assert_eq!(extract_binary(0b11_0101_11, 2..=5), 0b0101);
assert_eq!(extract_binary(0b11_1100_11, 2..=5), 0b1100);
assert_eq!(extract_binary(0b111_10011_, 0..=4), 0b10011);
assert_eq!(extract_binary(0b111100_1_1, 1..=1), 0b1);
assert_eq!(extract_binary(0b111100_0_1, 1..=1), 0b0);
// A full test from the docs
let cellid = 0b0100101110101000_1011100010010011_1001001100100100_1100000000000000_u64;
assert_eq!(extract_binary(cellid, 15..=24), 0b10_01001001);
assert_eq!(extract_binary(cellid, 25..=37), 0b01001_11001001);
assert_eq!(extract_binary(cellid, 38..=50), 0b00010_11100010);
assert_eq!(extract_binary(cellid, 51..=63), 0b01001_01110101);
}
}