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