Skip to content

Instantly share code, notes, and snippets.

@austenadler
Forked from missinglink/wrap.js
Last active March 11, 2023 21:26
Show Gist options
  • Save austenadler/ad22593c9492820a59217b6c84d301d6 to your computer and use it in GitHub Desktop.
Save austenadler/ad22593c9492820a59217b6c84d301d6 to your computer and use it in GitHub Desktop.
wrap latitude and longitude values around the poles in order to normalize their ranges
/// 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));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment