#![allow(dead_code)] use geoutils::Location; use std::fs::File; use csv::ReaderBuilder; use serde::{Deserialize, Serialize}; /// The allowed error for encoding and decoding points, in meters /// /// Due to the selected S2 level being 23, our error is expected to be under 2 meters /// /// With the encoding I selected, the max difference of my sample data actually fits in under 1 meter! pub const ALLOWED_DISTANCE_ERROR_M: f64 = 1.0_f64; // The earth's approximate latitude circumfrence pub const EARTH_CIRCUMFERENCE_LAT: f64 = 0.0_f64; // The earth's approximate longitude circumfrence pub const EARTH_CIRCUMFERENCE_LON: f64 = 0.0_f64; /// Bitmask to preserve all data bits at level 23 pub const CELLID_LEVEL_23_BITMASK: u64 = 0b11111111_11111111_11111111_11111111_11111111_11111111_10000000_00000000; /// The single 1 bit at the end of level 23 pub const CELLID_LEVEL_23_END_BIT: u64 = 0b00000000_00000000_00000000_00000000_00000000_00000000_01000000_00000000; #[macro_export] macro_rules! assert_eq_u64 { ($a:expr, $b:expr) => {{ let are_equal = $a == $b; let diff = $a ^ $b; eprintln!("Comparing u64:"); let a_txt = format!("{:0>64b}", $a).replace('0', " "); let b_txt = format!("{:0>64b}", $b).replace('0', " "); let diff_txt = if diff == 0 { String::from("NONE") } else { format!("{:0>64b}", diff) .replace('0', " ") .replace('1', "~") }; eprintln!("\t.{a_txt}."); eprintln!("\t.{b_txt}."); eprintln!("Diff:\t.{diff_txt}."); eprintln!("\t | | | | | | | |"); eprintln!("\t 63 52 48 40 32 28 16 0"); assert!(are_equal); }}; } /// Get a Vec of test entries pub fn test_events() -> Vec { ReaderBuilder::new() .from_reader(File::open("./test-data/01-sample-latlon-s2cpp-cellid.csv").unwrap()) .deserialize() .collect::, _>>() .unwrap() } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct TestEntry { pub lat: f64, pub lon: f64, pub cellid: u64, } /// Gets the approximate geodetic difference in meters between two latlons in meters pub fn approx_geodetic_difference_m((lat1, lon1): (f64, f64), (lat2, lon2): (f64, f64)) -> f64 { Location::new(lat1, lon1) .distance_to(&Location::new(lat2, lon2)) .unwrap() .meters() }