X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/2e56182a7f2837ee09ca08a3c0ac67557b62114f..95c3181a350538317678d5fef5122ed4b284b012:/nominatim/api/reverse.py?ds=sidebyside diff --git a/nominatim/api/reverse.py b/nominatim/api/reverse.py index 4a5f9c03..d46733f0 100644 --- a/nominatim/api/reverse.py +++ b/nominatim/api/reverse.py @@ -57,6 +57,7 @@ def _select_from_placex(t: SaFromClause, use_wkt: bool = True) -> SaSelect: t.c.importance, t.c.wikipedia, t.c.parent_place_id, t.c.rank_address, t.c.rank_search, centroid, + t.c.linked_place_id, t.c.admin_level, distance.label('distance'), t.c.geometry.ST_Expand(0).label('bbox')) @@ -87,7 +88,7 @@ def _locate_interpolation(table: SaFromClause) -> SaLabel: def _is_address_point(table: SaFromClause) -> SaColumn: return sa.and_(table.c.rank_address == 30, sa.or_(table.c.housenumber != None, - table.c.name.has_key('housename'))) + table.c.name.has_key('addr:housename'))) def _get_closest(*rows: Optional[SaRow]) -> Optional[SaRow]: @@ -99,9 +100,11 @@ class ReverseGeocoder: coordinate. """ - def __init__(self, conn: SearchConnection, params: ReverseDetails) -> None: + def __init__(self, conn: SearchConnection, params: ReverseDetails, + restrict_to_country_areas: bool = False) -> None: self.conn = conn self.params = params + self.restrict_to_country_areas = restrict_to_country_areas self.bind_params: Dict[str, Any] = {'max_rank': params.max_rank} @@ -477,16 +480,24 @@ class ReverseGeocoder: return _get_closest(address_row, other_row) - async def lookup_country(self) -> Optional[SaRow]: + async def lookup_country_codes(self) -> List[str]: """ Lookup the country for the current search. """ log().section('Reverse lookup by country code') t = self.conn.t.country_grid - sql: SaLambdaSelect = sa.select(t.c.country_code).distinct()\ + sql = sa.select(t.c.country_code).distinct()\ .where(t.c.geometry.ST_Contains(WKT_PARAM)) - ccodes = tuple((r[0] for r in await self.conn.execute(sql, self.bind_params))) + ccodes = [cast(str, r[0]) for r in await self.conn.execute(sql, self.bind_params)] log().var_dump('Country codes', ccodes) + return ccodes + + + async def lookup_country(self, ccodes: List[str]) -> Optional[SaRow]: + """ Lookup the country for the current search. + """ + if not ccodes: + ccodes = await self.lookup_country_codes() if not ccodes: return None @@ -516,7 +527,7 @@ class ReverseGeocoder: .order_by(sa.desc(inner.c.rank_search), inner.c.distance)\ .limit(1) - sql = sa.lambda_stmt(_base_query) + sql: SaLambdaSelect = sa.lambda_stmt(_base_query) if self.has_geometries(): sql = self._add_geometry_columns(sql, sa.literal_column('area.geometry')) @@ -559,10 +570,19 @@ class ReverseGeocoder: row, tmp_row_func = await self.lookup_street_poi() if row is not None: row_func = tmp_row_func - if row is None and self.max_rank > 4: - row = await self.lookup_area() - if row is None and self.layer_enabled(DataLayer.ADDRESS): - row = await self.lookup_country() + + if row is None: + if self.restrict_to_country_areas: + ccodes = await self.lookup_country_codes() + if not ccodes: + return None + else: + ccodes = [] + + if self.max_rank > 4: + row = await self.lookup_area() + if row is None and self.layer_enabled(DataLayer.ADDRESS): + row = await self.lookup_country(ccodes) result = row_func(row, nres.ReverseResult) if result is not None: