better structure
This commit is contained in:
parent
83be4b7616
commit
05092e55f1
backend/src
@ -8,8 +8,8 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
from ..overpass.overpass import Overpass, get_base_info
|
from ..overpass.overpass import Overpass, get_base_info
|
||||||
from ..structs.landmark import Landmark
|
from ..structs.landmark import Landmark
|
||||||
from .get_time_distance import get_distance
|
from ..utils.get_time_distance import get_distance
|
||||||
from .utils import create_bbox
|
from ..utils.bbox import create_bbox
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4,10 +4,10 @@ import yaml
|
|||||||
|
|
||||||
from ..structs.preferences import Preferences
|
from ..structs.preferences import Preferences
|
||||||
from ..structs.landmark import Landmark
|
from ..structs.landmark import Landmark
|
||||||
from .take_most_important import take_most_important
|
from ..utils.take_most_important import take_most_important
|
||||||
from .cluster_manager import ClusterManager
|
from .cluster_manager import ClusterManager
|
||||||
from ..overpass.overpass import Overpass, get_base_info
|
from ..overpass.overpass import Overpass, get_base_info
|
||||||
from .utils import create_bbox
|
from ..utils.bbox import create_bbox
|
||||||
|
|
||||||
from ..constants import AMENITY_SELECTORS_PATH, LANDMARK_PARAMETERS_PATH, OPTIMIZER_PARAMETERS_PATH
|
from ..constants import AMENITY_SELECTORS_PATH, LANDMARK_PARAMETERS_PATH, OPTIMIZER_PARAMETERS_PATH
|
||||||
|
|
@ -7,12 +7,12 @@ from fastapi import FastAPI, HTTPException, BackgroundTasks, Query
|
|||||||
from fastapi.encoders import jsonable_encoder
|
from fastapi.encoders import jsonable_encoder
|
||||||
|
|
||||||
from .logging_config import configure_logging
|
from .logging_config import configure_logging
|
||||||
from .structs.landmark import Landmark, Toilets
|
from .structs.landmark import Landmark
|
||||||
from .structs.preferences import Preferences
|
from .structs.preferences import Preferences
|
||||||
from .structs.linked_landmarks import LinkedLandmarks
|
from .structs.linked_landmarks import LinkedLandmarks
|
||||||
from .structs.trip import Trip
|
from .structs.trip import Trip
|
||||||
from .utils.landmarks_manager import LandmarkManager
|
from .landmarks.landmarks_manager import LandmarkManager
|
||||||
from .utils.toilets_manager import ToiletsManager
|
from .toilets.toilet_routes import router as toilets_router
|
||||||
from .optimization.optimizer import Optimizer
|
from .optimization.optimizer import Optimizer
|
||||||
from .optimization.refiner import Refiner
|
from .optimization.refiner import Refiner
|
||||||
from .overpass.overpass import fill_cache
|
from .overpass.overpass import fill_cache
|
||||||
@ -38,6 +38,10 @@ async def lifespan(app: FastAPI):
|
|||||||
app = FastAPI(lifespan=lifespan)
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.include_router(toilets_router)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/trip/new")
|
@app.post("/trip/new")
|
||||||
def new_trip(preferences: Preferences,
|
def new_trip(preferences: Preferences,
|
||||||
start: tuple[float, float],
|
start: tuple[float, float],
|
||||||
@ -67,6 +71,8 @@ def new_trip(preferences: Preferences,
|
|||||||
end = start
|
end = start
|
||||||
logger.info("No end coordinates provided. Using start=end.")
|
logger.info("No end coordinates provided. Using start=end.")
|
||||||
|
|
||||||
|
logger.info(f"Requested new trip generation. Details:\n\tCoordinates: {start}\n\tTime: {preferences.max_time_minute}\n\tSightseeing: {preferences.sightseeing.score}\n\tNature: {preferences.nature.score}\n\tShopping: {preferences.shopping.score}")
|
||||||
|
|
||||||
start_landmark = Landmark(name='start',
|
start_landmark = Landmark(name='start',
|
||||||
type='start',
|
type='start',
|
||||||
location=(start[0], start[1]),
|
location=(start[0], start[1]),
|
||||||
@ -225,32 +231,3 @@ def update_trip_time(trip_uuid: str, removed_landmark_uuid: str) -> Trip:
|
|||||||
trip = Trip.from_linked_landmarks(linked_tour, cache_client)
|
trip = Trip.from_linked_landmarks(linked_tour, cache_client)
|
||||||
|
|
||||||
return trip
|
return trip
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/toilets/new")
|
|
||||||
def get_toilets(location: tuple[float, float] = Query(...), radius: int = 500) -> list[Toilets] :
|
|
||||||
"""
|
|
||||||
Endpoint to find toilets within a specified radius from a given location.
|
|
||||||
|
|
||||||
This endpoint expects the `location` and `radius` as **query parameters**, not in the request body.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
location (tuple[float, float]): The latitude and longitude of the location to search from.
|
|
||||||
radius (int, optional): The radius (in meters) within which to search for toilets. Defaults to 500 meters.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[Toilets]: A list of Toilets objects that meet the criteria.
|
|
||||||
"""
|
|
||||||
if location is None:
|
|
||||||
raise HTTPException(status_code=406, detail="Coordinates not provided or invalid")
|
|
||||||
if not (-90 <= location[0] <= 90 or -180 <= location[1] <= 180):
|
|
||||||
raise HTTPException(status_code=422, detail="Start coordinates not in range")
|
|
||||||
|
|
||||||
toilets_manager = ToiletsManager(location, radius)
|
|
||||||
|
|
||||||
try :
|
|
||||||
toilets_list = toilets_manager.generate_toilet_list()
|
|
||||||
return toilets_list
|
|
||||||
except KeyError as exc:
|
|
||||||
raise HTTPException(status_code=404, detail="No toilets found") from exc
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Module allowing connexion to overpass api and fectch data from OSM."""
|
"""Module allowing connexion to overpass api and fectch data from OSM."""
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
import math
|
import math
|
||||||
import logging
|
import logging
|
||||||
@ -153,7 +154,7 @@ class Overpass :
|
|||||||
- If no conditions are provided, the query will just use the `selector` to filter the OSM
|
- If no conditions are provided, the query will just use the `selector` to filter the OSM
|
||||||
elements without additional constraints.
|
elements without additional constraints.
|
||||||
"""
|
"""
|
||||||
query = '[out:json];('
|
query = '[out:json][timeout:20];('
|
||||||
|
|
||||||
# convert the bbox to string.
|
# convert the bbox to string.
|
||||||
bbox_str = f"({','.join(map(str, bbox))})"
|
bbox_str = f"({','.join(map(str, bbox))})"
|
||||||
@ -399,18 +400,25 @@ def fill_cache():
|
|||||||
"""
|
"""
|
||||||
overpass = Overpass()
|
overpass = Overpass()
|
||||||
|
|
||||||
|
n_files = 0
|
||||||
|
total = 0
|
||||||
|
|
||||||
with os.scandir(OSM_CACHE_DIR) as it:
|
with os.scandir(OSM_CACHE_DIR) as it:
|
||||||
for entry in it:
|
for entry in it:
|
||||||
if entry.is_file() and entry.name.startswith('hollow_'):
|
if entry.is_file() and entry.name.startswith('hollow_'):
|
||||||
|
total += 1
|
||||||
try :
|
try :
|
||||||
# Read the whole file content as a string
|
# Read the whole file content as a string
|
||||||
with open(entry.path, 'r', encoding='utf-8') as f:
|
with open(entry.path, 'r', encoding='utf-8') as f:
|
||||||
# load data and fill the cache with the query and key
|
# load data and fill the cache with the query and key
|
||||||
json_data = json.load(f)
|
json_data = json.load(f)
|
||||||
overpass.fill_cache(json_data)
|
overpass.fill_cache(json_data)
|
||||||
|
n_files += 1
|
||||||
|
time.sleep(1)
|
||||||
# Now delete the file as the cache is filled
|
# Now delete the file as the cache is filled
|
||||||
os.remove(entry.path)
|
os.remove(entry.path)
|
||||||
|
|
||||||
except Exception as exc :
|
except Exception as exc :
|
||||||
overpass.logger.error(f'An error occured while parsing file {entry.path} as .json file: {str(exc)}')
|
overpass.logger.error(f'An error occured while parsing file {entry.path} as .json file: {str(exc)}')
|
||||||
|
|
||||||
|
overpass.logger.info(f"Successfully filled {n_files}/{total} cache files.")
|
@ -1,5 +1,4 @@
|
|||||||
"""Definition of the Landmark class to handle visitable objects across the world."""
|
"""Definition of the Landmark class to handle visitable objects across the world."""
|
||||||
|
|
||||||
from typing import Optional, Literal, List
|
from typing import Optional, Literal, List
|
||||||
from uuid import uuid4, UUID
|
from uuid import uuid4, UUID
|
||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
@ -129,26 +128,3 @@ class Landmark(BaseModel) :
|
|||||||
return (self.uuid == value.uuid or
|
return (self.uuid == value.uuid or
|
||||||
self.osm_id == value.osm_id or
|
self.osm_id == value.osm_id or
|
||||||
(self.name == value.name and self.distance(value) < 0.001))
|
(self.name == value.name and self.distance(value) < 0.001))
|
||||||
|
|
||||||
|
|
||||||
class Toilets(BaseModel) :
|
|
||||||
"""
|
|
||||||
Model for toilets. When false/empty the information is either false either not known.
|
|
||||||
"""
|
|
||||||
location : tuple
|
|
||||||
wheelchair : Optional[bool] = False
|
|
||||||
changing_table : Optional[bool] = False
|
|
||||||
fee : Optional[bool] = False
|
|
||||||
opening_hours : Optional[str] = ""
|
|
||||||
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
"""
|
|
||||||
String representation of the Toilets object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: A formatted string with the toilets location.
|
|
||||||
"""
|
|
||||||
return f'Toilets @{self.location}'
|
|
||||||
|
|
||||||
model_config = ConfigDict(from_attributes=True)
|
|
||||||
|
26
backend/src/structs/toilets.py
Normal file
26
backend/src/structs/toilets.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"""Definition of the Toilets class."""
|
||||||
|
from typing import Optional
|
||||||
|
from pydantic import BaseModel, ConfigDict
|
||||||
|
|
||||||
|
|
||||||
|
class Toilets(BaseModel) :
|
||||||
|
"""
|
||||||
|
Model for toilets. When false/empty the information is either false either not known.
|
||||||
|
"""
|
||||||
|
location : tuple
|
||||||
|
wheelchair : Optional[bool] = False
|
||||||
|
changing_table : Optional[bool] = False
|
||||||
|
fee : Optional[bool] = False
|
||||||
|
opening_hours : Optional[str] = ""
|
||||||
|
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
"""
|
||||||
|
String representation of the Toilets object.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: A formatted string with the toilets location.
|
||||||
|
"""
|
||||||
|
return f'Toilets @{self.location}'
|
||||||
|
|
||||||
|
model_config = ConfigDict(from_attributes=True)
|
37
backend/src/toilets/toilet_routes.py
Normal file
37
backend/src/toilets/toilet_routes.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from fastapi import HTTPException, APIRouter, Query
|
||||||
|
|
||||||
|
from ..structs.toilets import Toilets
|
||||||
|
from .toilets_manager import ToiletsManager
|
||||||
|
|
||||||
|
|
||||||
|
# Define the API router
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/toilets/new")
|
||||||
|
def get_toilets(location: tuple[float, float] = Query(...), radius: int = 500) -> list[Toilets] :
|
||||||
|
"""
|
||||||
|
Endpoint to find toilets within a specified radius from a given location.
|
||||||
|
|
||||||
|
This endpoint expects the `location` and `radius` as **query parameters**, not in the request body.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
location (tuple[float, float]): The latitude and longitude of the location to search from.
|
||||||
|
radius (int, optional): The radius (in meters) within which to search for toilets. Defaults to 500 meters.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[Toilets]: A list of Toilets objects that meet the criteria.
|
||||||
|
"""
|
||||||
|
if location is None:
|
||||||
|
raise HTTPException(status_code=406, detail="Coordinates not provided or invalid")
|
||||||
|
if not (-90 <= location[0] <= 90 or -180 <= location[1] <= 180):
|
||||||
|
raise HTTPException(status_code=422, detail="Start coordinates not in range")
|
||||||
|
|
||||||
|
toilets_manager = ToiletsManager(location, radius)
|
||||||
|
|
||||||
|
try :
|
||||||
|
toilets_list = toilets_manager.generate_toilet_list()
|
||||||
|
except KeyError as exc:
|
||||||
|
raise HTTPException(status_code=404, detail="No toilets found") from exc
|
||||||
|
|
||||||
|
return toilets_list
|
@ -2,8 +2,8 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from ..overpass.overpass import Overpass, get_base_info
|
from ..overpass.overpass import Overpass, get_base_info
|
||||||
from ..structs.landmark import Toilets
|
from ..structs.toilets import Toilets
|
||||||
from .utils import create_bbox
|
from ..utils.bbox import create_bbox
|
||||||
|
|
||||||
|
|
||||||
# silence the overpass logger
|
# silence the overpass logger
|
Loading…
x
Reference in New Issue
Block a user