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