Refactor and improve

This commit is contained in:
Andras Schmelczer 2026-02-03 20:26:57 +00:00
parent 1f148b2185
commit 242acff987
22 changed files with 754 additions and 1053 deletions

View file

@ -0,0 +1,84 @@
use axum::http::StatusCode;
/// Compute the lat/lon bounding box of an H3 cell, with a configurable buffer in degrees.
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() {
let lat = vertex.lat();
let lon = vertex.lng();
if lat < min_lat {
min_lat = lat;
}
if lat > max_lat {
max_lat = lat;
}
if lon < min_lon {
min_lon = lon;
}
if lon > max_lon {
max_lon = lon;
}
}
(
min_lat - buffer,
min_lon - buffer,
max_lat + buffer,
max_lon + buffer,
)
}
pub fn parse_bounds(bounds_str: &str) -> Result<(f64, f64, f64, f64), (StatusCode, String)> {
let parts: Vec<f64> = bounds_str
.split(',')
.map(|part| part.trim().parse::<f64>())
.collect::<Result<Vec<_>, _>>()
.map_err(|_| {
(
StatusCode::BAD_REQUEST,
"Invalid bounds format. Use: south,west,north,east".into(),
)
})?;
if parts.len() != 4 {
return Err((
StatusCode::BAD_REQUEST,
"Invalid bounds format. Use: south,west,north,east".into(),
));
}
Ok((parts[0], parts[1], parts[2], parts[3]))
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn parse_bounds_valid() {
assert_eq!(parse_bounds("1.0,2.0,3.0,4.0").unwrap(), (1.0, 2.0, 3.0, 4.0));
assert_eq!(parse_bounds("-51.5, -0.1, 51.6, 0.2").unwrap(), (-51.5, -0.1, 51.6, 0.2));
}
#[test]
fn parse_bounds_invalid() {
assert!(parse_bounds("1.0,2.0,3.0").is_err());
assert!(parse_bounds("1.0,2.0,3.0,4.0,5.0").is_err());
assert!(parse_bounds("a,b,c,d").is_err());
assert!(parse_bounds("").is_err());
}
#[test]
fn h3_cell_bounds_applies_buffer() {
let cell = h3o::CellIndex::from_str("8928308280fffff").unwrap();
let (min_lat, min_lon, max_lat, max_lon) = h3_cell_bounds(cell, 0.0);
let (buf_min_lat, buf_min_lon, buf_max_lat, buf_max_lon) = h3_cell_bounds(cell, 0.1);
assert!((min_lat - buf_min_lat - 0.1).abs() < 1e-10);
assert!((min_lon - buf_min_lon - 0.1).abs() < 1e-10);
assert!((buf_max_lat - max_lat - 0.1).abs() < 1e-10);
assert!((buf_max_lon - max_lon - 0.1).abs() < 1e-10);
}
}