]> git.openstreetmap.org Git - nominatim.git/commitdiff
python lookup: factor out finding in tables into own function
authorSarah Hoffmann <lonvia@denofr.de>
Mon, 3 Apr 2023 08:00:42 +0000 (10:00 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Mon, 3 Apr 2023 12:40:41 +0000 (14:40 +0200)
nominatim/api/core.py
nominatim/api/lookup.py

index 6d47d332371fffd1cbfae42deecfe695848e04ec..d00e6639da202ef15b7236a903b369c2c870d3b7 100644 (file)
@@ -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.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
 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:
             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,
 
 
     async def reverse(self, coord: AnyPoint, max_rank: Optional[int] = None,
index 1b0ee87f29607fe66c48a9237b253861d6ae52e4..5c54da4a1823209a9dcede95a7f3fd730b957a4d 100644 (file)
@@ -7,7 +7,7 @@
 """
 Implementation of place lookup by ID.
 """
 """
 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
 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
 
 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
 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()
 
 
     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)
     """ 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.")
 
     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
 
     # add missing details
     assert result is not None