X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/2f547325007dccf17ccfcfd309c18c2f41147772..1f0e1bec0ee66df7641e53c6b55e84d7eb88cec2:/nominatim/api/results.py diff --git a/nominatim/api/results.py b/nominatim/api/results.py index 2999b9a7..98b13380 100644 --- a/nominatim/api/results.py +++ b/nominatim/api/results.py @@ -11,7 +11,7 @@ Data classes are part of the public API while the functions are for internal use only. That's why they are implemented as free-standing functions instead of member functions. """ -from typing import Optional, Tuple, Dict, Sequence, TypeVar, Type +from typing import Optional, Tuple, Dict, Sequence, TypeVar, Type, List import enum import dataclasses import datetime as dt @@ -22,6 +22,7 @@ from nominatim.typing import SaSelect, SaRow from nominatim.api.types import Point, Bbox, LookupDetails from nominatim.api.connection import SearchConnection from nominatim.api.logging import log +from nominatim.api.localization import Locales # This file defines complex result data classes. # pylint: disable=too-many-instance-attributes @@ -52,8 +53,30 @@ class AddressLine: rank_address: int distance: float + local_name: Optional[str] = None + + +class AddressLines(List[AddressLine]): + """ Sequence of address lines order in descending order by their rank. + """ + + def localize(self, locales: Locales) -> List[str]: + """ Set the local name of address parts according to the chosen + locale. Return the list of local names without duplications. + + Only address parts that are marked as isaddress are localized + and returned. + """ + label_parts: List[str] = [] + + for line in self: + if line.isaddress and line.names: + line.local_name = locales.display_name(line.names) + if not label_parts or label_parts[-1] != line.local_name: + label_parts.append(line.local_name) + + return label_parts -AddressLines = Sequence[AddressLine] @dataclasses.dataclass @@ -144,6 +167,25 @@ class ReverseResult(BaseResult): bbox: Optional[Bbox] = None +class ReverseResults(List[ReverseResult]): + """ Sequence of reverse lookup results ordered by distance. + May be empty when no result was found. + """ + + +@dataclasses.dataclass +class SearchResult(BaseResult): + """ A search result for forward geocoding. + """ + bbox: Optional[Bbox] = None + + +class SearchResults(List[SearchResult]): + """ Sequence of forward lookup results ordered by relevance. + May be empty when no result was found. + """ + + def _filter_geometries(row: SaRow) -> Dict[str, str]: return {k[9:]: v for k, v in row._mapping.items() # pylint: disable=W0212 if k.startswith('geometry_')} @@ -226,6 +268,7 @@ def create_from_tiger_row(row: Optional[SaRow], res = class_type(source_table=SourceTable.TIGER, place_id=row.place_id, + osm_object=(row.osm_type, row.osm_id), category=('place', 'houses' if hnr is None else 'house'), postcode=row.postcode, country_code='us', @@ -286,8 +329,8 @@ def _result_row_to_address_row(row: SaRow) -> AddressLine: """ Create a new AddressLine from the results of a datbase query. """ extratags: Dict[str, str] = getattr(row, 'extratags', {}) - if 'place_type' in row: - extratags['place_type'] = row.place_type + if hasattr(row, 'place_type') and row.place_type: + extratags['place'] = row.place_type names = row.name if getattr(row, 'housenumber', None) is not None: @@ -333,7 +376,7 @@ async def complete_address_details(conn: SearchConnection, result: BaseResult) - sql = sa.select(sfn).order_by(sa.column('rank_address').desc(), sa.column('isaddress').desc()) - result.address_rows = [] + result.address_rows = AddressLines() for row in await conn.execute(sql): result.address_rows.append(_result_row_to_address_row(row)) @@ -357,7 +400,7 @@ def _placex_select_address_row(conn: SearchConnection, async def complete_linked_places(conn: SearchConnection, result: BaseResult) -> None: """ Retrieve information about places that link to the result. """ - result.linked_rows = [] + result.linked_rows = AddressLines() if result.source_table != SourceTable.PLACEX: return @@ -392,7 +435,7 @@ async def complete_parented_places(conn: SearchConnection, result: BaseResult) - """ Retrieve information about places that the result provides the address for. """ - result.parented_rows = [] + result.parented_rows = AddressLines() if result.source_table != SourceTable.PLACEX: return