Leaflet est la bibliothèque JavaScript de cartographie la plus simple à prendre en main : 42 Ko, aucune dépendance, une documentation limpide. En une quarantaine de lignes, vous allez publier une carte avec fond, marqueurs, popups et données GeoJSON.
La page minimale
Créez un fichier carte.html :
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ma première carte</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<style>
html, body, #map { height: 100%; margin: 0; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="app.js"></script>
</body>
</html>
La carte doit avoir une hauteur définie en CSS. Une div vide fait 0 px de haut : c'est la cause n°1 de « ma carte ne s'affiche pas ».
Initialiser la carte
Dans app.js, on crée la carte, on la centre et on ajoute un fond de tuiles :
const map = L.map('map').setView([45.764, 4.8357], 13); // [lat, lon], zoom
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© contributeurs OpenStreetMap'
}).addTo(map);
Notez que Leaflet attend [latitude, longitude], contrairement à GeoJSON. L'attribution n'est pas optionnelle : elle est exigée par la licence des données.
Marqueurs et popups
const fourviere = L.marker([45.7623, 4.8227]).addTo(map);
fourviere.bindPopup('<strong>Basilique de Fourvière</strong><br>Construite entre 1872 et 1884');
// Un cercle de 500 m de rayon
L.circle([45.7578, 4.832], { radius: 500, color: '#2ee6c5' })
.addTo(map)
.bindTooltip('Presqu\'île');
// Réagir au clic sur la carte
map.on('click', (e) => {
L.popup()
.setLatLng(e.latlng)
.setContent(`Lat ${e.latlng.lat.toFixed(5)}, Lon ${e.latlng.lng.toFixed(5)}`)
.openOn(map);
});
Charger du GeoJSON
Le vrai pouvoir arrive avec les données. L.geoJSON accepte un objet GeoJSON et permet de styliser chaque entité selon ses propriétés :
fetch('stations.geojson')
.then((r) => r.json())
.then((data) => {
const layer = L.geoJSON(data, {
pointToLayer: (feature, latlng) => L.circleMarker(latlng, {
radius: Math.sqrt(feature.properties.velos) * 2,
color: '#8b6cff',
fillOpacity: 0.6
}),
onEachFeature: (feature, layer) => {
layer.bindPopup(`${feature.properties.nom} : ${feature.properties.velos} vélos`);
}
}).addTo(map);
map.fitBounds(layer.getBounds()); // zoome sur les données
});
fetch ne fonctionne pas en ouvrant le fichier directement (file://). Servez votre dossier avec un serveur local : XAMPP, php -S localhost:8000 ou npx serve.
Contrôle des couches
const osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OSM' });
const topo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', { attribution: '© OSM © OpenTopoMap', maxZoom: 17 });
L.control.layers(
{ 'OpenStreetMap': osm, 'Topographique': topo }, // fonds (un seul actif)
{ 'Stations': layer } // couches superposables
).addTo(map);
L.control.scale({ imperial: false }).addTo(map);
Aller plus loin
- 10 outils à intégrer à votre carte Leaflet : géolocalisation, recherche d'adresse, mesure, dessin (Leaflet-Geoman), clusters (Leaflet.markercluster), carte de chaleur (Leaflet.heat), glisser-déposer de fichiers, légende, plein écran.
- Le même tutoriel avec MapLibre : carte orientable, rendu WebGL, des dizaines de milliers d'objets.
- Au-delà de quelques dizaines de milliers d'entités, passez aux tuiles vectorielles avec MapLibre.
Les outils de ce site sont passés de Leaflet à MapLibre pour pouvoir faire tourner la carte et afficher beaucoup d'objets : comparez avec le tutoriel MapLibre.
Démonstration
Le code de ce tutoriel, assemblé et en fonctionnement (les stations de vélos sont fictives) :
À essayer : cliquez sur le marqueur de Fourvière, survolez le cercle de la Presqu'île, cliquez une station violette (sa taille dépend du nombre de vélos), cliquez ailleurs pour lire les coordonnées, et changez de fond avec le sélecteur de couches en haut à droite.