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