Files
RadioPropagationApi/api/app/core/vegetation.py
T
2026-06-24 07:50:00 +03:00

53 lines
1.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from math import exp
from app.config import get_settings
@dataclass(frozen=True)
class P833Coefficients:
gamma_db_per_m: float
max_attenuation_db: float
WORLDCOVER_P833: dict[str, P833Coefficients] = {
"tree_cover": P833Coefficients(gamma_db_per_m=0.20, max_attenuation_db=30.0),
"mangroves": P833Coefficients(gamma_db_per_m=0.22, max_attenuation_db=32.0),
"shrubland": P833Coefficients(gamma_db_per_m=0.10, max_attenuation_db=12.0),
"grassland": P833Coefficients(gamma_db_per_m=0.05, max_attenuation_db=6.0),
"cropland": P833Coefficients(gamma_db_per_m=0.04, max_attenuation_db=5.0),
"herbaceous_wetland": P833Coefficients(gamma_db_per_m=0.08, max_attenuation_db=10.0),
"unknown": P833Coefficients(gamma_db_per_m=0.15, max_attenuation_db=25.0),
}
def p833_coefficients_for_class(class_name: str) -> P833Coefficients:
if class_name in WORLDCOVER_P833:
return WORLDCOVER_P833[class_name]
settings = get_settings()
return P833Coefficients(
gamma_db_per_m=settings.p833_gamma_db_per_m,
max_attenuation_db=settings.p833_max_attenuation_db,
)
def p833_attenuation(
depth_m: float,
freq_hz: float,
forest_type: str,
coefficients: P833Coefficients | None = None,
) -> float:
if depth_m <= 0:
return 0.0
if freq_hz <= 0:
raise ValueError("freq_hz must be positive")
coeff = coefficients or p833_coefficients_for_class(forest_type)
if coeff.max_attenuation_db <= 0:
raise ValueError("max_attenuation_db must be positive")
return coeff.max_attenuation_db * (
1 - exp(-(depth_m * coeff.gamma_db_per_m) / coeff.max_attenuation_db)
)