diff --git a/docs/library/Getting-Started.md b/docs/library/Getting-Started.md index 38517b14..6c187839 100644 --- a/docs/library/Getting-Started.md +++ b/docs/library/Getting-Started.md @@ -9,20 +9,78 @@ also less constraints on the kinds of data that can be accessed. The library allows to get access to more detailed information about the objects saved in the database. +!!! danger + The library interface is currently in an experimental stage. There might + be some smaller adjustments to the public interface until the next version. + + The library also misses a proper installation routine, so some manipulation + of the PYTHONPATH is required. Use is only recommended for advanced Python + programmers at the moment. + ## Installation To use the Nominatim library, you need access to a local Nominatim database. Follow the [installation and import instructions](../admin/) to set up your database. -!!! warning - Access to the library is currently still experimental. It is not yet - possible to install it in the usual way via pip or inside a virtualenv. - To get access to the library you need to set an appropriate PYTHONPATH. - With the default installation, the python library can be found under - `/usr/local/share/nominatim/lib-python`. If you have installed Nominatim - under a different prefix, adapt the `/usr/local/` part accordingly. - You can also point the PYTHONPATH to the Nominatim source code. +It is not yet possible to install it in the usual way via pip or inside a +virtualenv. To get access to the library you need to set an appropriate +PYTHONPATH. With the default installation, the python library can be found +under `/usr/local/share/nominatim/lib-python`. If you have installed +Nominatim under a different prefix, adapt the `/usr/local/` part accordingly. +You can also point the PYTHONPATH to the Nominatim source code. + + +### A simple search example + +To query the Nominatim database you need to first set up a connection. This +is done by creating an Nominatim API object. This object exposes all the +search functions of Nominatim that are also knwon from its web API. + +This code snippet implements a simple search for the town if 'Brugge': + +=== "NominatimAPIAsync" + ``` + from pathlib import Path + import asyncio + + import nominatim.api as napi + + async def search(query): + api = napi.NominatimAPIAsync(Path('.')) + + return await api.search(query) + + results = asyncio.run(search('Brugge')) + if not results: + print('Cannot find Brugge') + else: + print(f'Found a place at {results[0].centroid.x},{results[1].centroid.y}') + ``` + +=== "NominatimAPI" + ``` + from pathlib import Path + + import nominatim.api as napi + + api = napi.NominatimAPI(Path('.')) + + results = api.search('Brugge') + + if not results: + print('Cannot find Brugge') + else: + print(f'Found a place at {results[0].centroid.x},{results[1].centroid.y}') + ``` + +The Nonminatim API comes in two flavours: synchronous and asynchronous. +The complete Nominatim library is written so that it can work asynchronously. +If you have many requests to make, coroutines can speed up your applications +significantly. + +For smaller scripts there is also a sychronous wrapper around the API. + +### Defining which database to use + - A proper installation as a Python library will follow in the next - version. diff --git a/docs/library/Input-Parameter-Types.md b/docs/library/Input-Parameter-Types.md index dae560b2..5ee11425 100644 --- a/docs/library/Input-Parameter-Types.md +++ b/docs/library/Input-Parameter-Types.md @@ -49,8 +49,14 @@ types for place identification. All types are dataclasses. ## Layers +Layers allow to restrict the search result to thematic groups. This is +orthogonal to restriction by address ranks, which groups places by their +geographic extent. + + ::: nominatim.api.DataLayer options: heading_level: 6 + members_order: source diff --git a/docs/library/Result-Handling.md b/docs/library/Result-Handling.md index e2e0bc91..af2a8184 100644 --- a/docs/library/Result-Handling.md +++ b/docs/library/Result-Handling.md @@ -1,12 +1,47 @@ # Result handling +The search functions of the Nominatim API always return a result object that +contains the full raw information about the place that is available in the +database. This section discusses data types used in the results and utility +functions that allow further processing of the results. + +## Result fields + +### Sources + +Nominatim takes the result data from multiple souces. The `source_table` field +in the result describes, from which source the result was retrived. + ::: nominatim.api.SourceTable options: heading_level: 6 + members_order: source + +### Detailed address description + +When the `address_details` parameter is set, then functions return not +only information about the result place but also about the place that +make up the address. This information is almost always required, when you +want to present the user with a human-readable description of the result. +See also [Localization](#localization) below. + +The address details are available in the `address_rows` field as a ordered +list of `AddressLine` objects with the country information last. The list also +contains the result place itself and some artificial entries, for example, +for the housenumber or the country code. This makes processing and creating +a full address easiert. ::: nominatim.api.AddressLine options: heading_level: 6 + members_order: source + +### Detailed search terms + +The `details` function can return detailed information about which search terms +may be used to find a place, when the `keywords` parameter is set. Search +terms are split into terms for the name of the place and search terms for +its address. ::: nominatim.api.WordInfo options: diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index c3af00bd..45e4f5da 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -58,6 +58,7 @@ markdown_extensions: - codehilite - admonition - pymdownx.superfences + - pymdownx.tabbed - def_list - toc: permalink:  diff --git a/nominatim/api/core.py b/nominatim/api/core.py index f17973dc..fe7cfa3a 100644 --- a/nominatim/api/core.py +++ b/nominatim/api/core.py @@ -617,10 +617,15 @@ class NominatimAPI: Other parameters: max_results (int): Maximum number of results to return. The actual number of results may be less. (Default: 10) - min_rank (int): Lowest [address rank](../customize/Ranking.md#address-rank) to return. - max_rank (int): Highest address rank to return. + min_rank (int): Lowest permissible rank for the result. + For addressable places this is the minimum + [address rank](../customize/Ranking.md#address-rank). For all + other places the [search rank](../customize/Ranking.md#search-rank) + is used. + max_rank (int): Highest permissible rank for the result. See min_rank above. layers (enum): Defines the kind of data to take into account. - See description of layers below. (Default: addresses and POIs) + See [layers section](Input-Parameter-Types.md#layers) for details. + (Default: addresses and POIs) countries (list[str]): Restrict search to countries with the given ISO 3166-1 alpha-2 country code. An empty list (the default) disables this filter. @@ -729,10 +734,15 @@ class NominatimAPI: Other parameters: max_results (int): Maximum number of results to return. The actual number of results may be less. (Default: 10) - min_rank (int): Lowest [address rank](../customize/Ranking.md#address-rank) to return. - max_rank (int): Highest address rank to return. + min_rank (int): Lowest permissible rank for the result. + For addressable places this is the minimum + [address rank](../customize/Ranking.md#address-rank). For all + other places the [search rank](../customize/Ranking.md#search-rank) + is used. + max_rank (int): Highest permissible rank for the result. See min_rank above. layers (enum): Defines the kind of data to take into account. - See description of layers below. (Default: addresses and POIs) + See [layers section](Input-Parameter-Types.md#layers) for details. + (Default: addresses and POIs) countries (list[str]): Restrict search to countries with the given ISO 3166-1 alpha-2 country code. An empty list (the default) disables this filter. Do not use, when the country parameter @@ -836,10 +846,15 @@ class NominatimAPI: Other parameters: max_results (int): Maximum number of results to return. The actual number of results may be less. (Default: 10) - min_rank (int): Lowest [address rank](../customize/Ranking.md#address-rank) to return. - max_rank (int): Highest address rank to return. + min_rank (int): Lowest permissible rank for the result. + For addressable places this is the minimum + [address rank](../customize/Ranking.md#address-rank). For all + other places the [search rank](../customize/Ranking.md#search-rank) + is used. + max_rank (int): Highest permissible rank for the result. See min_rank above. layers (enum): Defines the kind of data to take into account. - See description of layers below. (Default: addresses and POIs) + See [layers section](Input-Parameter-Types.md#layers) for details. + (Default: addresses and POIs) countries (list[str]): Restrict search to countries with the given ISO 3166-1 alpha-2 country code. An empty list (the default) disables this filter. diff --git a/nominatim/api/results.py b/nominatim/api/results.py index d425ff6c..18df486f 100644 --- a/nominatim/api/results.py +++ b/nominatim/api/results.py @@ -46,32 +46,88 @@ def _mingle_name_tags(names: Optional[Dict[str, str]]) -> Optional[Dict[str, str class SourceTable(enum.Enum): - """ Enumeration of kinds of results. + """ The `SourceTable` type lists the possible sources a result can have. """ PLACEX = 1 + """ The placex table is the main source for result usually containing + OSM data. + """ OSMLINE = 2 + """ The osmline table contains address interpolations from OSM data. + Interpolation addresses are always approximate. The OSM id in the + result refers to the OSM way with the interpolation line object. + """ TIGER = 3 + """ TIGER address data contains US addresses imported on the side, + see [Installing TIGER data](../../customize/Tiger.md). + TIGER address are also interpolations. The addresses always refer + to a street from OSM data. The OSM id in the result refers to + that street. + """ POSTCODE = 4 + """ The postcode table contains artificial centroids for postcodes, + computed from the postcodes available with address points. Results + are always approximate. + """ COUNTRY = 5 + """ The country table provides a fallback, when country data is missing + in the OSM data. + """ @dataclasses.dataclass class AddressLine: - """ Detailed information about a related place. + """ The `AddressLine` may contain the following fields about a related place + and its function as an address object. Most fields are optional. + Their presence depends on the kind and function of the address part. """ place_id: Optional[int] + """ Internal ID of the place. + """ osm_object: Optional[Tuple[str, int]] + """ OSM type and ID of the place, if such an object exists. + """ category: Tuple[str, str] + """ Main category of the place, described by a key-value pair. + """ names: Dict[str, str] + """ All available names for the place including references, alternative + names and translations. + """ extratags: Optional[Dict[str, str]] + """ Any extra information available about the place. This is a dictionary + that usually contains OSM tag key-value pairs. + """ admin_level: Optional[int] + """ The administrative level of a boundary as tagged in the input data. + This field is only meaningful for places of the category + (boundary, administrative). + """ fromarea: bool + """ If true, then the exact area of the place is known. Without area + information, Nominatim has to make an educated guess if an address + belongs to one place or another. + """ isaddress: bool + """ If true, this place should be considered for the final address display. + Nominatim will sometimes include more than one candidate for + the address in the list when it cannot reliably determine where the + place belongs. It will consider names of all candidates when searching + but when displaying the result, only the most likely candidate should + be shown. + """ rank_address: int + """ [Address rank](../customize/Ranking.md#address-rank) of the place. + """ distance: float + """ Distance in degrees between the result place and this address part. + """ local_name: Optional[str] = None + """ Place holder for localization of this address part. See + [Localization](#localization) below. + """ class AddressLines(List[AddressLine]): @@ -80,7 +136,7 @@ class AddressLines(List[AddressLine]): def localize(self, locales: Locales) -> List[str]: """ Set the local name of address parts according to the chosen - locale. Return the list of local names without duplications. + locale. Return the list of local names without duplicates. Only address parts that are marked as isaddress are localized and returned. @@ -99,11 +155,19 @@ class AddressLines(List[AddressLine]): @dataclasses.dataclass class WordInfo: - """ Detailed information about a search term. + """ Each entry in the list of search terms contains the + following detailed information. """ word_id: int + """ Internal identifier for the word. + """ word_token: str + """ Normalised and transliterated form of the word. + This form is used for searching. + """ word: Optional[str] = None + """ Untransliterated form, if available. + """ WordInfos = Sequence[WordInfo] diff --git a/nominatim/api/types.py b/nominatim/api/types.py index 1927f69a..d6e80496 100644 --- a/nominatim/api/types.py +++ b/nominatim/api/types.py @@ -311,13 +311,33 @@ class GeometryFormat(enum.Flag): class DataLayer(enum.Flag): - """ Layer types that can be selected for reverse and forward search. + """ The `DataLayer` flag type defines the layers that can be selected + for reverse and forward search. + """ + ADDRESS = enum.auto() + """ The address layer contains all places that have a fully qualified + address that includes a house number (or a house name equivalent, + for some addresses) and places that can be part of an address like + roads, cities, states. """ POI = enum.auto() - ADDRESS = enum.auto() + """ Layer for points of interest like shops, restaurants but also + recycling bins or postboxes. + """ RAILWAY = enum.auto() - MANMADE = enum.auto() + """ Layer with railway features including tracks and other infrastructure. + Note that in Nominatim's standard configuration, only very few railway + features are imported into the database. Thus a custom configuration + is required to make full use of this layer. + """ NATURAL = enum.auto() + """ Layer with natural features like rivers, lakes and mountains. + """ + MANMADE = enum.auto() + """ Layer with other human-made features and boundaries. This layer is + the catch-all and includes all features not covered by the other + layers. A typical example for this layer are national park boundaries. + """ def format_country(cc: Any) -> List[str]: