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 {"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}")
async def websocket_eta(websocket: WebSocket, domicilio_id: int,
token: str, db: Session = Depends(get_db)):

View File

@@ -1,6 +1,7 @@
import json
import os
import datetime
import math
from sqlalchemy.orm import Session
from database import SessionLocal
import models
@@ -64,4 +65,28 @@ def get_eta(route_id: str, db: Session):
mensaje = f"El camión llegará a tu zona entre las {ventana_inicio} y {ventana_fin}."
return {"mensaje": mensaje, "evento": evento,
"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