Various fixes

This commit is contained in:
Andras Schmelczer 2026-02-04 22:29:42 +00:00
parent 34a4d0ba86
commit 55598aaaa0
14 changed files with 1250 additions and 130 deletions

View file

@ -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));
}
}