Reverse Geocoding
Click the map to get the address at any location Each library has its own approach: here's how they compare.
Quick Recommendations
Leaflet — Best when you want a simple click-to-address flow with the result shown in a Leaflet popup at the clicked location.
MapLibre GL JS — Ideal when reverse geocoding integrates with data-driven map interactions and you need the result as structured GeoJSON.
OpenLayers — The right choice when click coordinates need projection transformation and results display in an ol.Overlay popup.
MapTiler SDK — Works best for the simplest API: the SDK's geocoding helpers handle the API call with the pre-configured API key.
At a Glance
| Leaflet | MapLibre | OpenLayers | SDK | |
|---|---|---|---|---|
| Coordinates | [lat, lng] | [lng, lat] | fromLonLat([lng, lat]) | [lng, lat] |
| Rendering | DOM + Canvas (2D) | WebGL (GPU, 60fps) | Canvas + WebGL | WebGL (GPU, 60fps) |
| Bundle size | ~42 KB gzipped | ~250 KB gzipped | ~290 KB gzipped (tree-shakeable) | ~280 KB gzipped (includes MapLibre) |
| Learning curve | Easiest (simple API, great tutorials) | Moderate (source/layer model, expressions) | Steepest (projections, OGC standards, verbose API) | Easy (MapLibre API with convenience helpers) |
| 3D support | No native 3D (2D only) | Full: terrain, fill-extrusion, globe, sky | Limited: WebGL layers, no native globe | Full (same as MapLibre) |
| Code lines | 14 | 20 | 22 | 15 |
Code Snippets
Click a library to expand its code. Each snippet shows only the core logic: the scaffold handles HTML boilerplate.
Leaflet14 linesShow code
const map = L.map('map').setView([48.8566, 2.3522], 13);
L.tileLayer('https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', {
tileSize: 256,
attribution: '© <a href="https://www.maptiler.com/">MapTiler</a> © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);
let marker;
map.on('click', async (e) => {
const { lat, lng } = e.latlng;
const res = await fetch(`https://api.maptiler.com/geocoding/${lng},${lat}.json?key=YOUR_MAPTILER_KEY`);
const data = await res.json();
const label = data.features.length ? data.features[0].place_name : 'Unknown location';
if (marker) marker.remove();
marker = L.marker([lat, lng]).addTo(map).bindPopup(label).openPopup();
});MapLibre GL JS20 linesShow code
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/streets-v4/style.json?key=YOUR_MAPTILER_KEY',
center: [14.42, 50.08],
zoom: 12
});
map.addControl(new maplibregl.NavigationControl());
let marker;
map.on('click', async (e) => {
const { lng, lat } = e.lngLat;
const res = await fetch(`https://api.maptiler.com/geocoding/${lng},${lat}.json?key=YOUR_MAPTILER_KEY`);
const data = await res.json();
if (marker) marker.remove();
const name = data.features.length ? data.features[0].place_name : 'Unknown location';
marker = new maplibregl.Marker({ color: '#F44336' })
.setLngLat(e.lngLat)
.setPopup(new maplibregl.Popup({ offset: 25 }).setHTML(`<b>${name}</b><br>${lng.toFixed(5)}, ${lat.toFixed(5)}`))
.addTo(map);
marker.togglePopup();
});OpenLayers22 linesShow code
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', attributions: '© <a href="https://www.maptiler.com/copyright/">MapTiler</a>' }) })
],
view: new ol.View({ center: ol.proj.fromLonLat([2.3522, 48.8566]), zoom: 13 })
});
var popupEl = document.getElementById('popup');
var overlay = new ol.Overlay({ element: popupEl, positioning: 'bottom-center', offset: [0, -5] });
map.addOverlay(overlay);
map.on('click', function(evt) {
var lonlat = ol.proj.toLonLat(evt.coordinate);
popupEl.style.display = 'block';
popupEl.textContent = 'Loading...';
overlay.setPosition(evt.coordinate);
fetch('https://api.maptiler.com/geocoding/' + lonlat[0].toFixed(6) + ',' + lonlat[1].toFixed(6) + '.json?key=YOUR_MAPTILER_KEY')
.then(function(r) { return r.json(); })
.then(function(data) {
popupEl.textContent = data.features.length ? data.features[0].place_name : 'No address found';
})
.catch(function() { popupEl.textContent = 'Error fetching address'; });
});MapTiler SDK15 linesShow code
maptilersdk.config.apiKey = 'YOUR_MAPTILER_KEY';
const map = new maptilersdk.Map({
container: 'map',
style: maptilersdk.MapStyle.STREETS,
center: [2.3522, 48.8566],
zoom: 13
});
const popup = new maptilersdk.Popup();
map.on('click', async (e) => {
const { lng, lat } = e.lngLat;
const res = await fetch(`https://api.maptiler.com/geocoding/${lng},${lat}.json?key=YOUR_MAPTILER_KEY`);
const data = await res.json();
const name = data.features.length ? data.features[0].place_name : 'No result';
popup.setLngLat([lng, lat]).setHTML(`<b>${name}</b><br>${lng.toFixed(5)}, ${lat.toFixed(5)}`).addTo(map);
});Things to Know
Implementation-specific details that matter for reverse geocoding.
Click event provides [lat, lng] which must be swapped to [lng, lat] for the MapTiler Geocoding API query parameter.
Click event gives { lng, lat } directly in the correct order for the MapTiler API; results shown in a Popup.
Click coordinates are in EPSG:3857 and must be transformed to EPSG:4326 with ol.proj.toLonLat() before the API call.
Identical click event format to MapLibre; the SDK adds no reverse geocoding conveniences beyond the shared API.
Which Library to Use?
Click anywhere on a Leaflet map to get the address at that location using MapTiler reverse geocoding.
Best when you want a simple click-to-address flow with the result shown in a Leaflet popup at the clicked location.
Click anywhere on a MapLibre GL JS map to get the address at that location using the MapTiler reverse geocoding API.
Ideal when reverse geocoding integrates with data-driven map interactions and you need the result as structured GeoJSON.
Click anywhere on an OpenLayers map to get the address at that location using the MapTiler Reverse Geocoding API.
The right choice when click coordinates need projection transformation and results display in an ol.Overlay popup.
Click the map to get the address at that location using the MapTiler Reverse Geocoding API.
Works best for the simplest API: the SDK's geocoding helpers handle the API call with the pre-configured API key.
Build Maps with AI
Generate code like these examples using mapping library skills in your IDE.