generated from Grigo/AndroidTemplate
41 lines
1.1 KiB
Python
41 lines
1.1 KiB
Python
"""Terrain elevation via Open-Meteo (cached per coordinate)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Optional
|
|
|
|
import httpx
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_CACHE: dict[tuple[float, float], Optional[float]] = {}
|
|
_TIMEOUT = 3.0
|
|
|
|
|
|
def _cache_key(lat: float, lon: float) -> tuple[float, float]:
|
|
return (round(lat, 4), round(lon, 4))
|
|
|
|
|
|
def fetch_elevation_m(lat: float, lon: float) -> Optional[float]:
|
|
key = _cache_key(lat, lon)
|
|
if key in _CACHE:
|
|
return _CACHE[key]
|
|
try:
|
|
with httpx.Client(timeout=_TIMEOUT) as client:
|
|
r = client.get(
|
|
"https://api.open-meteo.com/v1/elevation",
|
|
params={"latitude": lat, "longitude": lon},
|
|
)
|
|
r.raise_for_status()
|
|
data = r.json()
|
|
elevations = data.get("elevation") or []
|
|
if elevations:
|
|
val = float(elevations[0])
|
|
_CACHE[key] = val
|
|
return val
|
|
except Exception as e:
|
|
logger.warning("open-meteo elevation failed for %s,%s: %s", lat, lon, e)
|
|
_CACHE[key] = None
|
|
return None
|