use std::str::FromStr; use common::test_events; use s2::cellid::CellID; use xpin::Error; use xpin::{Address, CELLID_LEVEL}; #[macro_use] mod common; use common::approx_geodetic_difference_m; use common::ALLOWED_DISTANCE_ERROR_M; use common::CELLID_LEVEL_23_BITMASK; use common::CELLID_LEVEL_23_END_BIT; #[test] fn test_invalid_lat_lon() { // Latitudes/longitudes are wrapped, so this is okay assert!(Address::from_lat_lon(1.0_f64, 400.0_f64).is_ok()); assert_eq!( Address::from_lat_lon(f64::INFINITY, 400.0_f64), Err(Error::NaNLatLng) ); assert_eq!( Address::from_lat_lon(1.0_f64, f64::NAN), Err(Error::NaNLatLng) ); } #[test] fn test_decoding_lat_lon() { let mut max_error_m = f64::MIN; let mut min_error_m = f64::MAX; for (idx, entry) in test_events().iter().enumerate() { eprintln!("Testing row {idx}"); let addr = Address::from_lat_lon(entry.lat, entry.lon).unwrap(); let addr_latlon = addr.as_lat_lon(); // The difference between the input lat/lon and the encoded-then-decoded lat/lon // This distance is essentially the error // If you pick a point on the map, this is how far off the encoded point actually represents let difference_m = approx_geodetic_difference_m(addr_latlon, (entry.lat, entry.lon)); // Compute the max and min differences for fun if difference_m > max_error_m { eprintln!("Setting max to {difference_m}"); max_error_m = difference_m; } if difference_m < min_error_m { min_error_m = difference_m; } eprintln!("Distance in meters: {:?}", difference_m); // Ensure the distance is not more than the allowed distance assert!(difference_m <= ALLOWED_DISTANCE_ERROR_M); // assert_eq!((entry.lat, entry.lon), (latlon.0, latlon.1)); } eprintln!("Got max: {max_error_m} and min: {min_error_m}"); } #[test] fn test_cellid_translation() { for (idx, entry) in test_events().iter().enumerate() { eprintln!("Testing row {idx}"); let addr = Address::from_lat_lon(entry.lat, entry.lon).unwrap(); let addr_cellid = addr.as_cellid(); eprintln!( "Entry: ({},{}) => {:0>64b}", entry.lat, entry.lon, entry.cellid ); eprintln!("\taddr: {addr}"); // Make sure the rust s2 implementation is accurate assert_eq!(entry.cellid, CellID(entry.cellid).0); assert_eq!( (entry.cellid & CELLID_LEVEL_23_BITMASK) | CELLID_LEVEL_23_END_BIT, CellID(entry.cellid).parent(CELLID_LEVEL).0 ); // Make sure the address is at the right level assert_eq!(addr_cellid.level(), CELLID_LEVEL); // Next, check if creating an address from a cellid matches itself assert_eq!(addr, Address::from_cellid_u64(entry.cellid)); assert_eq!( addr_cellid, Address::from_cellid_u64(entry.cellid).as_cellid() ); // Now check if the actual cell id matches assert_eq_u64!(addr_cellid.0, CellID(entry.cellid).parent(CELLID_LEVEL).0); } } #[test] fn test_encoding() { for (_idx, entry) in test_events().iter().enumerate() { let addr = Address::from_lat_lon(entry.lat, entry.lon).unwrap(); eprintln!("({}, {}) => {addr}", entry.lat, entry.lon); } // TODO: // assert!(false); } #[test] fn test_decoding() {}