feat: geolocalización GPS para detectar zona de recolección automáticamente

This commit is contained in:
2026-05-23 02:17:53 -06:00
parent ca3fa5f7bf
commit 147b4ecb20
4 changed files with 47 additions and 1 deletions

View File

@@ -174,6 +174,27 @@ def get_alerta_activa(
return alerta return alerta
return {"activa": False, "mensaje": None} return {"activa": False, "mensaje": None}
@app.get("/domicilios/ruta-por-coordenadas")
def ruta_por_coordenadas(
lat: float,
lng: float,
current_user=Depends(auth.get_current_user)
):
ruta, distancia = simulator.encontrar_ruta_por_coordenadas(lat, lng)
if not ruta:
raise HTTPException(status_code=404, detail="No hay cobertura en esta ubicación")
colonia_info = next(
(c for c in simulator.COLONIAS.values() if c["routeId"] == ruta["routeId"]),
None
)
return {
"route_id": ruta["routeId"],
"nombre_ruta": ruta["name"],
"colonia_sugerida": colonia_info["colonia"] if colonia_info else ruta["name"],
"distancia_metros": round(distancia),
"cobertura": True
}
@app.websocket("/ws/eta/{domicilio_id}") @app.websocket("/ws/eta/{domicilio_id}")
async def websocket_eta(websocket: WebSocket, domicilio_id: int, async def websocket_eta(websocket: WebSocket, domicilio_id: int,
token: str, db: Session = Depends(get_db)): token: str, db: Session = Depends(get_db)):

View File

@@ -1,6 +1,7 @@
import json import json
import os import os
import datetime import datetime
import math
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from database import SessionLocal from database import SessionLocal
import models import models
@@ -65,3 +66,27 @@ def get_eta(route_id: str, db: Session):
return {"mensaje": mensaje, "evento": evento, return {"mensaje": mensaje, "evento": evento,
"ventana_inicio": ventana_inicio, "ventana_fin": ventana_fin, "ventana_inicio": ventana_inicio, "ventana_fin": ventana_fin,
"current_position": pos} "current_position": pos}
def haversine(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
R = 6371
dlat = math.radians(lat2 - lat1)
dlon = math.radians(lon2 - lon1)
a = (math.sin(dlat/2)**2 +
math.cos(math.radians(lat1)) *
math.cos(math.radians(lat2)) *
math.sin(dlon/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return R * c * 1000
def encontrar_ruta_por_coordenadas(lat: float, lng: float):
mejor_ruta = None
menor_distancia = float('inf')
for ruta in RUTAS:
for pos in ruta["positions"]:
distancia = haversine(lat, lng, pos["lat"], pos["lng"])
if distancia < menor_distancia:
menor_distancia = distancia
mejor_ruta = ruta
if menor_distancia < 5000:
return mejor_ruta, menor_distancia
return None, None