array_map('strval', range($a, $b)); if ($i >= 13201 && $i <= 13216) return [['13055'], $codes(13201, 13216), 'Marseille']; if ($i >= 69381 && $i <= 69389) return [['69123'], $codes(69381, 69389), 'Lyon']; if ($i >= 75101 && $i <= 75120) return [$codes(75101, 75120), $codes(75101, 75120), 'Paris']; return null; } /** Somme des populations IRIS (recensement 2022) pour une liste de codes commune/arrondissement. */ function iris_sum(array $codes): float { if (!$codes) { return 0.0; } $ph = implode(',', array_fill(0, count($codes), '?')); $st = db()->prepare("SELECT SUM(pop) FROM iris_pop WHERE com IN ($ph)"); $st->execute(array_map('strval', $codes)); return (float) $st->fetchColumn(); } /** * Construit une série [{annee,pop}] : somme de pop_commune sur $histCodes (par année), * prolongée à 2022 par la somme d'iris_pop sur $irisCodes. */ function pop_series(bool $hasHist, bool $hasIris, array $histCodes, array $irisCodes): array { $out = []; $hasYear = []; if ($hasHist && $histCodes) { $ph = implode(',', array_fill(0, count($histCodes), '?')); $st = db()->prepare("SELECT annee, SUM(pop) AS pop FROM pop_commune WHERE comc IN ($ph) GROUP BY annee ORDER BY annee"); $st->execute($histCodes); foreach ($st as $r) { $y = (int) $r['annee']; $out[] = ['annee' => $y, 'pop' => (int) $r['pop']]; $hasYear[$y] = true; } } if ($hasIris && $irisCodes && empty($hasYear[2022])) { $ph = implode(',', array_fill(0, count($irisCodes), '?')); $p = db()->prepare("SELECT ROUND(SUM(pop)) FROM iris_pop WHERE com IN ($ph)"); $p->execute($irisCodes); $v = $p->fetchColumn(); if ($v !== null && $v !== false && (float) $v > 0) { $out[] = ['annee' => 2022, 'pop' => (int) $v]; } } usort($out, static fn($a, $b) => $a['annee'] - $b['annee']); return $out; } try { $uai = trim((string) ($_GET['uai'] ?? '')); if ($uai === '') { json_error('Paramètre uai requis.'); } $hasHist = (bool) db()->query("SHOW TABLES LIKE 'pop_commune'")->fetchColumn(); $hasIris = (bool) db()->query("SHOW TABLES LIKE 'iris_pop'")->fetchColumn(); if (!$hasHist && !$hasIris) { json_out(['zone' => [], 'ville' => null, 'ville_nom' => null]); } $e = db()->prepare('SELECT comc FROM etablissements WHERE id = ?'); $e->execute([$uai]); $comc = $e->fetchColumn(); if (!$comc) { json_out(['zone' => [], 'ville' => null, 'ville_nom' => null]); } $comc = (string) $comc; // Zone = commune ou arrondissement (code de l'établissement directement). $zone = pop_series($hasHist, $hasIris, [$comc], [$comc]); // Ville entière (seulement pour un arrondissement PLM). $ville = null; $villeNom = null; $estimated = false; if ($plm = plm_ville($comc)) { [$histCodes, $irisCodes, $villeNom] = $plm; $ville = pop_series($hasHist, $hasIris, $histCodes, $irisCodes); // Si l'arrondissement n'a pas d'historique propre (Lyon/Marseille), on l'ESTIME : // population de la ville × part de l'arrondissement dans les IRIS (recensement 2022). if (count($zone) < 2 && $ville && $hasIris) { $arrIris = iris_sum([$comc]); $cityIris = iris_sum($irisCodes); if ($arrIris > 0 && $cityIris > 0) { $share = $arrIris / $cityIris; $zone = array_map( static fn(array $p) => ['annee' => $p['annee'], 'pop' => (int) round($p['pop'] * $share)], $ville ); $estimated = true; } } } json_out([ 'zone' => $zone, 'zone_estimated' => $estimated, 'ville' => $ville, 'ville_nom' => $villeNom, ]); } catch (Throwable $e) { json_error('Erreur : ' . $e->getMessage(), 500); }