44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
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
|
||
},
|
||
}
|