]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/api/core.py
actions: pin pytest-asyncio version for Ubuntu 20
[nominatim.git] / nominatim / api / core.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2023 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Implementation of classes for API access via libraries.
9 """
10 from typing import Mapping, Optional, Any, AsyncIterator, Dict, Sequence, List, Tuple
11 import asyncio
12 import sys
13 import contextlib
14 from pathlib import Path
15
16 import sqlalchemy as sa
17 import sqlalchemy.ext.asyncio as sa_asyncio
18
19 from nominatim.errors import UsageError
20 from nominatim.db.sqlalchemy_schema import SearchTables
21 from nominatim.db.async_core_library import PGCORE_LIB, PGCORE_ERROR
22 from nominatim.config import Configuration
23 from nominatim.api.connection import SearchConnection
24 from nominatim.api.status import get_status, StatusResult
25 from nominatim.api.lookup import get_detailed_place, get_simple_place
26 from nominatim.api.reverse import ReverseGeocoder
27 from nominatim.api.search import ForwardGeocoder, Phrase, PhraseType, make_query_analyzer
28 import nominatim.api.types as ntyp
29 from nominatim.api.results import DetailedResult, ReverseResult, SearchResults
30
31
32 class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
33     """ The main frontend to the Nominatim database implements the
34         functions for lookup, forward and reverse geocoding using
35         asynchronous functions.
36
37         This class shares most of the functions with its synchronous
38         version. There are some additional functions or parameters,
39         which are documented below.
40     """
41     def __init__(self, project_dir: Path,
42                  environ: Optional[Mapping[str, str]] = None,
43                  loop: Optional[asyncio.AbstractEventLoop] = None) -> None:
44         """ Initiate a new frontend object with synchronous API functions.
45
46             Parameters:
47               project_dir: Path to the
48                   [project directory](../admin/Import.md#creating-the-project-directory)
49                   of the local Nominatim installation.
50               environ: Mapping of [configuration parameters](../customize/Settings.md).
51                   When set, replaces any configuration via environment variables.
52                   Settings in this mapping also have precedence over any
53                   parameters found in the `.env` file of the project directory.
54               loop: The asyncio event loop that will be used when calling
55                   functions. Only needed, when a custom event loop is used
56                   and the Python version is 3.9 or earlier.
57         """
58         self.config = Configuration(project_dir, environ)
59         self.query_timeout = self.config.get_int('QUERY_TIMEOUT') \
60                              if self.config.QUERY_TIMEOUT else None
61         self.reverse_restrict_to_country_area = self.config.get_bool('SEARCH_WITHIN_COUNTRIES')
62         self.server_version = 0
63
64         if sys.version_info >= (3, 10):
65             self._engine_lock = asyncio.Lock()
66         else:
67             self._engine_lock = asyncio.Lock(loop=loop) # pylint: disable=unexpected-keyword-arg
68         self._engine: Optional[sa_asyncio.AsyncEngine] = None
69         self._tables: Optional[SearchTables] = None
70         self._property_cache: Dict[str, Any] = {'DB:server_version': 0}
71
72
73     async def setup_database(self) -> None:
74         """ Set up the SQL engine and connections.
75
76             This function will be implicitly called when the database is
77             accessed for the first time. You may also call it explicitly to
78             avoid that the first call is delayed by the setup.
79         """
80         async with self._engine_lock:
81             if self._engine:
82                 return
83
84             extra_args: Dict[str, Any] = {'future': True,
85                                           'echo': self.config.get_bool('DEBUG_SQL')}
86
87             is_sqlite = self.config.DATABASE_DSN.startswith('sqlite:')
88
89             if is_sqlite:
90                 params = dict((p.split('=', 1)
91                               for p in self.config.DATABASE_DSN[7:].split(';')))
92                 dburl = sa.engine.URL.create('sqlite+aiosqlite',
93                                              database=params.get('dbname'))
94
95             else:
96                 dsn = self.config.get_database_params()
97                 query = {k: v for k, v in dsn.items()
98                          if k not in ('user', 'password', 'dbname', 'host', 'port')}
99
100                 dburl = sa.engine.URL.create(
101                            f'postgresql+{PGCORE_LIB}',
102                            database=dsn.get('dbname'),
103                            username=dsn.get('user'),
104                            password=dsn.get('password'),
105                            host=dsn.get('host'),
106                            port=int(dsn['port']) if 'port' in dsn else None,
107                            query=query)
108                 extra_args['max_overflow'] = 0
109                 extra_args['pool_size'] = self.config.get_int('API_POOL_SIZE')
110
111             engine = sa_asyncio.create_async_engine(dburl, **extra_args)
112
113             try:
114                 async with engine.begin() as conn:
115                     result = await conn.scalar(sa.text('SHOW server_version_num'))
116                     server_version = int(result)
117             except (PGCORE_ERROR, sa.exc.OperationalError):
118                 server_version = 0
119
120             if server_version >= 110000 and not is_sqlite:
121                 @sa.event.listens_for(engine.sync_engine, "connect")
122                 def _on_connect(dbapi_con: Any, _: Any) -> None:
123                     cursor = dbapi_con.cursor()
124                     cursor.execute("SET jit_above_cost TO '-1'")
125                     cursor.execute("SET max_parallel_workers_per_gather TO '0'")
126                 # Make sure that all connections get the new settings
127                 await self.close()
128
129             if is_sqlite:
130                 @sa.event.listens_for(engine.sync_engine, "connect")
131                 def _on_sqlite_connect(dbapi_con: Any, _: Any) -> None:
132                     dbapi_con.run_async(lambda conn: conn.enable_load_extension(True))
133                     cursor = dbapi_con.cursor()
134                     cursor.execute("SELECT load_extension('mod_spatialite')")
135                     cursor.execute('SELECT SetDecimalPrecision(7)')
136                     dbapi_con.run_async(lambda conn: conn.enable_load_extension(False))
137
138             self._property_cache['DB:server_version'] = server_version
139
140             self._tables = SearchTables(sa.MetaData(), engine.name) # pylint: disable=no-member
141             self._engine = engine
142
143
144     async def close(self) -> None:
145         """ Close all active connections to the database. The NominatimAPIAsync
146             object remains usable after closing. If a new API functions is
147             called, new connections are created.
148         """
149         if self._engine is not None:
150             await self._engine.dispose()
151
152
153     @contextlib.asynccontextmanager
154     async def begin(self) -> AsyncIterator[SearchConnection]:
155         """ Create a new connection with automatic transaction handling.
156
157             This function may be used to get low-level access to the database.
158             Refer to the documentation of SQLAlchemy for details how to use
159             the connection object.
160         """
161         if self._engine is None:
162             await self.setup_database()
163
164         assert self._engine is not None
165         assert self._tables is not None
166
167         async with self._engine.begin() as conn:
168             yield SearchConnection(conn, self._tables, self._property_cache)
169
170
171     async def status(self) -> StatusResult:
172         """ Return the status of the database.
173         """
174         try:
175             async with self.begin() as conn:
176                 conn.set_query_timeout(self.query_timeout)
177                 status = await get_status(conn)
178         except (PGCORE_ERROR, sa.exc.OperationalError):
179             return StatusResult(700, 'Database connection failed')
180
181         return status
182
183
184     async def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
185         """ Get detailed information about a place in the database.
186
187             Returns None if there is no entry under the given ID.
188         """
189         details = ntyp.LookupDetails.from_kwargs(params)
190         async with self.begin() as conn:
191             conn.set_query_timeout(self.query_timeout)
192             if details.keywords:
193                 await make_query_analyzer(conn)
194             return await get_detailed_place(conn, place, details)
195
196
197     async def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
198         """ Get simple information about a list of places.
199
200             Returns a list of place information for all IDs that were found.
201         """
202         details = ntyp.LookupDetails.from_kwargs(params)
203         async with self.begin() as conn:
204             conn.set_query_timeout(self.query_timeout)
205             if details.keywords:
206                 await make_query_analyzer(conn)
207             return SearchResults(filter(None,
208                                         [await get_simple_place(conn, p, details) for p in places]))
209
210
211     async def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
212         """ Find a place by its coordinates. Also known as reverse geocoding.
213
214             Returns the closest result that can be found or None if
215             no place matches the given criteria.
216         """
217         # The following negation handles NaN correctly. Don't change.
218         if not abs(coord[0]) <= 180 or not abs(coord[1]) <= 90:
219             # There are no results to be expected outside valid coordinates.
220             return None
221
222         details = ntyp.ReverseDetails.from_kwargs(params)
223         async with self.begin() as conn:
224             conn.set_query_timeout(self.query_timeout)
225             if details.keywords:
226                 await make_query_analyzer(conn)
227             geocoder = ReverseGeocoder(conn, details,
228                                        self.reverse_restrict_to_country_area)
229             return await geocoder.lookup(coord)
230
231
232     async def search(self, query: str, **params: Any) -> SearchResults:
233         """ Find a place by free-text search. Also known as forward geocoding.
234         """
235         query = query.strip()
236         if not query:
237             raise UsageError('Nothing to search for.')
238
239         async with self.begin() as conn:
240             conn.set_query_timeout(self.query_timeout)
241             geocoder = ForwardGeocoder(conn, ntyp.SearchDetails.from_kwargs(params),
242                                        self.config.get_int('REQUEST_TIMEOUT') \
243                                          if self.config.REQUEST_TIMEOUT else None)
244             phrases = [Phrase(PhraseType.NONE, p.strip()) for p in query.split(',')]
245             return await geocoder.lookup(phrases)
246
247
248     # pylint: disable=too-many-arguments,too-many-branches
249     async def search_address(self, amenity: Optional[str] = None,
250                              street: Optional[str] = None,
251                              city: Optional[str] = None,
252                              county: Optional[str] = None,
253                              state: Optional[str] = None,
254                              country: Optional[str] = None,
255                              postalcode: Optional[str] = None,
256                              **params: Any) -> SearchResults:
257         """ Find an address using structured search.
258         """
259         async with self.begin() as conn:
260             conn.set_query_timeout(self.query_timeout)
261             details = ntyp.SearchDetails.from_kwargs(params)
262
263             phrases: List[Phrase] = []
264
265             if amenity:
266                 phrases.append(Phrase(PhraseType.AMENITY, amenity))
267             if street:
268                 phrases.append(Phrase(PhraseType.STREET, street))
269             if city:
270                 phrases.append(Phrase(PhraseType.CITY, city))
271             if county:
272                 phrases.append(Phrase(PhraseType.COUNTY, county))
273             if state:
274                 phrases.append(Phrase(PhraseType.STATE, state))
275             if postalcode:
276                 phrases.append(Phrase(PhraseType.POSTCODE, postalcode))
277             if country:
278                 phrases.append(Phrase(PhraseType.COUNTRY, country))
279
280             if not phrases:
281                 raise UsageError('Nothing to search for.')
282
283             if amenity or street:
284                 details.restrict_min_max_rank(26, 30)
285             elif city:
286                 details.restrict_min_max_rank(13, 25)
287             elif county:
288                 details.restrict_min_max_rank(10, 12)
289             elif state:
290                 details.restrict_min_max_rank(5, 9)
291             elif postalcode:
292                 details.restrict_min_max_rank(5, 11)
293             else:
294                 details.restrict_min_max_rank(4, 4)
295
296             if 'layers' not in params:
297                 details.layers = ntyp.DataLayer.ADDRESS
298                 if amenity:
299                     details.layers |= ntyp.DataLayer.POI
300
301             geocoder = ForwardGeocoder(conn, details,
302                                        self.config.get_int('REQUEST_TIMEOUT') \
303                                          if self.config.REQUEST_TIMEOUT else None)
304             return await geocoder.lookup(phrases)
305
306
307     async def search_category(self, categories: List[Tuple[str, str]],
308                               near_query: Optional[str] = None,
309                               **params: Any) -> SearchResults:
310         """ Find an object of a certain category near another place.
311             The near place may either be given as an unstructured search
312             query in itself or as coordinates.
313         """
314         if not categories:
315             return SearchResults()
316
317         details = ntyp.SearchDetails.from_kwargs(params)
318         async with self.begin() as conn:
319             conn.set_query_timeout(self.query_timeout)
320             if near_query:
321                 phrases = [Phrase(PhraseType.NONE, p) for p in near_query.split(',')]
322             else:
323                 phrases = []
324                 if details.keywords:
325                     await make_query_analyzer(conn)
326
327             geocoder = ForwardGeocoder(conn, details,
328                                        self.config.get_int('REQUEST_TIMEOUT') \
329                                          if self.config.REQUEST_TIMEOUT else None)
330             return await geocoder.lookup_pois(categories, phrases)
331
332
333
334 class NominatimAPI:
335     """ This class provides a thin synchronous wrapper around the asynchronous
336         Nominatim functions. It creates its own event loop and runs each
337         synchronous function call to completion using that loop.
338     """
339
340     def __init__(self, project_dir: Path,
341                  environ: Optional[Mapping[str, str]] = None) -> None:
342         """ Initiate a new frontend object with synchronous API functions.
343
344             Parameters:
345               project_dir: Path to the
346                   [project directory](../admin/Import.md#creating-the-project-directory)
347                   of the local Nominatim installation.
348               environ: Mapping of [configuration parameters](../customize/Settings.md).
349                   When set, replaces any configuration via environment variables.
350                   Settings in this mapping also have precedence over any
351                   parameters found in the `.env` file of the project directory.
352         """
353         self._loop = asyncio.new_event_loop()
354         self._async_api = NominatimAPIAsync(project_dir, environ, loop=self._loop)
355
356
357     def close(self) -> None:
358         """ Close all active connections to the database.
359
360             This function also closes the asynchronous worker loop making
361             the NominatimAPI object unusuable.
362         """
363         self._loop.run_until_complete(self._async_api.close())
364         self._loop.close()
365
366
367     @property
368     def config(self) -> Configuration:
369         """ Provide read-only access to the [configuration](#Configuration)
370             used by the API.
371         """
372         return self._async_api.config
373
374     def status(self) -> StatusResult:
375         """ Return the status of the database as a dataclass object
376             with the fields described below.
377
378             Returns:
379               status(int): A status code as described on the status page.
380               message(str): Either 'OK' or a human-readable message of the
381                   problem encountered.
382               software_version(tuple): A tuple with the version of the
383                   Nominatim library consisting of (major, minor, patch, db-patch)
384                   version.
385               database_version(tuple): A tuple with the version of the library
386                   which was used for the import or last migration.
387                   Also consists of (major, minor, patch, db-patch).
388               data_updated(datetime): Timestamp with the age of the data.
389         """
390         return self._loop.run_until_complete(self._async_api.status())
391
392
393     def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
394         """ Get detailed information about a place in the database.
395
396             The result is a dataclass object with the fields described below
397             or `None` if the place could not be found in the database.
398
399             Parameters:
400               place: Description of the place to look up. See
401                      [Place identification](Input-Parameter-Types.md#place-identification)
402                      for the various ways to reference a place.
403
404             Other parameters:
405               geometry_output (enum): Add the full geometry of the place to the result.
406                 Multiple formats may be selected. Note that geometries can become
407                 quite large. (Default: none)
408               geometry_simplification (float): Simplification factor to use on
409                 the geometries before returning them. The factor expresses
410                 the tolerance in degrees from which the geometry may differ.
411                 Topology is preserved. (Default: 0.0)
412               address_details (bool): Add detailed information about the places
413                 that make up the address of the requested object. (Default: False)
414               linked_places (bool): Add detailed information about the places
415                 that link to the result. (Default: False)
416               parented_places (bool): Add detailed information about all places
417                 for which the requested object is a parent, i.e. all places for
418                 which the object provides the address details.
419                 Only POI places can have parents. (Default: False)
420               keywords (bool): Add detailed information about the search terms
421                 used for this place.
422
423             Returns:
424               source_table (enum): Data source of the place. See below for possible values.
425               category (tuple): A tuple of two strings with the primary OSM tag
426                   and value.
427               centroid (Point): Point position of the place.
428               place_id (Optional[int]): Internal ID of the place. This ID may differ
429                   for the same place between different installations.
430               parent_place_id (Optional(int]): Internal ID of the parent of this
431                   place. Only meaning full for POI-like objects (places with a
432                   rank_address of 30).
433               linked_place_id (Optional[int]): Internal ID of the place this object
434                   linkes to. When this ID is set then there is no guarantee that
435                   the rest of the result information is complete.
436               admin_level (int): Value of the `admin_level` OSM tag. Only meaningful
437                   for administrative boundary objects.
438               indexed_date (datetime): Timestamp when the place was last updated.
439               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
440               names (Optional[dict]): Dictionary of names of the place. Keys are
441                   usually the corresponding OSM tag keys.
442               address (Optional[dict]): Dictionary of address parts directly
443                   attributed to the place. Keys are usually the corresponding
444                   OSM tag keys with the `addr:` prefix removed.
445               extratags (Optional[dict]): Dictionary of additional attributes for
446                   the place. Usually OSM tag keys and values.
447               housenumber (Optional[str]): House number of the place, normalised
448                   for lookup. To get the house number in its original spelling,
449                   use `address['housenumber']`.
450               postcode (Optional[str]): Computed postcode for the place. To get
451                   directly attributed postcodes, use `address['postcode']` instead.
452               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
453                   The string has the format <language code>:<wikipedia title>.
454               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
455               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
456               importance (Optional[float]): Relative importance of the place. This is a measure
457                   how likely the place will be searched for.
458               country_code (Optional[str]): Country the feature is in as
459                   ISO 3166-1 alpha-2 country code.
460               address_rows (Optional[AddressLines]): List of places that make up the
461                   computed address. `None` when `address_details` parameter was False.
462               linked_rows (Optional[AddressLines]): List of places that link to the object.
463                   `None` when `linked_places` parameter was False.
464               parented_rows (Optional[AddressLines]): List of direct children of the place.
465                   `None` when `parented_places` parameter was False.
466               name_keywords (Optional[WordInfos]): List of search words for the name of
467                    the place. `None` when `keywords` parameter is set to False.
468               address_keywords (Optional[WordInfos]): List of search word for the address of
469                    the place. `None` when `keywords` parameter is set to False.
470               geometry (dict): Dictionary containing the full geometry of the place
471                    in the formats requested in the `geometry_output` parameter.
472         """
473         return self._loop.run_until_complete(self._async_api.details(place, **params))
474
475
476     def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
477         """ Get simple information about a list of places.
478
479             Returns a list of place information for all IDs that were found.
480             Each result is a dataclass with the fields detailed below.
481
482             Parameters:
483               places: List of descriptions of the place to look up. See
484                       [Place identification](Input-Parameter-Types.md#place-identification)
485                       for the various ways to reference a place.
486
487             Other parameters:
488               geometry_output (enum): Add the full geometry of the place to the result.
489                 Multiple formats may be selected. Note that geometries can become
490                 quite large. (Default: none)
491               geometry_simplification (float): Simplification factor to use on
492                 the geometries before returning them. The factor expresses
493                 the tolerance in degrees from which the geometry may differ.
494                 Topology is preserved. (Default: 0.0)
495               address_details (bool): Add detailed information about the places
496                 that make up the address of the requested object. (Default: False)
497               linked_places (bool): Add detailed information about the places
498                 that link to the result. (Default: False)
499               parented_places (bool): Add detailed information about all places
500                 for which the requested object is a parent, i.e. all places for
501                 which the object provides the address details.
502                 Only POI places can have parents. (Default: False)
503               keywords (bool): Add detailed information about the search terms
504                 used for this place.
505
506             Returns:
507               source_table (enum): Data source of the place. See below for possible values.
508               category (tuple): A tuple of two strings with the primary OSM tag
509                   and value.
510               centroid (Point): Point position of the place.
511               place_id (Optional[int]): Internal ID of the place. This ID may differ
512                   for the same place between different installations.
513               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
514               names (Optional[dict]): Dictionary of names of the place. Keys are
515                   usually the corresponding OSM tag keys.
516               address (Optional[dict]): Dictionary of address parts directly
517                   attributed to the place. Keys are usually the corresponding
518                   OSM tag keys with the `addr:` prefix removed.
519               extratags (Optional[dict]): Dictionary of additional attributes for
520                   the place. Usually OSM tag keys and values.
521               housenumber (Optional[str]): House number of the place, normalised
522                   for lookup. To get the house number in its original spelling,
523                   use `address['housenumber']`.
524               postcode (Optional[str]): Computed postcode for the place. To get
525                   directly attributed postcodes, use `address['postcode']` instead.
526               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
527                   The string has the format <language code>:<wikipedia title>.
528               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
529               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
530               importance (Optional[float]): Relative importance of the place. This is a measure
531                   how likely the place will be searched for.
532               country_code (Optional[str]): Country the feature is in as
533                   ISO 3166-1 alpha-2 country code.
534               address_rows (Optional[AddressLines]): List of places that make up the
535                   computed address. `None` when `address_details` parameter was False.
536               linked_rows (Optional[AddressLines]): List of places that link to the object.
537                   `None` when `linked_places` parameter was False.
538               parented_rows (Optional[AddressLines]): List of direct children of the place.
539                   `None` when `parented_places` parameter was False.
540               name_keywords (Optional[WordInfos]): List of search words for the name of
541                    the place. `None` when `keywords` parameter is set to False.
542               address_keywords (Optional[WordInfos]): List of search word for the address of
543                    the place. `None` when `keywords` parameter is set to False.
544               bbox (Bbox): Bounding box of the full geometry of the place.
545                    If the place is a single point, then the size of the bounding
546                    box is guessed according to the type of place.
547               geometry (dict): Dictionary containing the full geometry of the place
548                    in the formats requested in the `geometry_output` parameter.
549         """
550         return self._loop.run_until_complete(self._async_api.lookup(places, **params))
551
552
553     def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
554         """ Find a place by its coordinates. Also known as reverse geocoding.
555
556             Returns the closest result that can be found or `None` if
557             no place matches the given criteria. The result is a dataclass
558             with the fields as detailed below.
559
560             Parameters:
561               coord: Coordinate to lookup the place for as a Point
562                      or a tuple (x, y). Must be in WGS84 projection.
563
564             Other parameters:
565               max_rank (int): Highest address rank to return. Can be used to
566                 restrict search to streets or settlements.
567               layers (enum): Defines the kind of data to take into account.
568                 See description of layers below. (Default: addresses and POIs)
569               geometry_output (enum): Add the full geometry of the place to the result.
570                 Multiple formats may be selected. Note that geometries can become
571                 quite large. (Default: none)
572               geometry_simplification (float): Simplification factor to use on
573                 the geometries before returning them. The factor expresses
574                 the tolerance in degrees from which the geometry may differ.
575                 Topology is preserved. (Default: 0.0)
576               address_details (bool): Add detailed information about the places
577                 that make up the address of the requested object. (Default: False)
578               linked_places (bool): Add detailed information about the places
579                 that link to the result. (Default: False)
580               parented_places (bool): Add detailed information about all places
581                 for which the requested object is a parent, i.e. all places for
582                 which the object provides the address details.
583                 Only POI places can have parents. (Default: False)
584               keywords (bool): Add detailed information about the search terms
585                 used for this place.
586
587             Returns:
588               source_table (enum): Data source of the place. See below for possible values.
589               category (tuple): A tuple of two strings with the primary OSM tag
590                   and value.
591               centroid (Point): Point position of the place.
592               place_id (Optional[int]): Internal ID of the place. This ID may differ
593                   for the same place between different installations.
594               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
595               names (Optional[dict]): Dictionary of names of the place. Keys are
596                   usually the corresponding OSM tag keys.
597               address (Optional[dict]): Dictionary of address parts directly
598                   attributed to the place. Keys are usually the corresponding
599                   OSM tag keys with the `addr:` prefix removed.
600               extratags (Optional[dict]): Dictionary of additional attributes for
601                   the place. Usually OSM tag keys and values.
602               housenumber (Optional[str]): House number of the place, normalised
603                   for lookup. To get the house number in its original spelling,
604                   use `address['housenumber']`.
605               postcode (Optional[str]): Computed postcode for the place. To get
606                   directly attributed postcodes, use `address['postcode']` instead.
607               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
608                   The string has the format <language code>:<wikipedia title>.
609               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
610               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
611               importance (Optional[float]): Relative importance of the place. This is a measure
612                   how likely the place will be searched for.
613               country_code (Optional[str]): Country the feature is in as
614                   ISO 3166-1 alpha-2 country code.
615               address_rows (Optional[AddressLines]): List of places that make up the
616                   computed address. `None` when `address_details` parameter was False.
617               linked_rows (Optional[AddressLines]): List of places that link to the object.
618                   `None` when `linked_places` parameter was False.
619               parented_rows (Optional[AddressLines]): List of direct children of the place.
620                   `None` when `parented_places` parameter was False.
621               name_keywords (Optional[WordInfos]): List of search words for the name of
622                    the place. `None` when `keywords` parameter is set to False.
623               address_keywords (Optional[WordInfos]): List of search word for the address of
624                    the place. `None` when `keywords` parameter is set to False.
625               bbox (Bbox): Bounding box of the full geometry of the place.
626                    If the place is a single point, then the size of the bounding
627                    box is guessed according to the type of place.
628               geometry (dict): Dictionary containing the full geometry of the place
629                    in the formats requested in the `geometry_output` parameter.
630               distance (Optional[float]): Distance in degree from the input point.
631         """
632         return self._loop.run_until_complete(self._async_api.reverse(coord, **params))
633
634
635     def search(self, query: str, **params: Any) -> SearchResults:
636         """ Find a place by free-text search. Also known as forward geocoding.
637
638             Parameters:
639               query: Free-form text query searching for a place.
640
641             Other parameters:
642               max_results (int): Maximum number of results to return. The
643                 actual number of results may be less. (Default: 10)
644               min_rank (int): Lowest permissible rank for the result.
645                 For addressable places this is the minimum
646                 [address rank](../customize/Ranking.md#address-rank). For all
647                 other places the [search rank](../customize/Ranking.md#search-rank)
648                 is used.
649               max_rank (int): Highest permissible rank for the result. See min_rank above.
650               layers (enum): Defines the kind of data to take into account.
651                 See [layers section](Input-Parameter-Types.md#layers) for details.
652                 (Default: addresses and POIs)
653               countries (list[str]): Restrict search to countries with the given
654                 ISO 3166-1 alpha-2 country code. An empty list (the default)
655                 disables this filter.
656               excluded (list[int]): A list of internal IDs of places to exclude
657                 from the search.
658               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
659               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
660                 as a filter and return only results within the bounding box.
661               near (Optional[Point]): Focus search around the given point and
662                 return results ordered by distance to the given point.
663               near_radius (Optional[float]): Restrict results to results within
664                 the given distance in degrees of `near` point. Ignored, when
665                 `near` is not set.
666               categories (list[tuple]): Restrict search to places of the given
667                 categories. The category is the main OSM tag assigned to each
668                 place. An empty list (the default) disables this filter.
669               geometry_output (enum): Add the full geometry of the place to the result.
670                 Multiple formats may be selected. Note that geometries can become
671                 quite large. (Default: none)
672               geometry_simplification (float): Simplification factor to use on
673                 the geometries before returning them. The factor expresses
674                 the tolerance in degrees from which the geometry may differ.
675                 Topology is preserved. (Default: 0.0)
676               address_details (bool): Add detailed information about the places
677                 that make up the address of the requested object. (Default: False)
678               linked_places (bool): Add detailed information about the places
679                 that link to the result. (Default: False)
680               parented_places (bool): Add detailed information about all places
681                 for which the requested object is a parent, i.e. all places for
682                 which the object provides the address details.
683                 Only POI places can have parents. (Default: False)
684               keywords (bool): Add detailed information about the search terms
685                 used for this place.
686
687             Returns:
688               source_table (enum): Data source of the place. See below for possible values.
689               category (tuple): A tuple of two strings with the primary OSM tag
690                   and value.
691               centroid (Point): Point position of the place.
692               place_id (Optional[int]): Internal ID of the place. This ID may differ
693                   for the same place between different installations.
694               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
695               names (Optional[dict]): Dictionary of names of the place. Keys are
696                   usually the corresponding OSM tag keys.
697               address (Optional[dict]): Dictionary of address parts directly
698                   attributed to the place. Keys are usually the corresponding
699                   OSM tag keys with the `addr:` prefix removed.
700               extratags (Optional[dict]): Dictionary of additional attributes for
701                   the place. Usually OSM tag keys and values.
702               housenumber (Optional[str]): House number of the place, normalised
703                   for lookup. To get the house number in its original spelling,
704                   use `address['housenumber']`.
705               postcode (Optional[str]): Computed postcode for the place. To get
706                   directly attributed postcodes, use `address['postcode']` instead.
707               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
708                   The string has the format <language code>:<wikipedia title>.
709               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
710               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
711               importance (Optional[float]): Relative importance of the place. This is a measure
712                   how likely the place will be searched for.
713               country_code (Optional[str]): Country the feature is in as
714                   ISO 3166-1 alpha-2 country code.
715               address_rows (Optional[AddressLines]): List of places that make up the
716                   computed address. `None` when `address_details` parameter was False.
717               linked_rows (Optional[AddressLines]): List of places that link to the object.
718                   `None` when `linked_places` parameter was False.
719               parented_rows (Optional[AddressLines]): List of direct children of the place.
720                   `None` when `parented_places` parameter was False.
721               name_keywords (Optional[WordInfos]): List of search words for the name of
722                    the place. `None` when `keywords` parameter is set to False.
723               address_keywords (Optional[WordInfos]): List of search word for the address of
724                    the place. `None` when `keywords` parameter is set to False.
725               bbox (Bbox): Bounding box of the full geometry of the place.
726                    If the place is a single point, then the size of the bounding
727                    box is guessed according to the type of place.
728               geometry (dict): Dictionary containing the full geometry of the place
729                    in the formats requested in the `geometry_output` parameter.
730         """
731         return self._loop.run_until_complete(
732                    self._async_api.search(query, **params))
733
734
735     # pylint: disable=too-many-arguments
736     def search_address(self, amenity: Optional[str] = None,
737                        street: Optional[str] = None,
738                        city: Optional[str] = None,
739                        county: Optional[str] = None,
740                        state: Optional[str] = None,
741                        country: Optional[str] = None,
742                        postalcode: Optional[str] = None,
743                        **params: Any) -> SearchResults:
744         """ Find an address using structured search.
745
746             Parameters:
747               amenity: Name of a POI.
748               street: Street and optionally housenumber of the address. If the address
749                 does not have a street, then the place the housenumber references to.
750               city: Postal city of the address.
751               county: County equivalent of the address. Does not exist in all
752                 jurisdictions.
753               state: State or province of the address.
754               country: Country with its full name or its ISO 3166-1 alpha-2 country code.
755                 Do not use together with the country_code filter.
756               postalcode: Post code or ZIP for the place.
757
758             Other parameters:
759               max_results (int): Maximum number of results to return. The
760                 actual number of results may be less. (Default: 10)
761               min_rank (int): Lowest permissible rank for the result.
762                 For addressable places this is the minimum
763                 [address rank](../customize/Ranking.md#address-rank). For all
764                 other places the [search rank](../customize/Ranking.md#search-rank)
765                 is used.
766               max_rank (int): Highest permissible rank for the result. See min_rank above.
767               layers (enum): Defines the kind of data to take into account.
768                 See [layers section](Input-Parameter-Types.md#layers) for details.
769                 (Default: addresses and POIs)
770               countries (list[str]): Restrict search to countries with the given
771                 ISO 3166-1 alpha-2 country code. An empty list (the default)
772                 disables this filter. Do not use, when the country parameter
773                 is used.
774               excluded (list[int]): A list of internal IDs of places to exclude
775                 from the search.
776               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
777               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
778                 as a filter and return only results within the bounding box.
779               near (Optional[Point]): Focus search around the given point and
780                 return results ordered by distance to the given point.
781               near_radius (Optional[float]): Restrict results to results within
782                 the given distance in degrees of `near` point. Ignored, when
783                 `near` is not set.
784               categories (list[tuple]): Restrict search to places of the given
785                 categories. The category is the main OSM tag assigned to each
786                 place. An empty list (the default) disables this filter.
787               geometry_output (enum): Add the full geometry of the place to the result.
788                 Multiple formats may be selected. Note that geometries can become
789                 quite large. (Default: none)
790               geometry_simplification (float): Simplification factor to use on
791                 the geometries before returning them. The factor expresses
792                 the tolerance in degrees from which the geometry may differ.
793                 Topology is preserved. (Default: 0.0)
794               address_details (bool): Add detailed information about the places
795                 that make up the address of the requested object. (Default: False)
796               linked_places (bool): Add detailed information about the places
797                 that link to the result. (Default: False)
798               parented_places (bool): Add detailed information about all places
799                 for which the requested object is a parent, i.e. all places for
800                 which the object provides the address details.
801                 Only POI places can have parents. (Default: False)
802               keywords (bool): Add detailed information about the search terms
803                 used for this place.
804
805             Returns:
806               source_table (enum): Data source of the place. See below for possible values.
807               category (tuple): A tuple of two strings with the primary OSM tag
808                   and value.
809               centroid (Point): Point position of the place.
810               place_id (Optional[int]): Internal ID of the place. This ID may differ
811                   for the same place between different installations.
812               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
813               names (Optional[dict]): Dictionary of names of the place. Keys are
814                   usually the corresponding OSM tag keys.
815               address (Optional[dict]): Dictionary of address parts directly
816                   attributed to the place. Keys are usually the corresponding
817                   OSM tag keys with the `addr:` prefix removed.
818               extratags (Optional[dict]): Dictionary of additional attributes for
819                   the place. Usually OSM tag keys and values.
820               housenumber (Optional[str]): House number of the place, normalised
821                   for lookup. To get the house number in its original spelling,
822                   use `address['housenumber']`.
823               postcode (Optional[str]): Computed postcode for the place. To get
824                   directly attributed postcodes, use `address['postcode']` instead.
825               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
826                   The string has the format <language code>:<wikipedia title>.
827               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
828               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
829               importance (Optional[float]): Relative importance of the place. This is a measure
830                   how likely the place will be searched for.
831               country_code (Optional[str]): Country the feature is in as
832                   ISO 3166-1 alpha-2 country code.
833               address_rows (Optional[AddressLines]): List of places that make up the
834                   computed address. `None` when `address_details` parameter was False.
835               linked_rows (Optional[AddressLines]): List of places that link to the object.
836                   `None` when `linked_places` parameter was False.
837               parented_rows (Optional[AddressLines]): List of direct children of the place.
838                   `None` when `parented_places` parameter was False.
839               name_keywords (Optional[WordInfos]): List of search words for the name of
840                    the place. `None` when `keywords` parameter is set to False.
841               address_keywords (Optional[WordInfos]): List of search word for the address of
842                    the place. `None` when `keywords` parameter is set to False.
843               bbox (Bbox): Bounding box of the full geometry of the place.
844                    If the place is a single point, then the size of the bounding
845                    box is guessed according to the type of place.
846               geometry (dict): Dictionary containing the full geometry of the place
847                    in the formats requested in the `geometry_output` parameter.
848         """
849         return self._loop.run_until_complete(
850                    self._async_api.search_address(amenity, street, city, county,
851                                                   state, country, postalcode, **params))
852
853
854     def search_category(self, categories: List[Tuple[str, str]],
855                         near_query: Optional[str] = None,
856                         **params: Any) -> SearchResults:
857         """ Find an object of a certain category near another place.
858
859             The near place may either be given as an unstructured search
860             query in itself or as a geographic area through the
861             viewbox or near parameters.
862
863             Parameters:
864               categories: Restrict search to places of the given
865                 categories. The category is the main OSM tag assigned to each
866                 place.
867               near_query: Optional free-text query to define the are to
868                 restrict search to.
869
870             Other parameters:
871               max_results (int): Maximum number of results to return. The
872                 actual number of results may be less. (Default: 10)
873               min_rank (int): Lowest permissible rank for the result.
874                 For addressable places this is the minimum
875                 [address rank](../customize/Ranking.md#address-rank). For all
876                 other places the [search rank](../customize/Ranking.md#search-rank)
877                 is used.
878               max_rank (int): Highest permissible rank for the result. See min_rank above.
879               layers (enum): Defines the kind of data to take into account.
880                 See [layers section](Input-Parameter-Types.md#layers) for details.
881                 (Default: addresses and POIs)
882               countries (list[str]): Restrict search to countries with the given
883                 ISO 3166-1 alpha-2 country code. An empty list (the default)
884                 disables this filter.
885               excluded (list[int]): A list of internal IDs of places to exclude
886                 from the search.
887               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
888               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
889                 as a filter and return only results within the bounding box.
890               near (Optional[Point]): Focus search around the given point and
891                 return results ordered by distance to the given point.
892               near_radius (Optional[float]): Restrict results to results within
893                 the given distance in degrees of `near` point. Ignored, when
894                 `near` is not set.
895               geometry_output (enum): Add the full geometry of the place to the result.
896                 Multiple formats may be selected. Note that geometries can become
897                 quite large. (Default: none)
898               geometry_simplification (float): Simplification factor to use on
899                 the geometries before returning them. The factor expresses
900                 the tolerance in degrees from which the geometry may differ.
901                 Topology is preserved. (Default: 0.0)
902               address_details (bool): Add detailed information about the places
903                 that make up the address of the requested object. (Default: False)
904               linked_places (bool): Add detailed information about the places
905                 that link to the result. (Default: False)
906               parented_places (bool): Add detailed information about all places
907                 for which the requested object is a parent, i.e. all places for
908                 which the object provides the address details.
909                 Only POI places can have parents. (Default: False)
910               keywords (bool): Add detailed information about the search terms
911                 used for this place.
912
913             Returns:
914               source_table (enum): Data source of the place. See below for possible values.
915               category (tuple): A tuple of two strings with the primary OSM tag
916                   and value.
917               centroid (Point): Point position of the place.
918               place_id (Optional[int]): Internal ID of the place. This ID may differ
919                   for the same place between different installations.
920               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
921               names (Optional[dict]): Dictionary of names of the place. Keys are
922                   usually the corresponding OSM tag keys.
923               address (Optional[dict]): Dictionary of address parts directly
924                   attributed to the place. Keys are usually the corresponding
925                   OSM tag keys with the `addr:` prefix removed.
926               extratags (Optional[dict]): Dictionary of additional attributes for
927                   the place. Usually OSM tag keys and values.
928               housenumber (Optional[str]): House number of the place, normalised
929                   for lookup. To get the house number in its original spelling,
930                   use `address['housenumber']`.
931               postcode (Optional[str]): Computed postcode for the place. To get
932                   directly attributed postcodes, use `address['postcode']` instead.
933               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
934                   The string has the format <language code>:<wikipedia title>.
935               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
936               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
937               importance (Optional[float]): Relative importance of the place. This is a measure
938                   how likely the place will be searched for.
939               country_code (Optional[str]): Country the feature is in as
940                   ISO 3166-1 alpha-2 country code.
941               address_rows (Optional[AddressLines]): List of places that make up the
942                   computed address. `None` when `address_details` parameter was False.
943               linked_rows (Optional[AddressLines]): List of places that link to the object.
944                   `None` when `linked_places` parameter was False.
945               parented_rows (Optional[AddressLines]): List of direct children of the place.
946                   `None` when `parented_places` parameter was False.
947               name_keywords (Optional[WordInfos]): List of search words for the name of
948                    the place. `None` when `keywords` parameter is set to False.
949               address_keywords (Optional[WordInfos]): List of search word for the address of
950                    the place. `None` when `keywords` parameter is set to False.
951               bbox (Bbox): Bounding box of the full geometry of the place.
952                    If the place is a single point, then the size of the bounding
953                    box is guessed according to the type of place.
954               geometry (dict): Dictionary containing the full geometry of the place
955                    in the formats requested in the `geometry_output` parameter.
956         """
957         return self._loop.run_until_complete(
958                    self._async_api.search_category(categories, near_query, **params))