Aller au contenu

Carte des communes

Télécharger le référentiel géographique du hub, lister les 553 communes avec leur population, et les placer sur une carte à partir des centroïdes disponibles.

Objectif : une page qui liste les communes du Sénégal avec leur population 2023 et les situe sur une carte. Aucun appel à l'API : le fichier du hub suffit.

Les données

Le jeu Référentiel géographique contient 734 lieux : 14 régions, 46 départements, 116 arrondissements, 5 villes et 553 communes. Téléchargement : lieux.json (aussi en CSV et XLSX sur la page du jeu).

Chaque lieu porte id, level, name, name_source, parent_id, population_2023, lat et lon.

  • Hiérarchie et population : ANSD, répertoire des localités RGPH-5 2023, licence CC-BY 4.0.
  • Centroïdes (lat, lon) : OCHA COD-AB Sénégal via HDX, licence CC BY-IGO (source non officielle).

Les communes n'ont pas de centroïde

HDX fournit des centroïdes jusqu'aux arrondissements, pas pour les communes. Leurs lat et lon sont vides. Cette recette place donc chaque commune sur le point de son arrondissement, ou à défaut de son département. La carte montre une zone, pas l'emplacement exact de la commune.

Préparer les points

Une fonction regroupe les communes sous le premier ancêtre qui a un centroïde. Mettez-la dans preparer.js.

JavaScript
export function preparer(lieux) {
	const parId = new Map(lieux.map((l) => [l.id, l]));
	const nom = (l) => l.name ?? l.name_source;
	// La commune n'a pas de centroïde : on remonte vers le premier ancêtre qui en a un.
	const ancetreAvecPoint = (l) => {
		for (let p = parId.get(l.parent_id); p; p = parId.get(p.parent_id)) if (p.lat != null) return p;
		return null;
	};
	const points = new Map();
	for (const commune of lieux.filter((l) => l.level === 'commune')) {
		const ancetre = ancetreAvecPoint(commune);
		if (!ancetre) continue;
		const point = points.get(ancetre.id) ?? { nom: nom(ancetre), niveau: ancetre.level, lat: ancetre.lat, lon: ancetre.lon, communes: [] };
		point.communes.push({ nom: nom(commune), population: commune.population_2023 });
		points.set(ancetre.id, point);
	}
	return [...points.values()];
}

Sur la version 1.0.0 du jeu, les 553 communes se répartissent sur 130 points : 85 arrondissements, 40 départements et 5 régions.

La page

  1. Copiez lieux.json à côté de votre page. Une copie locale fixe la version utilisée.

  2. Créez carte.html :

    HTML
    <!doctype html>
    <html lang="fr">
    <head>
    	<meta charset="utf-8" />
    	<meta name="viewport" content="width=device-width, initial-scale=1" />
    	<title>Communes du Sénégal</title>
    	<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    	<style>
    		#carte { height: 60vh; }
    	</style>
    </head>
    <body>
    	<h1>Communes du Sénégal</h1>
    	<div id="carte" role="region" aria-label="Carte des communes"></div>
    	<p>Sources : ANSD, RGPH-5 2023, via 221 (CC-BY 4.0). Centroïdes : OCHA COD-AB via HDX, source non officielle (CC BY-IGO).</p>
    	<h2>Liste</h2>
    	<ul id="liste"></ul>
    	<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    	<script type="module">
    		import { preparer } from './preparer.js';
    
    		const lieux = await (await fetch('./lieux.json')).json();
    		const points = preparer(lieux);
    		const fmt = new Intl.NumberFormat('fr-FR');
    
    		const carte = L.map('carte').setView([14.5, -14.5], 7);
    		L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap' }).addTo(carte);
    
    		for (const p of points) {
    			const total = p.communes.reduce((s, c) => s + (c.population ?? 0), 0);
    			const bulle = document.createElement('p');
    			bulle.textContent = `${p.nom} (${p.niveau}) : ${p.communes.length} commune(s), ${fmt.format(total)} hab.`;
    			L.circleMarker([p.lat, p.lon], { radius: 4 + Math.sqrt(total) / 60 }).bindPopup(bulle).addTo(carte);
    		}
    
    		// La liste reste la vue de référence : lisible au clavier et au lecteur d'écran.
    		const liste = document.querySelector('#liste');
    		points
    			.flatMap((p) => p.communes.map((c) => ({ ...c, zone: p.nom })))
    			.sort((a, b) => a.nom.localeCompare(b.nom, 'fr'))
    			.forEach((c) => {
    				const li = document.createElement('li');
    				li.textContent = `${c.nom}, ${c.zone}, ${fmt.format(c.population ?? 0)} hab.`;
    				liste.append(li);
    			});
    	</script>
    </body>
    </html>
  3. Servez le dossier (par exemple npx serve .). Un fichier ouvert directement ne peut pas charger lieux.json.

Les tuiles OpenStreetMap ont leurs propres conditions d'usage : lisez la politique d'usage des tuiles avant une mise en production.

Attribution

La licence CC-BY 4.0 exige de citer la source. Reprenez la mention « ANSD, RGPH-5 2023, via 221 ». Pour les centroïdes, citez « OCHA, COD-AB Sénégal, via HDX (CC BY-IGO) ».

Et ensuite ?