Various fixes
This commit is contained in:
parent
34a4d0ba86
commit
55598aaaa0
14 changed files with 1250 additions and 130 deletions
|
|
@ -1,11 +1,29 @@
|
|||
use axum::http::StatusCode;
|
||||
|
||||
/// Compute the lat/lon bounding box of an H3 cell, with a configurable buffer in degrees.
|
||||
/// Check if two bounding boxes intersect.
|
||||
/// Both boxes are (south, west, north, east) / (min_lat, min_lon, max_lat, max_lon).
|
||||
#[inline]
|
||||
pub fn bounds_intersect(
|
||||
a_south: f64,
|
||||
a_west: f64,
|
||||
a_north: f64,
|
||||
a_east: f64,
|
||||
b_south: f64,
|
||||
b_west: f64,
|
||||
b_north: f64,
|
||||
b_east: f64,
|
||||
) -> bool {
|
||||
a_west <= b_east && a_east >= b_west && a_south <= b_north && a_north >= b_south
|
||||
}
|
||||
|
||||
/// Compute the lat/lon bounding box of an H3 cell in degrees, with a configurable buffer in degrees.
|
||||
/// Returns (south, west, north, east) / (min_lat, min_lon, max_lat, max_lon).
|
||||
pub fn h3_cell_bounds(cell: h3o::CellIndex, buffer: f64) -> (f64, f64, f64, f64) {
|
||||
let boundary = cell.boundary();
|
||||
let (mut min_lat, mut max_lat) = (f64::INFINITY, f64::NEG_INFINITY);
|
||||
let (mut min_lon, mut max_lon) = (f64::INFINITY, f64::NEG_INFINITY);
|
||||
for vertex in boundary.iter() {
|
||||
// h3o LatLng::lat()/lng() return degrees
|
||||
let lat = vertex.lat();
|
||||
let lon = vertex.lng();
|
||||
if lat < min_lat {
|
||||
|
|
@ -81,4 +99,42 @@ mod tests {
|
|||
assert!((buf_max_lat - max_lat - 0.1).abs() < 1e-10);
|
||||
assert!((buf_max_lon - max_lon - 0.1).abs() < 1e-10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn h3_cell_bounds_returns_degrees_not_radians() {
|
||||
// Cell "8928308280fffff" is in San Francisco area (~37.77°N, ~-122.4°W)
|
||||
let cell = h3o::CellIndex::from_str("8928308280fffff").unwrap();
|
||||
let (min_lat, min_lon, max_lat, max_lon) = h3_cell_bounds(cell, 0.0);
|
||||
|
||||
// If h3o returned radians, values would be < π ≈ 3.14
|
||||
// Latitude ~37.77° proves we're getting degrees, not radians
|
||||
assert!(min_lat > 30.0 && min_lat < 45.0, "min_lat {} should be ~37° (degrees)", min_lat);
|
||||
assert!(max_lat > 30.0 && max_lat < 45.0, "max_lat {} should be ~37° (degrees)", max_lat);
|
||||
|
||||
// Longitude ~-122° also proves degrees (radians would be < π)
|
||||
assert!(min_lon < -100.0, "min_lon {} should be ~-122° (degrees)", min_lon);
|
||||
assert!(max_lon < -100.0, "max_lon {} should be ~-122° (degrees)", max_lon);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bounds_intersect_overlapping() {
|
||||
// Two overlapping boxes
|
||||
assert!(bounds_intersect(0.0, 0.0, 2.0, 2.0, 1.0, 1.0, 3.0, 3.0));
|
||||
// Box B is inside box A
|
||||
assert!(bounds_intersect(0.0, 0.0, 10.0, 10.0, 2.0, 2.0, 5.0, 5.0));
|
||||
// Box A is inside box B
|
||||
assert!(bounds_intersect(2.0, 2.0, 5.0, 5.0, 0.0, 0.0, 10.0, 10.0));
|
||||
// Touching at edge
|
||||
assert!(bounds_intersect(0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 2.0, 1.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bounds_intersect_non_overlapping() {
|
||||
// Box B is to the right of box A
|
||||
assert!(!bounds_intersect(0.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 3.0));
|
||||
// Box B is above box A
|
||||
assert!(!bounds_intersect(0.0, 0.0, 1.0, 1.0, 2.0, 0.0, 3.0, 1.0));
|
||||
// Completely separate
|
||||
assert!(!bounds_intersect(0.0, 0.0, 1.0, 1.0, 5.0, 5.0, 6.0, 6.0));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue