X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/a413aae8a3962be4d623844d867604df68a9a211..d5b6042118504e6419a557c99685381914161732:/nominatim/api/search/geocoder.py diff --git a/nominatim/api/search/geocoder.py b/nominatim/api/search/geocoder.py index 5e90d408..f88bffbd 100644 --- a/nominatim/api/search/geocoder.py +++ b/nominatim/api/search/geocoder.py @@ -9,6 +9,7 @@ Public interface to the search code. """ from typing import List, Any, Optional, Iterator, Tuple import itertools +import datetime as dt from nominatim.api.connection import SearchConnection from nominatim.api.types import SearchDetails @@ -24,9 +25,11 @@ class ForwardGeocoder: """ Main class responsible for place search. """ - def __init__(self, conn: SearchConnection, params: SearchDetails) -> None: + def __init__(self, conn: SearchConnection, + params: SearchDetails, timeout: Optional[int]) -> None: self.conn = conn self.params = params + self.timeout = dt.timedelta(seconds=timeout or 1000000) self.query_analyzer: Optional[AbstractQueryAnalyzer] = None @@ -55,8 +58,9 @@ class ForwardGeocoder: num_searches = 0 for assignment in yield_token_assignments(query): searches.extend(search_builder.build(assignment)) - log().table_dump('Searches for assignment', - _dump_searches(searches, query, num_searches)) + if num_searches < len(searches): + log().table_dump('Searches for assignment', + _dump_searches(searches, query, num_searches)) num_searches = len(searches) searches.sort(key=lambda s: s.penalty) @@ -70,6 +74,7 @@ class ForwardGeocoder: """ log().section('Execute database searches') results = SearchResults() + end_time = dt.datetime.now() + self.timeout num_results = 0 min_ranking = 1000.0 @@ -84,6 +89,8 @@ class ForwardGeocoder: log().result_dump('Results', ((r.accuracy, r) for r in results[num_results:])) num_results = len(results) prev_penalty = search.penalty + if dt.datetime.now() >= end_time: + break if results: min_ranking = min(r.ranking for r in results) @@ -151,7 +158,8 @@ class ForwardGeocoder: # pylint: disable=invalid-name,too-many-locals def _dump_searches(searches: List[AbstractSearch], query: QueryStruct, start: int = 0) -> Iterator[Optional[List[Any]]]: - yield ['Penalty', 'Lookups', 'Housenr', 'Postcode', 'Countries', 'Qualifier', 'Rankings'] + yield ['Penalty', 'Lookups', 'Housenr', 'Postcode', 'Countries', + 'Qualifier', 'Catgeory', 'Rankings'] def tk(tl: List[int]) -> str: tstr = [f"{query.find_lookup_word_by_id(t)}({t})" for t in tl] @@ -180,12 +188,19 @@ def _dump_searches(searches: List[AbstractSearch], query: QueryStruct, return f'{c[0]}^{c[1]}' for search in searches[start:]: - fields = ('name_lookups', 'name_ranking', 'countries', 'housenumbers', - 'postcodes', 'qualifier') - iters = itertools.zip_longest([f"{search.penalty:.3g}"], - *(getattr(search, attr, []) for attr in fields), - fillvalue= '') - for penalty, lookup, rank, cc, hnr, pc, qual in iters: + fields = ('lookups', 'rankings', 'countries', 'housenumbers', + 'postcodes', 'qualifiers') + if hasattr(search, 'search'): + iters = itertools.zip_longest([f"{search.penalty:.3g}"], + *(getattr(search.search, attr, []) for attr in fields), + getattr(search, 'categories', []), + fillvalue='') + else: + iters = itertools.zip_longest([f"{search.penalty:.3g}"], + *(getattr(search, attr, []) for attr in fields), + [], + fillvalue='') + for penalty, lookup, rank, cc, hnr, pc, qual, cat in iters: yield [penalty, fmt_lookup(lookup), fmt_cstr(hnr), - fmt_cstr(pc), fmt_cstr(cc), fmt_cstr(qual), fmt_ranking(rank)] + fmt_cstr(pc), fmt_cstr(cc), fmt_cstr(qual), fmt_cstr(cat), fmt_ranking(rank)] yield None