add getting started section for library docs

This commit is contained in:
Sarah Hoffmann
2023-08-27 14:42:04 +02:00
parent f917fa67aa
commit ef1b52eee5
4 changed files with 199 additions and 31 deletions

View File

@@ -34,52 +34,216 @@ You can also point the PYTHONPATH to the Nominatim source code.
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.
search functions of Nominatim that are also known from its web API.
This code snippet implements a simple search for the town if 'Brugge':
=== "NominatimAPIAsync"
```
from pathlib import Path
import asyncio
!!! example
=== "NominatimAPIAsync"
``` python
from pathlib import Path
import asyncio
import nominatim.api as napi
import nominatim.api as napi
async def search(query):
api = napi.NominatimAPIAsync(Path('.'))
async def search(query):
api = napi.NominatimAPIAsync(Path('.'))
return await api.search(query)
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}')
```
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
=== "NominatimAPI"
``` python
from pathlib import Path
import nominatim.api as napi
import nominatim.api as napi
api = napi.NominatimAPI(Path('.'))
api = napi.NominatimAPI(Path('.'))
results = api.search('Brugge')
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}')
```
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.
The Nominatim library is designed around
[asyncio](https://docs.python.org/3/library/asyncio.html). `NominatimAPIAsync`
provides you with an interface of coroutines.
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.
For smaller scripts there is also a synchronous wrapper around the API. By
using `NominatimAPI`, you get exactly the same interface using classic functions.
The examples in this chapter will always show how work with both of the
implementations. The documentation itself will refer usually only to
'Nominatim API class' when both flavours are meant. If a functionality is
available only for the synchronous or asynchronous version, this will be
explicitly mentioned.
### Defining which database to use
The [Configuration](../admin/Import.md#configuration-setup-in-env)
section explains how Nominatim is configured using the
[dotenv](https://github.com/theskumar/python-dotenv) library.
The same configuration mechanism is used with the
Nominatim API library. You should therefore be sure you are familiar with
the section.
The constructor of the 'Nominatim API class' takes one mandatory parameter:
the path to the [project directory](../admin/Import.md#creating-the-project-directory).
You should have set up this directory as part of the Nominatim import.
Any configuration found in the `.env` file in this directory will automatically
used.
The second way to configure your Nominatim setup is through environment variables.
Normally, Nominatim will check the operating system environment. This can be
overwritten by giving the constructor a dictionary of configuration parameters.
Let us look up 'Brugge' in the special database named 'belgium' instead of the
standard 'nominatim' database:
!!! example
=== "NominatimAPIAsync"
``` python
from pathlib import Path
import asyncio
import nominatim.api as napi
config_params = {
'NOMINATIM_DATABASE_DSN': 'pgsql:dbname=belgium'
}
async def search(query):
api = napi.NominatimAPIAsync(Path('.'), environ=config_params)
return await api.search(query)
results = asyncio.run(search('Brugge'))
```
=== "NominatimAPI"
``` python
from pathlib import Path
import nominatim.api as napi
config_params = {
'NOMINATIM_DATABASE_DSN': 'pgsql:dbname=belgium'
}
api = napi.NominatimAPI(Path('.'), environ=config_params)
results = api.search('Brugge')
```
### Presenting results to humans
All search functions return the raw results from the database. There is no
full human-readable label. To create such a label, you need two things:
* the address details of the place
* adapt the result to the language you wish to use for display
Again searching for 'Brugge', this time with a nicely formatted result:
!!! example
=== "NominatimAPIAsync"
``` python
from pathlib import Path
import asyncio
import nominatim.api as napi
async def search(query):
api = napi.NominatimAPIAsync(Path('.'))
return await api.search(query, address_details=True)
results = asyncio.run(search('Brugge'))
locale = napi.Locales(['fr', 'en'])
for i, result in enumerate(results):
address_parts = result.address_rows.localize(locale)
print(f"{i + 1}. {', '.join(address_parts)}")
```
=== "NominatimAPI"
``` python
from pathlib import Path
import nominatim.api as napi
api = napi.NominatimAPI(Path('.'))
results = api.search('Brugge', address_details=True)
locale = napi.Locales(['fr', 'en'])
for i, result in enumerate(results):
address_parts = result.address_rows.localize(locale)
print(f"{i + 1}. {', '.join(address_parts)}")
```
To request information about the address of a result, add the optional
parameter 'address_details' to your search:
``` python
>>> results = api.search('Brugge', address_details=True)
```
An additional field `address_rows` will set in results that are returned.
It contains a list of all places that make up the address of the place. For
simplicity, this includes name and house number of the place itself. With
the names in this list it is possible to create a human-readable description
of the result. To do that, you first need to decide in which language the
results should be presented. As with the names in the result itself, the
places in `address_rows` contain all possible name translation for each row.
The library has a helper class `Locale` which helps extracting a name of a
place in the preferred language. It gets a list of language code in the
order of preference. So
``` python
locale = napi.Locale(['fr', 'en'])
```
creates a helper class that returns the name preferably in French. If that is
not possible, it tries English and eventually falls back to the default `name`
or `ref`.
The Locale object can be applied to a name dictionary to return the best-matching
name out of it:
``` python
>>> print(locale.display_name(results[0].names))
'Brugges'
```
The `address_row` field has a helper function to apply the function to all
its members and save the result in the `local_name` field. It also returns
all the localized names as a convenient simple list. This list can be used
to create a human-readable output:
``` python
>>> address_parts = results[0].address_rows.localize(locale)
>>> print(', '.join(address_parts))
Bruges, Flandre-Occidentale, Flandre, Belgique
```
This is a fairly simple way to create a human-readable description. The
place information in `address_rows` contains further information about each
place. For example, which OSM `adlin_level` was used, what category the place
belongs to or what rank Nominatim has assigned. Use this to adapt the output
to local address formats.
For more information on address rows, see
[detailed address description](Result-Handling.md#detailed-address-description).

View File

@@ -21,7 +21,6 @@ to instantiate a separate instance for each thread.
- search_category
heading_level: 6
group_by_category: False
show_signature_annotations: True
### NominatimAPIAsync
@@ -35,4 +34,3 @@ to instantiate a separate instance for each thread.
- begin
heading_level: 6
group_by_category: False
show_signature_annotations: True