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