from __future__ import annotations from typing import Dict, Any, Tuple, List import os from pyproj import Geod LatLon = Tuple[float, float] class CrowFlyRoutingProvider: """ Isócrona aproximada como círculo geodésico: radio = velocidad_km_h * (minutos / 60.0) Útil para demos sin depender de motores externos. """ def __init__(self) -> None: self._geod = Geod(ellps="WGS84") # Puedes ajustar la velocidad por entorno (urbana 25–35 km/h es razonable) self._speed_kmh = float(os.getenv("ROUTING_CROWFLY_SPEED_KMH", "30")) def health(self) -> Dict[str, Any]: return {"provider": "crowfly", "ok": True, "speed_kmh": self._speed_kmh} def isochrone(self, center: LatLon, minutes: int) -> Dict[str, Any]: lat, lon = float(center[0]), float(center[1]) # distancia en metros km = self._speed_kmh * (float(minutes) / 60.0) dist_m = km * 1000.0 # polígono aproximado (64 segmentos) coords: List[Tuple[float, float]] = [] for b in range(0, 360, 360 // 64): lon2, lat2, _ = self._geod.fwd(lon, lat, b, dist_m) coords.append((lon2, lat2)) coords.append(coords[0]) # cerrar # GeoJSON-like return { "type": "Feature", "properties": {"minutes": minutes, "speed_kmh": self._speed_kmh}, "geometry": { "type": "Polygon", "coordinates": [coords], # lon,lat }, }