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