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