From 63638eb44745fc2e2aa4803d01ac868dd04a36a9 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 3 Apr 2023 10:00:42 +0200 Subject: [PATCH] python lookup: factor out finding in tables into own function --- nominatim/api/core.py | 4 +-- nominatim/api/lookup.py | 63 +++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/nominatim/api/core.py b/nominatim/api/core.py index 6d47d332..d00e6639 100644 --- a/nominatim/api/core.py +++ b/nominatim/api/core.py @@ -20,7 +20,7 @@ from nominatim.db.sqlalchemy_schema import SearchTables from nominatim.config import Configuration from nominatim.api.connection import SearchConnection from nominatim.api.status import get_status, StatusResult -from nominatim.api.lookup import get_place_by_id +from nominatim.api.lookup import get_detailed_place from nominatim.api.reverse import ReverseGeocoder from nominatim.api.types import PlaceRef, LookupDetails, AnyPoint, DataLayer from nominatim.api.results import DetailedResult, ReverseResult @@ -137,7 +137,7 @@ class NominatimAPIAsync: Returns None if there is no entry under the given ID. """ async with self.begin() as conn: - return await get_place_by_id(conn, place, details or LookupDetails()) + return await get_detailed_place(conn, place, details or LookupDetails()) async def reverse(self, coord: AnyPoint, max_rank: Optional[int] = None, diff --git a/nominatim/api/lookup.py b/nominatim/api/lookup.py index 1b0ee87f..5c54da4a 100644 --- a/nominatim/api/lookup.py +++ b/nominatim/api/lookup.py @@ -7,7 +7,7 @@ """ Implementation of place lookup by ID. """ -from typing import Optional +from typing import Optional, Callable, Tuple, Type import datetime as dt import sqlalchemy as sa @@ -18,6 +18,8 @@ import nominatim.api.types as ntyp import nominatim.api.results as nres from nominatim.api.logging import log +RowFunc = Callable[[Optional[SaRow], Type[nres.BaseResultT]], Optional[nres.BaseResultT]] + def _select_column_geometry(column: SaColumn, geometry_output: ntyp.GeometryFormat) -> SaLabel: """ Create the appropriate column expression for selecting a @@ -140,8 +142,34 @@ async def find_in_postcode(conn: SearchConnection, place: ntyp.PlaceRef, return (await conn.execute(sql)).one_or_none() -async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef, - details: ntyp.LookupDetails) -> Optional[nres.DetailedResult]: +async def find_in_all_tables(conn: SearchConnection, place: ntyp.PlaceRef, + details: ntyp.LookupDetails + ) -> Tuple[Optional[SaRow], RowFunc[nres.BaseResultT]]: + """ Search for the given place in all data tables + and return the base information. + """ + row = await find_in_placex(conn, place, details) + log().var_dump('Result (placex)', row) + if row is not None: + return row, nres.create_from_placex_row + + row = await find_in_osmline(conn, place, details) + log().var_dump('Result (osmline)', row) + if row is not None: + return row, nres.create_from_osmline_row + + row = await find_in_postcode(conn, place, details) + log().var_dump('Result (postcode)', row) + if row is not None: + return row, nres.create_from_postcode_row + + row = await find_in_tiger(conn, place, details) + log().var_dump('Result (tiger)', row) + return row, nres.create_from_tiger_row + + +async def get_detailed_place(conn: SearchConnection, place: ntyp.PlaceRef, + details: ntyp.LookupDetails) -> Optional[nres.DetailedResult]: """ Retrieve a place with additional details from the database. """ log().function('get_place_by_id', place=place, details=details) @@ -149,27 +177,14 @@ async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef, if details.geometry_output and details.geometry_output != ntyp.GeometryFormat.GEOJSON: raise ValueError("lookup only supports geojosn polygon output.") - row = await find_in_placex(conn, place, details) - log().var_dump('Result (placex)', row) - if row is not None: - result = nres.create_from_placex_row(row, nres.DetailedResult) - else: - row = await find_in_osmline(conn, place, details) - log().var_dump('Result (osmline)', row) - if row is not None: - result = nres.create_from_osmline_row(row, nres.DetailedResult) - else: - row = await find_in_postcode(conn, place, details) - log().var_dump('Result (postcode)', row) - if row is not None: - result = nres.create_from_postcode_row(row, nres.DetailedResult) - else: - row = await find_in_tiger(conn, place, details) - log().var_dump('Result (tiger)', row) - if row is not None: - result = nres.create_from_tiger_row(row, nres.DetailedResult) - else: - return None + row_func: RowFunc[nres.DetailedResult] + row, row_func = await find_in_all_tables(conn, place, details) + + if row is None: + return None + + result = row_func(row, nres.DetailedResult) + assert result is not None # add missing details assert result is not None -- 2.39.5