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