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