mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-10-09 17:02:46 +02:00
ajout analyses osmose dans les pages de détail
This commit is contained in:
parent
359d4ba6b8
commit
0aaddb44c5
13 changed files with 1963 additions and 12 deletions
|
@ -613,8 +613,60 @@ final class AdminController extends AbstractController
|
|||
{
|
||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||
if (!$stats) {
|
||||
$this->addFlash('error', '2 Aucune stats trouvée pour ce code INSEE.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
// Si aucune stats n'existe, rechercher dans l'API geo.api.gouv.fr
|
||||
$apiUrl = "https://geo.api.gouv.fr/communes/{$insee_code}";
|
||||
$response = @file_get_contents($apiUrl);
|
||||
|
||||
if ($response === false) {
|
||||
$this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE et impossible de récupérer les informations depuis l\'API geo.api.gouv.fr.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
$communeData = json_decode($response, true);
|
||||
if (!$communeData || !isset($communeData['nom'])) {
|
||||
$this->addFlash('error', 'Aucune commune trouvée avec ce code INSEE dans l\'API geo.api.gouv.fr.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats avec les données de l'API
|
||||
$stats = new Stats();
|
||||
$stats->setZone($insee_code)
|
||||
->setName($communeData['nom'])
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('request');
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($communeData['population'])) {
|
||||
$stats->setPopulation($communeData['population']);
|
||||
}
|
||||
|
||||
// Ajouter les coordonnées si disponibles
|
||||
if (isset($communeData['centre']) && isset($communeData['centre']['coordinates'])) {
|
||||
$stats->setLon((string)$communeData['centre']['coordinates'][0]);
|
||||
$stats->setLat((string)$communeData['centre']['coordinates'][1]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($communeData['codesPostaux']) && !empty($communeData['codesPostaux'])) {
|
||||
$stats->setCodesPostaux(implode(',', $communeData['codesPostaux']));
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($communeData['codeEpci'])) {
|
||||
$stats->setCodeEpci((int)$communeData['codeEpci']);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($communeData['siren'])) {
|
||||
$stats->setSiren((int)$communeData['siren']);
|
||||
}
|
||||
|
||||
// Persister l'objet Stats
|
||||
$this->entityManager->persist($stats);
|
||||
$this->entityManager->flush();
|
||||
|
||||
$this->addFlash('success', 'Nouvelle commune ajoutée à partir des données de l\'API geo.api.gouv.fr.');
|
||||
}
|
||||
|
||||
$themes = \App\Service\FollowUpService::getFollowUpThemes();
|
||||
|
@ -1372,6 +1424,274 @@ final class AdminController extends AbstractController
|
|||
$this->addFlash('success', $budgetsMisAJour . ' budgets mis à jour.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
#[Route('/admin/import-stats-from-csv', name: 'app_admin_import_stats_from_csv')]
|
||||
public function importStatsFromCsv(): Response
|
||||
{
|
||||
$this->actionLogger->log('admin/import_stats_from_csv', []);
|
||||
|
||||
$csvFile = 'communes_france.csv';
|
||||
if (!file_exists($csvFile)) {
|
||||
$this->addFlash('error', 'Le fichier CSV des communes n\'existe pas. Veuillez exécuter le script fetch_communes.py pour le générer.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
$statsRepo = $this->entityManager->getRepository(Stats::class);
|
||||
$createdCount = 0;
|
||||
$skippedCount = 0;
|
||||
$errorCount = 0;
|
||||
|
||||
// Ouvrir le fichier CSV
|
||||
$handle = fopen($csvFile, 'r');
|
||||
if (!$handle) {
|
||||
$this->addFlash('error', 'Impossible d\'ouvrir le fichier CSV des communes.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
// Lire l'en-tête pour déterminer les indices des colonnes
|
||||
$header = fgetcsv($handle);
|
||||
$indices = array_flip($header);
|
||||
|
||||
// Vérifier que les colonnes nécessaires existent
|
||||
$requiredColumns = ['code', 'nom'];
|
||||
foreach ($requiredColumns as $column) {
|
||||
if (!isset($indices[$column])) {
|
||||
$this->addFlash('error', "La colonne '$column' est manquante dans le fichier CSV.");
|
||||
fclose($handle);
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
}
|
||||
|
||||
// Traiter chaque ligne du CSV
|
||||
while (($data = fgetcsv($handle)) !== false) {
|
||||
try {
|
||||
$inseeCode = $data[$indices['code']];
|
||||
|
||||
// Vérifier si une Stats existe déjà pour ce code INSEE
|
||||
$existingStat = $statsRepo->findOneBy(['zone' => $inseeCode]);
|
||||
if ($existingStat) {
|
||||
$skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats
|
||||
$stat = new Stats();
|
||||
$stat->setZone($inseeCode)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('request');
|
||||
|
||||
// Ajouter le nom si disponible
|
||||
if (isset($indices['nom']) && !empty($data[$indices['nom']])) {
|
||||
$stat->setName($data[$indices['nom']]);
|
||||
}
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($indices['population']) && !empty($data[$indices['population']])) {
|
||||
$stat->setPopulation((int)$data[$indices['population']]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($indices['codesPostaux']) && !empty($data[$indices['codesPostaux']])) {
|
||||
$stat->setCodesPostaux($data[$indices['codesPostaux']]);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($indices['siren']) && !empty($data[$indices['siren']])) {
|
||||
$stat->setSiren((int)$data[$indices['siren']]);
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($indices['codeEpci']) && !empty($data[$indices['codeEpci']])) {
|
||||
$stat->setCodeEpci((int)$data[$indices['codeEpci']]);
|
||||
}
|
||||
|
||||
// Ajouter les coordonnées si disponibles
|
||||
if (isset($indices['longitude']) && isset($indices['latitude']) &&
|
||||
!empty($data[$indices['longitude']]) && !empty($data[$indices['latitude']])) {
|
||||
$stat->setLon((string)$data[$indices['longitude']])
|
||||
->setLat((string)$data[$indices['latitude']]);
|
||||
}
|
||||
|
||||
// Persister l'objet Stats
|
||||
$this->entityManager->persist($stat);
|
||||
$createdCount++;
|
||||
|
||||
// Flush tous les 100 objets pour éviter de surcharger la mémoire
|
||||
if ($createdCount % 100 === 0) {
|
||||
$this->entityManager->flush();
|
||||
$this->entityManager->clear(Stats::class);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush les derniers objets
|
||||
$this->entityManager->flush();
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->addFlash('success', "Import terminé : $createdCount communes ajoutées, $skippedCount déjà existantes, $errorCount erreurs.");
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
#[Route('/admin/create-missing-stats-from-csv', name: 'app_admin_create_missing_stats_from_csv')]
|
||||
public function createMissingStatsFromCsv(): Response
|
||||
{
|
||||
$this->actionLogger->log('admin/create_missing_stats_from_csv', []);
|
||||
|
||||
$csvFile = 'communes_france.csv';
|
||||
if (!file_exists($csvFile)) {
|
||||
$this->addFlash('error', 'Le fichier CSV des communes n\'existe pas. Veuillez exécuter le script fetch_communes.py pour le générer.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
$statsRepo = $this->entityManager->getRepository(Stats::class);
|
||||
$createdCount = 0;
|
||||
$skippedCount = 0;
|
||||
$errorCount = 0;
|
||||
|
||||
// Ouvrir le fichier CSV
|
||||
$handle = fopen($csvFile, 'r');
|
||||
if (!$handle) {
|
||||
$this->addFlash('error', 'Impossible d\'ouvrir le fichier CSV des communes.');
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
// Lire l'en-tête pour déterminer les indices des colonnes
|
||||
$header = fgetcsv($handle);
|
||||
$indices = array_flip($header);
|
||||
|
||||
// Vérifier que les colonnes nécessaires existent
|
||||
$requiredColumns = ['code', 'nom'];
|
||||
foreach ($requiredColumns as $column) {
|
||||
if (!isset($indices[$column])) {
|
||||
$this->addFlash('error', "La colonne '$column' est manquante dans le fichier CSV.");
|
||||
fclose($handle);
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
}
|
||||
|
||||
// Traiter chaque ligne du CSV
|
||||
while (($data = fgetcsv($handle)) !== false) {
|
||||
try {
|
||||
$inseeCode = $data[$indices['code']];
|
||||
|
||||
// Vérifier si une Stats existe déjà pour ce code INSEE
|
||||
$existingStat = $statsRepo->findOneBy(['zone' => $inseeCode]);
|
||||
if ($existingStat) {
|
||||
$skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Créer un nouvel objet Stats
|
||||
$stat = new Stats();
|
||||
$stat->setZone($inseeCode)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime())
|
||||
->setKind('command'); // Utiliser 'command' comme source
|
||||
|
||||
// Ajouter le nom si disponible
|
||||
if (isset($indices['nom']) && !empty($data[$indices['nom']])) {
|
||||
$stat->setName($data[$indices['nom']]);
|
||||
}
|
||||
|
||||
// Ajouter la population si disponible
|
||||
if (isset($indices['population']) && !empty($data[$indices['population']])) {
|
||||
$stat->setPopulation((int)$data[$indices['population']]);
|
||||
}
|
||||
|
||||
// Ajouter les codes postaux si disponibles
|
||||
if (isset($indices['codesPostaux']) && !empty($data[$indices['codesPostaux']])) {
|
||||
$stat->setCodesPostaux($data[$indices['codesPostaux']]);
|
||||
}
|
||||
|
||||
// Ajouter le SIREN si disponible
|
||||
if (isset($indices['siren']) && !empty($data[$indices['siren']])) {
|
||||
$stat->setSiren((int)$data[$indices['siren']]);
|
||||
}
|
||||
|
||||
// Ajouter le code EPCI si disponible
|
||||
if (isset($indices['codeEpci']) && !empty($data[$indices['codeEpci']])) {
|
||||
$stat->setCodeEpci((int)$data[$indices['codeEpci']]);
|
||||
}
|
||||
|
||||
// Compléter les données manquantes (coordonnées, budget, etc.)
|
||||
$this->completeStatsData($stat);
|
||||
|
||||
// Persister l'objet Stats
|
||||
$this->entityManager->persist($stat);
|
||||
$createdCount++;
|
||||
|
||||
// Flush tous les 100 objets pour éviter de surcharger la mémoire
|
||||
if ($createdCount % 100 === 0) {
|
||||
$this->entityManager->flush();
|
||||
$this->entityManager->clear(Stats::class);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$errorCount++;
|
||||
$this->actionLogger->log('error_create_missing_stats_from_csv', [
|
||||
'insee_code' => $inseeCode ?? 'unknown',
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Flush les derniers objets
|
||||
$this->entityManager->flush();
|
||||
|
||||
fclose($handle);
|
||||
|
||||
$this->addFlash('success', "Création des Stats manquantes terminée : $createdCount communes ajoutées, $skippedCount déjà existantes, $errorCount erreurs.");
|
||||
return $this->redirectToRoute('app_admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Complète les données manquantes d'un objet Stats (coordonnées, budget, etc.)
|
||||
*/
|
||||
private function completeStatsData(Stats $stat): void
|
||||
{
|
||||
$insee_code = $stat->getZone();
|
||||
|
||||
// Compléter les coordonnées si manquantes
|
||||
if (!$stat->getLat() || !$stat->getLon()) {
|
||||
try {
|
||||
$apiUrl = 'https://geo.api.gouv.fr/communes/' . $insee_code . '?fields=centre';
|
||||
$response = @file_get_contents($apiUrl);
|
||||
if ($response !== false) {
|
||||
$data = json_decode($response, true);
|
||||
if (isset($data['centre']['coordinates']) && count($data['centre']['coordinates']) === 2) {
|
||||
$stat->setLon((string)$data['centre']['coordinates'][0]);
|
||||
$stat->setLat((string)$data['centre']['coordinates'][1]);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->actionLogger->log('error_complete_stats_data', [
|
||||
'insee_code' => $insee_code,
|
||||
'error' => 'Failed to fetch coordinates: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Compléter le budget si manquant
|
||||
if (!$stat->getBudgetAnnuel() && property_exists($this, 'budgetService') && $this->budgetService !== null) {
|
||||
try {
|
||||
$budget = $this->budgetService->getBudgetAnnuel($insee_code);
|
||||
if ($budget !== null) {
|
||||
$stat->setBudgetAnnuel((string)$budget);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->actionLogger->log('error_complete_stats_data', [
|
||||
'insee_code' => $insee_code,
|
||||
'error' => 'Failed to fetch budget: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculer le pourcentage de complétion
|
||||
$stat->computeCompletionPercent();
|
||||
}
|
||||
|
||||
#[Route('/admin/podium-contributeurs-osm', name: 'app_admin_podium_contributeurs_osm')]
|
||||
public function podiumContributeursOsm(): Response
|
||||
|
@ -1401,7 +1721,7 @@ final class AdminController extends AbstractController
|
|||
$topContributors = array_slice($contributions, 0, 10, true);
|
||||
|
||||
return $this->render('admin/podium_contributeurs_osm.html.twig', [
|
||||
'contributors' => $topContributors
|
||||
'podium' => $topContributors
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1015,6 +1015,7 @@ class PublicController extends AbstractController
|
|||
'count_data' => json_encode($countData),
|
||||
'completion_data' => json_encode($completionData),
|
||||
'icons' => \App\Service\FollowUpService::getFollowUpIcons(),
|
||||
'maptiler_token' => $_ENV['MAPTILER_TOKEN'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue