"""Module for finding public toilets around given coordinates.""" import logging from ..overpass.overpass import Overpass, get_base_info from ..structs.toilets import Toilets from ..utils.bbox import create_bbox # silence the overpass logger logging.getLogger('Overpass').setLevel(level=logging.CRITICAL) class ToiletsManager: """ Manages the process of fetching and caching toilet information from OpenStreetMap (OSM) based on a specified location and radius. This class is responsible for: - Fetching toilet data from OSM using Overpass API around a given set of coordinates (latitude, longitude). - Using a caching strategy to optimize requests by saving and retrieving data from a local cache. - Logging important events and errors related to data fetching. Attributes: logger (logging.Logger): Logger for the class to capture events. location (tuple[float, float]): Latitude and longitude representing the location to search around. radius (int): The search radius in meters for finding nearby toilets. overpass (Overpass): The Overpass API instance used to query OSM. """ logger = logging.getLogger(__name__) location: tuple[float, float] radius: int # radius in meters def __init__(self, location: tuple[float, float], radius : int) -> None: self.radius = radius self.location = location # Setup the caching in the Overpass class. self.overpass = Overpass() def generate_toilet_list(self) -> list[Toilets] : """ Generates a list of toilet locations by fetching data from OpenStreetMap (OSM) around the given coordinates stored in `self.location`. Returns: list[Toilets]: A list of `Toilets` objects containing detailed information about the toilets found around the given coordinates. """ bbox = create_bbox(self.location, self.radius) osm_types = ['node', 'way', 'relation'] toilets_list = [] query = Overpass.build_query( bbox = bbox, osm_types = osm_types, selector = '"amenity"="toilets"', out = 'ids center tags' ) try: result = self.overpass.fetch_data_from_api(query_str=query) except Exception as e: self.logger.error(f"Error fetching toilets: {e}") return None toilets_list = self.to_toilets(result) return toilets_list def to_toilets(self, elements: list) -> list[Toilets]: """ Parse the Overpass API result and extract landmarks. This method processes the JSON elements returned by the Overpass API and extracts landmarks of types 'node', 'way', and 'relation'. It retrieves relevant information such as name, coordinates, and tags, and converts them into Landmark objects. Args: list (osm elements): The root element of the JSON response from Overpass API. elem_type (str): The type of landmark (e.g., node, way, relation). Returns: list[Landmark]: A list of Landmark objects extracted from the JSON data. """ if elements is None : return [] toilets_list = [] for elem in elements: osm_type = elem.get('type') # Get coordinates and append them to the points list _, coords = get_base_info(elem, osm_type) if coords is None : continue toilets = Toilets(location=coords) # Extract tags as a dictionary tags = elem.get('tags') if 'wheelchair' in tags.keys() and tags['wheelchair'] == 'yes': toilets.wheelchair = True if 'changing_table' in tags.keys() and tags['changing_table'] == 'yes': toilets.changing_table = True if 'fee' in tags.keys() and tags['fee'] == 'yes': toilets.fee = True if 'opening_hours' in tags.keys() : toilets.opening_hours = tags['opening_hours'] toilets_list.append(toilets) return toilets_list