Privacy first!
In many cases you might not want to show a precisely geocoded location.
As a very basic example: imagine you're building an app that lets people
share photos. You might want to show the neighbourhood and city a user
of the app is in, but probably not the precise house address.
Due to privacy concerns you might not want to show a precisely geocoded location
If you send coordinates (for example the location of the user's phone, or
the coordinates you extracted from the photo) to the
OpenCage geocoding API,
by default we will reverse geocode those coordinates to as precise
a location as possible, for example a building address.
We then format that address correctly for that country and put the result
in the
formatted
value of the API result.
So what can you do if you don't want to show that exact address?
Important: do the geocoding server-side
Before we get to the code example, one critical point: this technique
only protects privacy if the geocoding request itself happens on your
server, not in the user's browser.
If you call the OpenCage geocoding API directly from client-side JavaScript
and then only display a coarsened string, you haven't actually protected
anything - the full API response, including the precise formatted address
and exact coordinates, is still sitting in the browser's memory and visible
to anyone who opens their browser's developer tools.
Filtering what you show on screen doesn't filter what was sent to the browser.
To actually preserve privacy:
- Make the reverse geocoding request from your backend/server (not the browser).
- On the server, build the coarsened string (see below).
- Send only that coarsened string to the client, never the raw API response.
Creating your own privacy respecting formatted string
The solution is you need to create your own location string to display
from the hierarchy pieces we return in the
components
part of the response. As a first step, please read the brief
section about components in the API reference.
Below is an example (the logic works the same whether you run it server-side
in Node.js, or adapt it to Python/Ruby/PHP/etc — see the further reading
for other language tutorials).
As an example, for the coordinates
52.536507, 13.426880
we return a
formatted
value
Jablonskistraße 29, 10405 Berlin, Germany
but with the logic below you would instead show
Winsviertel, Prenzlauer Berg, Berlin, Germany
which is correct but not precise.
Keep in mind that "coarse" is relative to population density. A
neighbourhood
in a dense city can be genuinely vague, but the same field for a small village
in a rural area may still narrow things down to a small number of people.
Pick the tier that gives you the privacy level you actually need for the
location types you expect.
// run this server-side, after you've made a reverse geocoding request
// to the OpenCage geocoding API.
// Only send the *return value* of this function
// to the client - never the raw API response.
// See tutorials:
// - javascript: https://opencagedata.com/tutorials/geocode-in-javascript
// - other languages: https://opencagedata.com/sdks
//
function create_pformatted(result) {
console.log('formatted: ' + result.formatted);
// list of component pieces we want in our string
// ordered from more precise to less
var targets = [
'neighbourhood',
'suburb',
'city_district',
'village',
'town',
'city',
'state',
'country'
];
var privacy_formatted_pieces = [];
// check the components list to see if the piece exists for
// this location
targets.forEach(checkComponent);
function checkComponent(item){
if (item in result.components){
privacy_formatted_pieces.push(result.components[item]);
}
}
// print the new privacy formatted string
var pformatted = privacy_formatted_pieces.join(', ');
// fallback: if none of the target fields exist for this location
// (rare, but possible for very remote areas), fall back to the country
if (pformatted === '' && result.components.country) {
pformatted = result.components.country;
}
return pformatted;
}
If you're also storing or transmitting the raw coordinates (not just the reverse-geocoded address), consider also truncating their precision before storage. Rounding to 2-3 decimal places (roughly 1km precision) is a simple companion technique that reduces how identifying the raw coordinates themselves are, independent of the address string.
Further reading
Happy geocoding!
2,500 geocoding API requests/day - No credit card required