49 lines
1.6 KiB
Rust
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);
|
|
}
|
|
}
|