This is a tutorial for using the
OpenCage geocoding API
in Node.js.
Topics covered in this tutorial
- General Background
- installing opencage-api-client
- Reverse geocoding
- Forward geocoding
- Geocoding a list of places
- Making requests in parallel
- Other javascript frameworks
- Further reading
Background
The code examples below will use your geocoding API key once you
log in.
Before we dive in to the tutorial
- Sign up for an OpenCage geocoding API key.
- Play with the demo page, so that you see the actual response the API returns.
- Browse the API reference, so you understand the optional parameters, best practices, possible response codes, and the rate limiting on free trial accounts.
Nodejs packages for accessing the OpenCage Geocoding API
In node.js there are two packages you can use:
Install the nodejs package
$ npm install opencage-api-client
# or using yarn
$ yarn add opencage-api-client
Set API key
Create a.env
file with:
OPENCAGE_API_KEY=YOUR-API-KEY
Reverse geocode (coordinates to place)
const opencage = require('opencage-api-client');
opencage
.geocode({ q: '37.4396, -122.1864', language: 'fr' })
.then((data) => {
// console.log(JSON.stringify(data));
if (data.status.code === 200 && data.results.length > 0) {
const place = data.results[0];
console.log(place.formatted);
console.log(place.components.road);
console.log(place.annotations.timezone.name);
} else {
console.log('status', data.status.message);
console.log('total_results', data.total_results);
}
})
.catch((error) => {
console.log('error', error.message);
if (error.status.code === 402) {
console.log('hit free trial daily limit');
console.log('become a customer: https://opencagedata.com/pricing');
}
});
// ... prints
// 1330 Middle Avenue, Menlo Park, Californie 94025, États-Unis d'Amérique
// Middle Avenue
// America/Los_Angeles
Forward geocode (address to coordinates)
const opencage = require('opencage-api-client');
// note that the library takes care of URI encoding
opencage
.geocode({ q: 'Theresienhöhe 11, München' })
.then((data) => {
// console.log(JSON.stringify(data));
if (data.status.code === 200 && data.results.length > 0) {
const place = data.results[0];
console.log(place.formatted);
console.log(place.geometry);
console.log(place.annotations.timezone.name);
} else {
console.log('Status', data.status.message);
console.log('total_results', data.total_results);
}
})
.catch((error) => {
// console.log(JSON.stringify(error));
console.log('Error', error.message);
// other possible response codes:
// https://opencagedata.com/api#codes
if (error.status.code === 402) {
console.log('hit free trial daily limit');
console.log('become a customer: https://opencagedata.com/pricing');
}
});
// ... prints
// Theresienhöhe 11, 80339 Munich, Germany
// { lat: 48.1341651, lng: 11.5464794 }
// Europe/Berlin
Batch geocode a file of addresses
For basic usage, here is an example to batch geocode a file of addresses
Create a file "smaill_file_to_geocode.csv" containing addressesMadrid, Spain
Milan, Italy
Berlin, Germany
München, Deutschland
Philipsbornstr 2, 30165 Hannover, Germany
const fs = require('fs');
const { geocode } = require('opencage-api-client');
const infile = 'smaill_file_to_geocode.csv';
const batch = async (lines) => {
for (let index = 0; index < lines.length; index++) {
const address = lines[index];
if (address.trim() !== '') {
// note that the library takes care of URI encoding
try {
const apiResponse = await geocode({ q: address });
// NodeJS<14 use : if(apiResponse && apiResponse.results && apiResponse.results.length > 0)
if (apiResponse?.status?.code === 200 && apiResponse?.results?.length > 0) {
const geocoded = apiResponse.results[0];
const latitude = geocoded.geometry.lat;
const longitude = geocoded.geometry.lng;
console.log(`${address} - ${latitude}, ${longitude}`);
}
} catch (error) {
console.log(error);
}
}
}
};
fs.readFile(infile, 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
const lines = data.split(/\r?\n/);
batch(lines);
});
// ... prints
// Madrid, Spain - 40.4167047, -3.7035825
// Milan, Italy - 45.4668, 9.1905
// Berlin, Germany - 52.5170365, 13.3888599
// München, Deutschland - 48.1371079, 11.5753822
// Philipsbornstr 2, 30165 Hannover, Germany - 52.387783, 9.7334394
Running many parallel queries
For large dataset, nodejs and its I/O model allows us to quickly process a large amount of requests per second - assuming of course that you are on a paid plan that allows high volume. We prepared a more complex code example, than the previous one above, nodejs parallel batch requests using a queue, task workers.
Before you start geocoding at high volume, please read our guide to geocoding large datasets where we explain various strategies and points to consider.
Install nodejs package
# install with npm or yarn
$ npm install node-geocoder
Forward geocode (address to coordinates)
var NodeGeocoder = require('node-geocoder');
var geocoder = NodeGeocoder({
provider: 'opencage',
apiKey: 'YOUR-API-KEY'
});
// Using callback
geocoder.geocode('37.4396, -122.1864', function(err, res) {
console.log(res);
});
geocoder.geocode('29 champs elysée paris', function(err, res) {
console.log(res);
});
// Or using Promise
geocoder.geocode('37.4396, -122.1864')
.then(function(res) {
console.log(res);
})
.catch(function(err) {
console.log(err);
});
Batch geocode addresses
geocoder.batchGeocode(['address1', 'address2'], function (err, results) {
// Return an array of type {error: false, value: []}
console.log(results) ;
});