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