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