use crate::constants::{EARTH_RADIUS_KM, MAX_H3_RES};
use crate::h3_index::inspection::is_valid_cell;
use crate::indexing::cell_to_boundary; use crate::polygon::generic_area_rads2;
use crate::types::{CellBoundary, H3Error, H3Index, LatLng};
pub fn cell_area_rads2(cell: H3Index) -> Result<f64, H3Error> {
if !is_valid_cell(cell) {
return Err(H3Error::CellInvalid);
}
let boundary = cell_to_boundary(cell)?;
Ok(generic_area_rads2(&boundary.verts[0..boundary.num_verts]))
}
pub fn cell_area_km2(cell: H3Index) -> Result<f64, H3Error> {
Ok(cell_area_rads2(cell)? * EARTH_RADIUS_KM * EARTH_RADIUS_KM)
}
pub fn cell_area_m2(cell: H3Index) -> Result<f64, H3Error> {
Ok(cell_area_km2(cell)? * 1_000_000.0) }
pub fn exact_edge_length_rads(_edge: H3Index) -> Result<f64, H3Error> {
Err(H3Error::Failed) }
pub fn exact_edge_length_km(edge: H3Index) -> Result<f64, H3Error> {
Ok(exact_edge_length_rads(edge)? * EARTH_RADIUS_KM)
}
pub fn exact_edge_length_m(edge: H3Index) -> Result<f64, H3Error> {
Ok(exact_edge_length_km(edge)? * 1000.0)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::indexing::lat_lng_to_cell;
use crate::types::LatLng;
use std::f64::consts::PI;
#[test]
fn test_cli_cell_area_rads2() {
let cell = H3Index(0x85283473fffffff); let expected_area_rads2 = 0.0000065310;
let avg_area_rads2 = crate::latlng::get_hexagon_area_avg_km2(5).unwrap() / (EARTH_RADIUS_KM * EARTH_RADIUS_KM);
match cell_area_rads2(cell) {
Ok(area) => {
assert!(
(area - expected_area_rads2).abs() < expected_area_rads2 * 0.1,
"Cell area rads2 mismatch"
);
}
Err(e) => panic!("cell_area_rads2 failed: {:?}", e),
}
}
#[test]
fn test_cli_cell_area_km2() {
let cell = H3Index(0x85283473fffffff);
let expected_area_km2 = 265.0925581283;
let avg_area_km2 = crate::latlng::get_hexagon_area_avg_km2(5).unwrap();
match cell_area_km2(cell) {
Ok(area) => {
assert!(
(area - expected_area_km2).abs() < expected_area_km2 * 0.1,
"Cell area km2 mismatch"
);
}
Err(e) => panic!("cell_area_km2 failed: {:?}", e),
}
}
}