Run a free geocoder with Nominatim Docker
The fastest way to set up a free geocoding and reverse geocoding service on your local machine is by installing Nominatim using Docker. In this tutorial, I'll walk you through the process and explain what happens at each step along the way. Once Nominatim is up and running, we'll run a quick geocoding example to check that it works.
Part 1: OpenStreetMap OSM Nominatim API tutorial
Part 2: Run a free geocoder with Nominatim Docker (this article)
Part 3: Building a free geocoding and reverse geocoding service with OpenStreetMap
Part 4: How to draw and view boundary data with OpenStreetMap OSM
How Nominatim works
Nominatim is a geocoding and reverse geocoding software package that is commonly used to convert addresses into geographic coordinates (latitude and longitude) and vice versa.
You can think of Nominatim as a specialized search engine for OpenStreetMap (OSM) data. OSM organizes data as a graph, with places
(e.g. a specific building address) as nodes connected by roads to other places. Each place
is annotated with tags describing its name, address, coordinates, function etc.
Nominatim unwraps this graph and stores it in database tables where it can be efficiently queried. For example, each place
then becomes a row entry in the places
table, with columns for name, address, coordinates etc. Relationships between places are encoded as references to different rows.
So let's say you want to geocode (convert an address name to a latitude, longitude pair) the address, "999 Canada Place". The address string can be found in the name column of the places
table which is specifically designed to handle free text search efficiently. This means that when an address is inserted into the database, a separate lookup table that maps words or phrases to the row entries they occur in is also updated, which allows for fast searching based on address names or phrases. Nominatim uses Postgres, but the principles I've described here apply to any relational database.
Install Docker and spin up Nominatim
To run Nominatim, we are going to use Docker, a program that packages software into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and runtime.
Download Docker Desktop and start it so that it runs in the background. Next, in the preferences section, make sure that you configure docker to run with enough memory and disk space because we'll be extracting map data from OSM and using it to populate several database tables, and this consumes disk storage. Set disk image size to at least 8 GB and memory to 20 GB.
Finally, run the command:
docker run -it \
-e PBF_URL=http://download.geofabrik.de/north-america/canada/british-columbia-latest.osm.pbf \
-e REPLICATION_URL=https://download.geofabrik.de/north-america/canada/british-columbia-updates/ \
-p 8080:8080 \
--name nominatim \
mediagis/nominatim:4.3
This sets up a Nominatim container instance (pulled from the mediagis/nominatim v4.3 repository) using OSM data for British Columbia, Canada, allowing you to access a geocoding service via HTTP on port 8080 of your host machine. Additionally, it configures the container to receive incremental updates (via the REPLICATION_URL
) to stay synchronized with changes in OSM data.
Once you hit enter, you'll see a progress bar that shows you how much time the download has left.
Extracting map data to Postgres
Once the download is complete, the install script unpacks the OSM map data and saves it into Postgres using the osm2pgsql utility.
When this is done, you'll get a message saying, "Nominatim is ready to accept requests".
Testing our free geocoder
The final step involves verifying the functionality of the Nominatim API through a basic geocoding example. Assuming you've followed all the previous instructions, our free geocoding service should now be operational at http://localhost:8080. To test it, please open a new browser tab and navigate to the following address: http://localhost:8080/search?q=canada+place.
You should get back the following response:
[
{
"place_id": 579864,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"osm_type": "way",
"osm_id": 706831744,
"boundingbox": [
"49.2877544",
"49.2881403",
"-123.115517",
"-123.114108"
],
"lat": "49.287991",
"lon": "-123.1149786",
"display_name": "Canada Place, Gastown, Downtown, Vancouver, Metro Vancouver Regional District, V6C, Canada",
"place_rank": 26,
"category": "highway",
"type": "tertiary",
"importance": 0.30000999999999994
},
// ... removed similar entries
{
"place_id": 579858,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
"osm_type": "node",
"osm_id": 7515805468,
"boundingbox": [
"49.2879188",
"49.2880188",
"-123.1147061",
"-123.1146061"
],
"lat": "49.2879688",
"lon": "-123.1146561",
"display_name": "Canada Place, West Waterfront Road, Gastown, Downtown, Vancouver, Metro Vancouver Regional District, V6C, Canada",
"place_rank": 30,
"category": "highway",
"type": "bus_stop",
"importance": 0.20000999999999997
}
]
which is an array of all the places
that correspond to the search term "Canada Place" (Vancouver's downtown cruise terminal). The lat
and lon
fields represent the geocoded coordinates of each place
.
Now that we've gotten our free geocoder working locally, the next step is to use the Nominatim API to build a free geocoding and reverse geocoding service.
👋 As always, if you have any questions or suggestions for me, please reach out or say hello on LinkedIn.
Next: Part 3: Building a free geocoding and reverse geocoding service with OpenStreetMap