69 lines
2.7 KiB
Python
69 lines
2.7 KiB
Python
import logging
|
|
from fastapi import FastAPI, Query, Body
|
|
|
|
from structs.landmark import Landmark
|
|
from structs.preferences import Preferences
|
|
from structs.linked_landmarks import LinkedLandmarks
|
|
from utils.landmarks_manager import LandmarkManager
|
|
from utils.optimizer import Optimizer
|
|
from utils.refiner import Refiner
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
app = FastAPI()
|
|
manager = LandmarkManager()
|
|
optimizer = Optimizer()
|
|
refiner = Refiner(optimizer=optimizer)
|
|
|
|
|
|
@app.post("/route/new")
|
|
def get_route(preferences: Preferences, start: tuple[float, float], end: tuple[float, float] | None = None) -> str:
|
|
'''
|
|
Main function to call the optimizer.
|
|
:param preferences: the preferences specified by the user as the post body
|
|
:param start: the coordinates of the starting point as a tuple of floats (as url query parameters)
|
|
:param end: the coordinates of the finishing point as a tuple of floats (as url query parameters)
|
|
:return: the uuid of the first landmark in the optimized route
|
|
'''
|
|
if preferences is None:
|
|
raise ValueError("Please provide preferences in the form of a 'Preference' BaseModel class.")
|
|
if start is None:
|
|
raise ValueError("Please provide the starting coordinates as a tuple of floats.")
|
|
if end is None:
|
|
end = start
|
|
logger.info("No end coordinates provided. Using start=end.")
|
|
|
|
start_landmark = Landmark(name='start', type='start', location=(start[0], start[1]), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
|
end_landmark = Landmark(name='end', type='finish', location=(end[0], end[1]), osm_type='end', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
|
|
|
# Generate the landmarks from the start location
|
|
landmarks, landmarks_short = manager.generate_landmarks_list(
|
|
center_coordinates = start,
|
|
preferences = preferences
|
|
)
|
|
|
|
# insert start and finish to the landmarks list
|
|
landmarks_short.insert(0, start_landmark)
|
|
landmarks_short.append(end_landmark)
|
|
|
|
# TODO infer these parameters from the preferences
|
|
max_walking_time = 4 # hours
|
|
detour = 30 # minutes
|
|
|
|
# First stage optimization
|
|
base_tour = optimizer.solve_optimization(max_walking_time*60, landmarks_short)
|
|
|
|
# Second stage optimization
|
|
refined_tour = refiner.refine_optimization(landmarks, base_tour, max_walking_time*60, detour)
|
|
|
|
linked_tour = LinkedLandmarks(refined_tour)
|
|
return linked_tour[0].uuid
|
|
|
|
|
|
|
|
@app.get("/landmark/{landmark_uuid}")
|
|
def get_landmark(landmark_uuid: str) -> Landmark:
|
|
#cherche dans linked_tour et retourne le landmark correspondant
|
|
pass
|