linting
Some checks failed
Run linting on the backend code / Build (pull_request) Has been cancelled
Run testing on the backend code / Build (pull_request) Has been cancelled
Build and deploy the backend to staging / Deploy to staging (pull_request) Has been cancelled
Build and deploy the backend to staging / Build and push image (pull_request) Has been cancelled

This commit is contained in:
kscheidecker 2025-02-19 16:04:18 +01:00
parent 05092e55f1
commit 73f0dc8361
12 changed files with 52 additions and 38 deletions

View File

View File

@ -113,7 +113,7 @@ class ClusterManager:
points = []
for elem in result:
osm_type = elem.get('type')
# Get coordinates and append them to the points list
_, coords = get_base_info(elem, osm_type)
if coords is not None :
@ -217,7 +217,7 @@ class ClusterManager:
# Define the bounding box for a given radius around the coordinates
bbox = create_bbox(cluster.centroid, 300)
# Query neighborhoods and shopping malls
selectors = ['"place"~"^(suburb|neighborhood|neighbourhood|quarter|city_block)$"']

View File

@ -298,6 +298,16 @@ class LandmarkManager:
def description_and_keywords(self, tags: dict):
"""
Generates a description and a set of keywords for a given landmark based on its tags.
Params:
tags (dict): A dictionary containing metadata about the landmark, including its name,
importance, height, date of construction, and visitor information.
Returns:
description (str): A string description of the landmark.
keywords (dict): A dictionary of keywords with fields such as 'importance', 'height',
'place_type', and 'date'.
"""
# Extract relevant fields
name = tags.get('name')
@ -314,7 +324,7 @@ class LandmarkManager:
if importance is None :
if len(tags.keys()) < 5 :
return None, None
elif len(tags.keys()) < 10 :
if len(tags.keys()) < 10 :
description = f"{name} is a well known {place_type}."
elif len(tags.keys()) < 17 :
importance = 'national'
@ -350,6 +360,17 @@ class LandmarkManager:
def get_place_type(self, data):
"""
Determines the type of the place based on available tags such as 'amenity', 'building',
'historic', and 'leisure'. The priority order is: 'historic' > 'building' (if not generic) >
'amenity' > 'leisure'.
Params:
data (dict): A dictionary containing metadata about the place.
Returns:
place_type (str): The determined type of the place, or None if no relevant type is found.
"""
amenity = data.get('amenity', None)
building = data.get('building', None)
historic = data.get('historic', None)
@ -369,6 +390,16 @@ class LandmarkManager:
def get_date(self, data):
"""
Extracts the most relevant date from the available tags, prioritizing 'construction_date',
'start_date', 'year_of_construction', and 'opening_date' in that order.
Params:
data (dict): A dictionary containing metadata about the place.
Returns:
date (str): The most relevant date found, or None if no date is available.
"""
construction_date = data.get('construction_date', None)
opening_date = data.get('opening_date', None)
start_date = data.get('start_date', None)

View File

