]> git.openstreetmap.org Git - nominatim.git/commitdiff
add getting started section for library docs
authorSarah Hoffmann <lonvia@denofr.de>
Sun, 27 Aug 2023 12:42:04 +0000 (14:42 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Sun, 27 Aug 2023 12:42:04 +0000 (14:42 +0200)
docs/extra.css
docs/library/Getting-Started.md
docs/library/NominatimAPI.md
docs/mkdocs.yml

index 2151b06686b23a83f355606b0b7b1effe657e24c..155fa1aa71fcaf91bbbd66792a87110b206569a9 100644 (file)
@@ -29,3 +29,8 @@ th {
 
 .doc-children .doc-contents {
     margin-left: 3em;
+}
+
+.md-footer__inner {
+    display: none;
+}
index a013f40cbbba824b9e65b1a0a908fef4f560ed27..77724e67c7212d4d5b788d2d307a13156ae30dad 100644 (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).
index a5481a190f3b7c36dd2e92d8d442234da96632c5..0fa9d65951f598e57eceee96952e65b819829511 100644 (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
index 8a9d6e7de510104d8774d500e5550ecbd7e96e9f..df68cda877780b515167ae6988847453fdfe5ad2 100644 (file)
@@ -3,6 +3,7 @@ theme:
   name: material
   features:
     - navigation.tabs
+copyright: Copyright &copy; 2023 Nominatim developer community
 docs_dir: ${CMAKE_CURRENT_BINARY_DIR}
 site_url: https://nominatim.org
 repo_url: https://github.com/openstreetmap/Nominatim