]> 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;
 
 .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
 
 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':
 
 
 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.
 
 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
 
 
 ### 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
             - search_category
         heading_level: 6
         group_by_category: False
-        show_signature_annotations: True
 
 
 ### NominatimAPIAsync
 
 
 ### NominatimAPIAsync
@@ -35,4 +34,3 @@ to instantiate a separate instance for each thread.
             - begin
         heading_level: 6
         group_by_category: False
             - 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
   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
 docs_dir: ${CMAKE_CURRENT_BINARY_DIR}
 site_url: https://nominatim.org
 repo_url: https://github.com/openstreetmap/Nominatim