Reverse geocoding

reverseGeocode() turns coordinates, such as a map click or a GPS fix, into the address at that point. The Node.js reverse geocoding example prints the whole GeoJSON response.

Basic reverse geocoding usage

Simple coordinate to address conversion

import { reverseGeocode } from '@tomtom-org/maps-sdk/services';
const place = await reverseGeocode({ position: [4.9041, 52.3676] }); // [longitude, latitude]
console.log(place.properties?.address?.freeformAddress); // e.g. "Dam, 1012 Amsterdam, Netherlands"

position takes [longitude, latitude] or any GeoJSON carrying a point. The call resolves a ReverseGeocodingResponse, the nearest addressable location:

  • geometry - The point you queried. The point the service matched it to is properties.originalPosition, as Reverse geocoding properties describes.
  • properties.type - 'Point Address', 'Street' or 'Geography'. A Geography result also carries its geographyType, a GeographyType[] with the names geographyTypes takes, so you can compare the two without mapping the API’s own area names.
  • properties.entryPoints - The address’s entrances, unclassified.
  • If nothing matches, it’s the queried point without properties, and its type says so. Check properties before you read it. The check also narrows the response to a Place you can show.
  • There are no dataSources, because a reverse geocoded area has no ID for geometry data. To get its outline, geocode or search for the area.

Enhanced result processing

Address components depend on the location and its data. A city address is detailed, while a remote point may only name its region. Address lists every component.

const address = place.properties?.address;
if (address) {
console.log(address.streetName, address.streetNumber, address.municipality, address.country);
}

Advanced configuration options

ParameterTypeDescription
positionHasLngLatRequired. The point to look up.
radiusMetersnumberHow far from position to look for an address, in metres. Positive.
geographyTypesGeographyType[]Return the containing area of these types instead of the street address, e.g. ['Municipality'].
headingnumberTravel direction in degrees, −360 to 360 (0 north, 90 east), for a direction-aware street match. Ignored with geographyTypes.
geopoliticalViewGeopoliticalViewSee Geopolitical view.

It also takes language and the other options every service call takes. The full type is ReverseGeocodingParams.

// The nearest address within 100 m, in English
const nearby = await reverseGeocode({ position: [4.9041, 52.3676], radiusMeters: 100, language: 'en-GB' });
// The municipality the point is in
const municipality = await reverseGeocode({ position: [4.9041, 52.3676], geographyTypes: ['Municipality'] });
// The street matched along an eastward heading
const onTheRoad = await reverseGeocode({ position: [4.9041, 52.3676], heading: 90 });

A small radiusMeters is more precise but may find nothing in sparse areas.

Geopolitical view

In a disputed territory, the country an address belongs to depends on the geopolitical view. The same point in Gilgit is in Pakistan from the international view and in India from the Indian one:

const unified = await reverseGeocode({ position: [74.31, 35.92], geopoliticalView: 'Unified' });
const indian = await reverseGeocode({ position: [74.31, 35.92], geopoliticalView: 'IN' });
// unified.properties.address.country: 'Pakistan', indian.properties.address.country: 'India'

geopoliticalView defaults to the global one, which the map also follows. See Geopolitical views.

Integration patterns

Map click integration

Clicks can come faster than answers, so run each lookup through createLatestRequest. Its section also covers what a retired lookup resolves to, cancel() and deadlines.

import { TomTomMap } from '@tomtom-org/maps-sdk/map';
import { createLatestRequest, reverseGeocode } from '@tomtom-org/maps-sdk/services';
const map = new TomTomMap({ mapLibre: { container: 'map' } });
const latestLookup = createLatestRequest();
map.mapLibreMap.on('click', async (event) => {
const lookup = await latestLookup.run((signal) =>
reverseGeocode({ position: event.lngLat.toArray(), signal })
);
if (!lookup.current) return; // a newer click retired this lookup
const address = lookup.value.properties?.address?.freeformAddress;
if (address) showAddress(address);
});

The reverse geocoding playground adds a pin and an address popup. In the Places module, the result’s pin sits on the queried point. To place it on the address, first set geometry.coordinates to properties.originalPosition.

GPS location processing

navigator.geolocation.getCurrentPosition(async ({ coords }) => {
const place = await reverseGeocode({ position: [coords.longitude, coords.latitude], radiusMeters: 50 });
const currentAddress = place.properties?.address;
if (currentAddress) displayCurrentLocation(currentAddress.freeformAddress);
});

Error handling and edge cases

  • If no address is found, you get a place without properties, not an error.
  • A failed request rejects with an SDKError. Error handling covers its kinds, including cancellation.
  • Ocean and remote points may return only a region or a country.
  • Each point costs one request. Pace many points to your key’s rate limit, and cache answers for points you look up repeatedly, rounding the coordinates for the cache key.

Map integration