Andrew Larcombe

Geocoding with OpenCage and Gatsby

See the demo: https://andrewl.github.io/gatsby-geocoding

Get the code: https://github.com/andrewl/gatsby-geocoding

Let's say you have a CSV file containing the addresses of a bunch of places that you want to display on a map on your Gatsby site, but you don't have a lat-long position for them. What are you going to do?

The answer is 'geocoding' - this process takes an address (eg "10 Smith Street, Leeds, LS1 1QQ") and works out its latitude and longitude (eg 53.80)°N, 1.55°W). It's a far from straightforward process, but fortunately there are a number of Geocoding APIs out there.

This tutorial uses the OpenCage Geocoding Service, a commercial service with a generous free testing tier, that is based on Open Data. To use this service with Gatsby we'll be using the gatsby-transformer-opencage-geocoder plugin Disclosure: I was paid to develop this plugin.

Get the data

We'll use data from the UK's NHS Digital - the dataset is from their 'Organisation Data Service' and we'll use their 'GP Practices' dataset from their downloads page. For brevity I've save the first 100 lines of the CSV in the 'data' directory of the repo.

Install the plugins

Assuming you've got a Gatsby site setup we'll need to install some plugins to read data from a CSV file, carry out the geocoding, and display a map:

npm i --save gatsby-source-filesystem gatsby-transformer-csv gatsby-transformer-opencage-geocoder leaflet opencage-api-client react-leaflet

Configure the plugins

Configure the plugins as follows: We'll need gatsby-source-filesystem to pull in nodes from files in our 'data' directory, and setup gatsby-transformer-csv so that it doesn't consider the first line of the CSV file as a header containing column names.

To do the geocoding we'll need to tell the gatsby-transformer-opencage-geocoder plugin our API key (signup for one at https://opencagedata.com/users/sign_up), which node types we want to geocode (EpraccurCsv - this is generated by the gatsby-transformer-csv plugin) and the fields that contain the address information (field5, field6, field7, field8, field9, field10 all contain parts of the address).

Geocode!

Running 'gatsby develop' will, of course, create our nodes. During this process the gatsby-transformer-opencage-geocoder uses Gatsby's Node API to add latitude and longitude to any nodes whose type we have told it to geocode. You can see the results of this in GraphiQL. Here you can see a GraphQL fragment querying the address fields, and the latitude and longitude fields that have been inserted by the transformer plugin at fields.geocoderGeometry.lat and fields.geocoderGeometry.lng

Create a map

It's now pretty straightforward to write a template which can use the latitude and longitude to display a marker on a map

This GraphQL fragment from the surgery.js page template pulls out the name, address and geocoded position...

...and you can see how we can use these attributes in the template here, using the LeafletMap component described in my other post at https://www.andrewl.net/article/gatsby-geo-simple-map

The rest of the codebase just uses some standard Gatsby techniques to create a list page on the index, and to create the GP surgery pages. You can checkout the code at https://github.com/andrewl/gatsby-geocoding

I'm Andrew - a Tech Architect and Agile Delivery Consultant. Find out more about the services I offer here