@ -94,6 +94,7 @@ def new_trip(preferences: Preferences,
n_tags=0)
start_time = time.time()
# Generate the landmarks from the start location
landmarks, landmarks_short = manager.generate_landmarks_list(
center_coordinates = start,
@ -103,15 +104,6 @@ def new_trip(preferences: Preferences,
if len(landmarks) == 0 :
raise HTTPException(status_code=500, detail="No landmarks were found.")
###################### store landmarks in json file for debug ######################
landmarks_list = [jsonable_encoder(item) for item in landmarks]
with open('landmarks.json', 'w+') as file:
json.dump(landmarks_list, file, indent=4)
####################################################################################
# insert start and finish to the landmarks list
landmarks_short.insert(0, start_landmark)
landmarks_short.append(end_landmark)

View File

@ -278,7 +278,7 @@ class Refiner :
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
xs, ys = better_tour_poly.exterior.xy
"""
ERROR HERE :
FIXED : ERROR HERE :
Exception has occurred: AttributeError
'LineString' object has no attribute 'exterior'
"""

View File

@ -65,14 +65,12 @@ class Overpass :
self.logger.debug(f'Query string: {query_str}')
return self.fetch_data_from_api(query_str)
# Hybrid cache: some data from Overpass, some data from cache.
else :
# Resize the bbox for smaller search area and build new query string.
non_cached_bbox = Overpass._get_non_cached_bbox(non_cached_cells, bbox)
query_str = Overpass.build_query(non_cached_bbox, osm_types, selector, conditions, out)
self.logger.debug(f'Query string: {query_str}')
non_cached_responses = self.fetch_data_from_api(query_str)
return Overpass._filter_landmarks(cached_responses, bbox) + non_cached_responses
# Resize the bbox for smaller search area and build new query string.
non_cached_bbox = Overpass._get_non_cached_bbox(non_cached_cells, bbox)
query_str = Overpass.build_query(non_cached_bbox, osm_types, selector, conditions, out)
self.logger.debug(f'Query string: {query_str}')
non_cached_responses = self.fetch_data_from_api(query_str)
return Overpass._filter_landmarks(cached_responses, bbox) + non_cached_responses
def fetch_data_from_api(self, query_str: str) -> List[dict]:
@ -97,8 +95,8 @@ class Overpass :
return elements
except urllib.error.URLError as e:
self.logger.error(f"Error connecting to Overpass API: {e}")
raise ConnectionError(f"Error connecting to Overpass API: {e}") from e
self.logger.error(f"Error connecting to Overpass API: {str(exc)}")
raise ConnectionError(f"Error connecting to Overpass API: {str(exc)}") from e
except Exception as exc :
raise Exception(f'An unexpected error occured: {str(exc)}') from exc
@ -389,8 +387,8 @@ def get_base_info(elem: dict, osm_type: OSM_TYPES, with_name=False) :
if with_name :
name = elem.get('tags', {}).get('name')
return osm_id, coords, name
else :
return osm_id, coords
return osm_id, coords
def fill_cache():
@ -421,4 +419,4 @@ def fill_cache():
except Exception as 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.")
overpass.logger.info(f"Successfully filled {n_files}/{total} cache files.")

View File

@ -1,7 +1,7 @@
"""Definition of the Landmark class to handle visitable objects across the world."""
from typing import Optional, Literal, List
from typing import Optional, Literal
from uuid import uuid4, UUID
from pydantic import BaseModel, ConfigDict, Field
from pydantic import BaseModel, Field
# Output to frontend
@ -70,11 +70,6 @@ class Landmark(BaseModel) :
is_place_of_worship : Optional[bool] = False
class Config:
json_encoders = {
UUID: lambda v: str(v) # Ensure UUID is serialized as a string
}
def __str__(self) -> str:
"""
String representation of the Landmark object.

View File

@ -341,5 +341,3 @@ def test_shopping(client, request) : # pylint: disable=redefined-outer-name
assert comp_time < 30, f"Computation time exceeded 30 seconds: {comp_time:.2f} seconds"
assert duration_minutes*0.8 < result['total_time'], f"Trip too short: {result['total_time']} instead of {duration_minutes}"
assert duration_minutes*1.2 > result['total_time'], f"Trip too long: {result['total_time']} instead of {duration_minutes}"

View File

@ -1,7 +1,6 @@
"""Helper methods for testing."""
import logging
from fastapi import HTTPException
from pydantic import ValidationError
from ..structs.landmark import Landmark
from ..cache import client as cache_client

View File

View File

@ -1,3 +1,4 @@
"""Defines the endpoint for fetching toilet locations."""
from fastapi import HTTPException, APIRouter, Query
from ..structs.toilets import Toilets
@ -33,5 +34,5 @@ def get_toilets(location: tuple[float, float] = Query(...), radius: int = 500) -
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

View File

@ -24,4 +24,4 @@ def create_bbox(coords: tuple[float, float], radius: int):
lon_min = lon - d_lon * 180 / m.pi
lon_max = lon + d_lon * 180 / m.pi
return (lat_min, lon_min, lat_max, lon_max)
return (lat_min, lon_min, lat_max, lon_max)