Show an imprecise location

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:

  1. Make the reverse geocoding request from your backend/server (not the browser).
  2. On the server, build the coarsened string (see below).
  3. 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!

Start your free trial

2,500 geocoding API requests/day - No credit card required