Skip to content

Commit 04b1949

Browse files
Refactor EmotionalRouteView to filter and sort landmarks by proximity, enhancing route calculation and handling cases with no valid routes.
1 parent cd424cf commit 04b1949

File tree

1 file changed

+43
-25
lines changed

1 file changed

+43
-25
lines changed

guia/views.py

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,39 +56,57 @@ def post(self, request):
5656
if not mood or not lat or not lon:
5757
return Response({"error": "Datos incompletos"}, status=400)
5858

59-
# Crear punto de inicio
6059
start = Point(float(lon), float(lat))
61-
62-
# Obtener mood
6360
mood_obj = Mood.objects.filter(name__iexact=mood).first()
61+
6462
if not mood_obj:
6563
return Response({"error": "Mood no válido"}, status=404)
6664

67-
# Buscar landmarks que tengan ese mood
68-
landmarks = Landmark.objects.filter(moods=mood_obj)
69-
70-
# Ordenar por cercanía al punto de inicio (más adelante puede ser por duración)
71-
close_points = sorted(landmarks, key=lambda l: l.geom.distance(start))[:3]
72-
73-
coords = [f"{lon},{lat}"] + [f"{p.geom.x},{p.geom.y}" for p in close_points]
74-
75-
# Llamar a OSRM
76-
osrm_url = f"http://osrm_server:5000/route/v1/foot/" + ";".join(coords)
77-
res = requests.get(
78-
osrm_url, params={"overview": "full", "geometries": "geojson"}
79-
)
80-
81-
if res.status_code != 200:
82-
return Response({"error": "No se pudo conectar con OSRM"}, status=500)
83-
84-
route_data = res.json()["routes"][0]
65+
# Filtra y ordena todos los hitos compatibles por cercanía al punto de inicio
66+
all_landmarks = list(Landmark.objects.filter(moods=mood_obj).order_by("geom"))
67+
68+
if not all_landmarks:
69+
return Response({"error": "No hay hitos para este mood"}, status=404)
70+
71+
coords = [f"{lon},{lat}"] # Coordenadas iniciales
72+
visited = []
73+
total_duration = 0
74+
total_distance = 0
75+
76+
for landmark in all_landmarks:
77+
test_coords = coords + [f"{landmark.geom.x},{landmark.geom.y}"]
78+
osrm_url = f"http://osrm_server:5000/route/v1/foot/" + ";".join(test_coords)
79+
80+
res = requests.get(
81+
osrm_url, params={"overview": "full", "geometries": "geojson"}
82+
)
83+
if res.status_code != 200:
84+
continue
85+
86+
data = res.json()["routes"][0]
87+
duration = data["duration"]
88+
distance = data["distance"]
89+
90+
if duration <= minutes * 60:
91+
coords.append(f"{landmark.geom.x},{landmark.geom.y}")
92+
visited.append(landmark)
93+
total_duration = duration
94+
total_distance = distance
95+
else:
96+
break # Ya no caben más hitos
97+
98+
if not visited:
99+
return Response(
100+
{"error": "No se encontró una ruta dentro del tiempo indicado"},
101+
status=404,
102+
)
85103

86104
return Response(
87105
{
88-
"route": route_data["geometry"],
89-
"distance_km": route_data["distance"] / 1000,
90-
"duration_min": route_data["duration"] / 60,
91-
"visited": [p.name for p in close_points],
106+
"route": data["geometry"],
107+
"distance_km": total_distance / 1000,
108+
"duration_min": total_duration / 60,
109+
"visited": [v.name for v in visited],
92110
}
93111
)
94112

0 commit comments

Comments
 (0)