/// Normalize co-ordinates that lie outside of the normal ranges. /// Longitude wrapping simply requires adding +- 360 to the value until it comes into range. /// /// For the latitude values, we need to flip the longitude whenever the latitude crosses a pole. /// /// Description and original source was ported from https://gist.github.com/missinglink/d0a085188a8eab2ca66db385bb7c023a to rust pub fn wrap_latlon(mut lat: f64, mut lon: f64) -> (f64, f64) { let quadrant = ((lat.abs() / 90_f64).floor() % 4_f64) as i8; let pole = if lat > 0_f64 { 90_f64 } else { -90_f64 }; let offset = lat % 90_f64; match quadrant { 0 => { lat = offset; } 1 => { lat = pole - offset; lon += 180_f64 } 2 => { lat = -offset; lon += 180_f64; } 3 => { lat = -pole + offset; } _ => {} } if lon > 180_f64 || lon < -180_f64 { lon -= ((lon + 180_f64) / 360_f64).floor() * 360_f64; } (lat, lon) } #[cfg(test)] mod tests { use super::*; #[test] fn test_control() { // Control - no wrapping required assert_eq!( wrap_latlon(55.555_f64, 22.222_f64), (55.555_f64, 22.222_f64) ); } #[test] fn test_latitude_positive() { // Positive latitude wrapping - 1 degree assert_eq!(wrap_latlon(1_f64, 0_f64), (1_f64, 0_f64)); // Positive latitude wrapping - 91 degrees assert_eq!(wrap_latlon(91_f64, 0_f64), (89_f64, 180_f64)); // Positive latitude wrapping - 181 degrees assert_eq!(wrap_latlon(181_f64, 0_f64), (-1_f64, 180_f64)); // Positive latitude wrapping - 271 degrees assert_eq!(wrap_latlon(271_f64, 0_f64), (-89_f64, 0_f64)); // Positive latitude wrapping - 361 degrees assert_eq!(wrap_latlon(361_f64, 0_f64), (1_f64, 0_f64)); // Positive latitude wrapping - 631 degrees assert_eq!(wrap_latlon(631_f64, 0_f64), (-89_f64, 0_f64)); // Positive latitude wrapping - 721 degrees assert_eq!(wrap_latlon(721_f64, 0_f64), (1_f64, 0_f64)); } #[test] fn test_latitude_negative() { // Negative latitude wrapping - 1 degree assert_eq!(wrap_latlon(-1_f64, 0_f64), (-1_f64, 0_f64)); // Negative latitude wrapping - 91 degrees assert_eq!(wrap_latlon(-91_f64, 0_f64), (-89_f64, 180_f64)); // Negative latitude wrapping - 181 degrees assert_eq!(wrap_latlon(-181_f64, 0_f64), (1_f64, 180_f64)); // Negative latitude wrapping - 271 degrees assert_eq!(wrap_latlon(-271_f64, 0_f64), (89_f64, 0_f64)); // Negative latitude wrapping - 361 degrees assert_eq!(wrap_latlon(-361_f64, 0_f64), (-1_f64, 0_f64)); // Negative latitude wrapping - 631 degrees assert_eq!(wrap_latlon(-631_f64, 0_f64), (89_f64, 0_f64)); // Positive latitude wrapping - 721 degrees assert_eq!(wrap_latlon(721_f64, 0_f64), (1_f64, 0_f64)); } #[test] fn test_longitude_positive() { // Positive longitude wrapping - 1 degree assert_eq!(wrap_latlon(0_f64, 1_f64), (0_f64, 1_f64)); // Positive longitude wrapping - 181 degrees assert_eq!(wrap_latlon(0_f64, 181_f64), (0_f64, -179_f64)); // Positive longitude wrapping - 271 degrees assert_eq!(wrap_latlon(0_f64, 271_f64), (0_f64, -89_f64)); // Positive longitude wrapping - 361 degrees assert_eq!(wrap_latlon(0_f64, 361_f64), (0_f64, 1_f64)); // Positive longitude wrapping - 631 degrees assert_eq!(wrap_latlon(0_f64, 631_f64), (0_f64, -89_f64)); // Positive longitude wrapping - 721 degrees assert_eq!(wrap_latlon(0_f64, 721_f64), (0_f64, 1_f64)); } #[test] fn test_longitude_negative() { // Negative longitude wrapping - 1 degree assert_eq!(wrap_latlon(0_f64, -1_f64), (0_f64, -1_f64)); // Negative longitude wrapping - 181 degrees assert_eq!(wrap_latlon(0_f64, -181_f64), (0_f64, 179_f64)); // Negative longitude wrapping - 271 degrees assert_eq!(wrap_latlon(0_f64, -271_f64), (0_f64, 89_f64)); // Negative longitude wrapping - 361 degrees assert_eq!(wrap_latlon(0_f64, -361_f64), (0_f64, -1_f64)); // Negative longitude wrapping - 631 degrees assert_eq!(wrap_latlon(0_f64, -631_f64), (0_f64, 89_f64)); // Negative longitude wrapping - 721 degrees assert_eq!(wrap_latlon(0_f64, -721_f64), (0_f64, -1_f64)); } }