carte thèmatique
This commit is contained in:
parent
2fd0d8d933
commit
5fe2804a1a
5 changed files with 253 additions and 142 deletions
|
@ -381,7 +381,7 @@ final class AdminController extends AbstractController
|
|||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
|
||||
// Normalisation des scores pondérés entre 0 et 100
|
||||
foreach ($podium_local as &$row) {
|
||||
if ($maxPondere > 0 && $row['completion_pondere'] !== null) {
|
||||
|
@ -391,7 +391,7 @@ final class AdminController extends AbstractController
|
|||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
|
||||
// Tri décroissant sur le score normalisé
|
||||
usort($podium_local, function ($a, $b) {
|
||||
return ($b['completion_pondere_normalisee'] ?? 0) <=> ($a['completion_pondere_normalisee'] ?? 0);
|
||||
|
@ -452,6 +452,8 @@ final class AdminController extends AbstractController
|
|||
$progression7Days[$type] = \App\Service\FollowUpService::calculate7DayProgression($stats, $type);
|
||||
}
|
||||
$progression7Days['places'] = \App\Service\FollowUpService::calculate7DayProgression($stats, 'places');
|
||||
|
||||
|
||||
|
||||
return $this->render('admin/stats.html.twig', [
|
||||
'stats' => $stats,
|
||||
|
@ -467,7 +469,7 @@ final class AdminController extends AbstractController
|
|||
'latestFollowups' => $latestFollowups,
|
||||
'followup_labels' => \App\Service\FollowUpService::getFollowUpThemes(),
|
||||
'followup_icons' => \App\Service\FollowUpService::getFollowUpIcons(),
|
||||
'progression7Days' => $progression7Days,
|
||||
'progression7Days' => $progression7Days,
|
||||
'all_types' => \App\Service\FollowUpService::getFollowUpThemes(),
|
||||
]);
|
||||
}
|
||||
|
@ -491,7 +493,7 @@ final class AdminController extends AbstractController
|
|||
$followups = $stats->getCityFollowUps();
|
||||
$countData = [];
|
||||
$completionData = [];
|
||||
|
||||
|
||||
foreach ($followups as $fu) {
|
||||
if ($fu->getName() === $theme . '_count') {
|
||||
$countData[] = [
|
||||
|
@ -525,7 +527,7 @@ final class AdminController extends AbstractController
|
|||
$josm_url = null;
|
||||
}
|
||||
// Fonction utilitaire pour extraire clé/valeur de la requête Overpass
|
||||
$extractTag = function($query) {
|
||||
$extractTag = function ($query) {
|
||||
if (preg_match('/\\[([a-zA-Z0-9:_-]+)\\]="([^"]+)"/', $query, $matches)) {
|
||||
return [$matches[1], $matches[2]];
|
||||
}
|
||||
|
@ -569,7 +571,7 @@ final class AdminController extends AbstractController
|
|||
'lat' => $place->getLat(),
|
||||
'lon' => $place->getLon(),
|
||||
'name' => $place->getName(),
|
||||
'tags' => [ 'main_tag' => $place->getMainTag() ],
|
||||
'tags' => ['main_tag' => $place->getMainTag()],
|
||||
'is_complete' => !empty($place->getName()),
|
||||
'osm_url' => 'https://www.openstreetmap.org/' . $place->getOsmKind() . '/' . $place->getOsmId(),
|
||||
];
|
||||
|
@ -577,7 +579,7 @@ final class AdminController extends AbstractController
|
|||
}
|
||||
$geojson = [
|
||||
'type' => 'FeatureCollection',
|
||||
'features' => array_map(function($obj) {
|
||||
'features' => array_map(function ($obj) {
|
||||
return [
|
||||
'type' => 'Feature',
|
||||
'geometry' => [
|
||||
|
@ -608,6 +610,7 @@ final class AdminController extends AbstractController
|
|||
'completion_data' => json_encode($completionData),
|
||||
'icons' => \App\Service\FollowUpService::getFollowUpIcons(),
|
||||
'geojson' => json_encode($geojson),
|
||||
'overpass_query' => $overpass_query,
|
||||
'josm_url' => $josm_url,
|
||||
'center' => $center,
|
||||
'maptiler_token' => $_ENV['MAPTILER_TOKEN'] ?? null,
|
||||
|
@ -617,14 +620,16 @@ final class AdminController extends AbstractController
|
|||
#[Route('/admin/placeType/{osm_kind}/{osm_id}', name: 'app_admin_by_osm_id')]
|
||||
public function placeType(string $osm_kind, string $osm_id): Response
|
||||
{
|
||||
|
||||
|
||||
$place = $this->entityManager->getRepository(Place::class)->findOneBy(['osm_kind' => $osm_kind, 'osmId' => $osm_id]);
|
||||
if ($place) {
|
||||
$this->actionLogger->log('admin/placeType', ['osm_kind' => $osm_kind, 'osm_id' => $osm_id,
|
||||
'name' => $place->getName(),
|
||||
'code_insee' => $place->getZipCode(),
|
||||
'uuid' => $place->getUuidForUrl()
|
||||
]);
|
||||
$this->actionLogger->log('admin/placeType', [
|
||||
'osm_kind' => $osm_kind,
|
||||
'osm_id' => $osm_id,
|
||||
'name' => $place->getName(),
|
||||
'code_insee' => $place->getZipCode(),
|
||||
'uuid' => $place->getUuidForUrl()
|
||||
]);
|
||||
return $this->redirectToRoute('app_admin_commerce', ['id' => $place->getId()]);
|
||||
} else {
|
||||
$this->actionLogger->log('ERROR_admin/placeType', ['osm_kind' => $osm_kind, 'osm_id' => $osm_id]);
|
||||
|
@ -1520,11 +1525,11 @@ final class AdminController extends AbstractController
|
|||
public function podiumContributeursOsm(): Response
|
||||
{
|
||||
$this->actionLogger->log('admin/podium_contributeurs_osm', []);
|
||||
|
||||
|
||||
// Récupérer tous les lieux avec un utilisateur OSM
|
||||
$places = $this->entityManager->getRepository(Place::class)->findBy(['osm_user' => null], ['osm_user' => 'ASC']);
|
||||
$places = array_filter($places, fn($place) => $place->getOsmUser() !== null);
|
||||
|
||||
|
||||
// Compter les contributions par utilisateur
|
||||
$contributions = [];
|
||||
foreach ($places as $place) {
|
||||
|
@ -1536,13 +1541,13 @@ final class AdminController extends AbstractController
|
|||
$contributions[$user]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Trier par nombre de contributions décroissant
|
||||
arsort($contributions);
|
||||
|
||||
|
||||
// Prendre les 10 premiers
|
||||
$topContributors = array_slice($contributions, 0, 10, true);
|
||||
|
||||
|
||||
return $this->render('admin/podium_contributeurs_osm.html.twig', [
|
||||
'contributors' => $topContributors
|
||||
]);
|
||||
|
@ -1555,15 +1560,17 @@ final class AdminController extends AbstractController
|
|||
|
||||
if ($request->isMethod('POST')) {
|
||||
$uploadedFile = $request->files->get('json_file');
|
||||
|
||||
|
||||
if (!$uploadedFile) {
|
||||
$this->addFlash('error', 'Aucun fichier JSON n\'a été fourni.');
|
||||
return $this->redirectToRoute('app_admin_import_stats');
|
||||
}
|
||||
|
||||
// Vérifier le type de fichier
|
||||
if ($uploadedFile->getClientMimeType() !== 'application/json' &&
|
||||
$uploadedFile->getClientOriginalExtension() !== 'json') {
|
||||
if (
|
||||
$uploadedFile->getClientMimeType() !== 'application/json' &&
|
||||
$uploadedFile->getClientOriginalExtension() !== 'json'
|
||||
) {
|
||||
$this->addFlash('error', 'Le fichier doit être au format JSON.');
|
||||
return $this->redirectToRoute('app_admin_import_stats');
|
||||
}
|
||||
|
@ -1598,7 +1605,7 @@ final class AdminController extends AbstractController
|
|||
|
||||
// Vérifier si l'objet Stats existe déjà
|
||||
$existingStats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $zone]);
|
||||
|
||||
|
||||
if ($existingStats) {
|
||||
$skippedCount++;
|
||||
continue; // Ignorer les objets existants
|
||||
|
@ -1607,9 +1614,9 @@ final class AdminController extends AbstractController
|
|||
// Créer un nouvel objet Stats
|
||||
$stats = new Stats();
|
||||
$stats->setZone($zone)
|
||||
->setName($name)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime());
|
||||
->setName($name)
|
||||
->setDateCreated(new \DateTime())
|
||||
->setDateModified(new \DateTime());
|
||||
|
||||
// Remplir les champs optionnels
|
||||
if (isset($statData['population'])) {
|
||||
|
@ -1656,7 +1663,6 @@ final class AdminController extends AbstractController
|
|||
|
||||
$this->entityManager->persist($stats);
|
||||
$createdCount++;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = "Ligne " . ($index + 1) . ": " . $e->getMessage();
|
||||
}
|
||||
|
@ -1680,7 +1686,6 @@ final class AdminController extends AbstractController
|
|||
'skipped' => $skippedCount,
|
||||
'errors' => count($errors)
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->addFlash('error', 'Erreur lors de l\'import : ' . $e->getMessage());
|
||||
$this->actionLogger->log('admin/import_stats_error', ['error' => $e->getMessage()]);
|
||||
|
@ -1696,7 +1701,7 @@ final class AdminController extends AbstractController
|
|||
public function exportOverpassCsv($insee_code): Response
|
||||
{
|
||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||
|
||||
|
||||
if (!$stats) {
|
||||
throw $this->createNotFoundException('Stats non trouvées pour ce code INSEE');
|
||||
}
|
||||
|
@ -1747,7 +1752,7 @@ final class AdminController extends AbstractController
|
|||
public function exportTableCsv($insee_code): Response
|
||||
{
|
||||
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
|
||||
|
||||
|
||||
if (!$stats) {
|
||||
throw $this->createNotFoundException('Stats non trouvées pour ce code INSEE');
|
||||
}
|
||||
|
@ -1784,7 +1789,7 @@ final class AdminController extends AbstractController
|
|||
$osmKind = $place->getOsmKind();
|
||||
$osmId = $place->getOsmId();
|
||||
$osmLink = ($osmKind && $osmId) ? 'https://www.openstreetmap.org/' . $osmKind . '/' . $osmId : '';
|
||||
|
||||
|
||||
// Construire l'adresse complète
|
||||
$address = '';
|
||||
if ($place->getHousenumber() && $place->getStreet()) {
|
||||
|
@ -1792,7 +1797,7 @@ final class AdminController extends AbstractController
|
|||
} elseif ($place->getStreet()) {
|
||||
$address = $place->getStreet();
|
||||
}
|
||||
|
||||
|
||||
fputcsv($output, [
|
||||
$place->getName() ?: '(sans nom)',
|
||||
$place->getEmail() ?: '',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue