From 2fd0d8d93389b88ff092f83dab4fa171ee37906f Mon Sep 17 00:00:00 2001 From: Tykayn Date: Sat, 5 Jul 2025 15:25:33 +0200 Subject: [PATCH] tests liens ctc --- src/Controller/AdminController.php | 100 +++++++++- .../admin/followup_theme_graph.html.twig | 106 ++++++++++ templates/admin/stats.html.twig | 187 +++++++++++------- 3 files changed, 315 insertions(+), 78 deletions(-) diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php index 0e3117e..943bac7 100644 --- a/src/Controller/AdminController.php +++ b/src/Controller/AdminController.php @@ -468,10 +468,11 @@ final class AdminController extends AbstractController 'followup_labels' => \App\Service\FollowUpService::getFollowUpThemes(), 'followup_icons' => \App\Service\FollowUpService::getFollowUpIcons(), 'progression7Days' => $progression7Days, + 'all_types' => \App\Service\FollowUpService::getFollowUpThemes(), ]); } - #[Route('/admin/stats/{insee_code}/followup-graph/{theme}', name: 'admin_followup_theme_graph', requirements: ['insee_code' => '\\d+'])] + #[Route('/admin/stats/{insee_code}/followup-graph/{theme}', name: 'admin_followup_theme_graph', requirements: ['insee_code' => '\d+'])] public function followupThemeGraph(string $insee_code, string $theme): Response { $stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); @@ -510,11 +511,94 @@ final class AdminController extends AbstractController usort($countData, fn($a, $b) => $a['date'] <=> $b['date']); usort($completionData, fn($a, $b) => $a['date'] <=> $b['date']); - $this->actionLogger->log('followup_theme_graph', [ - 'insee_code' => $insee_code, - 'theme' => $theme, - 'theme_label' => $themes[$theme] ?? 'Unknown' - ]); + // Récupérer les objets du thème (Place) pour la ville + $places = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code]); + $motocultrice = $this->motocultrice; + $objects = []; + // Récupérer la correspondance thème <-> requête Overpass + $themeQueries = \App\Service\FollowUpService::getFollowUpOverpassQueries(); + $overpass_type_query = $themeQueries[$theme] ?? ''; + if ($overpass_type_query) { + $overpass_query = "[out:json][timeout:60];\narea[\"ref:INSEE\"=\"$insee_code\"]->.searchArea;\n($overpass_type_query);\n(._;>;);\nout meta;\n>;"; + $josm_url = 'http://127.0.0.1:8111/import?url=https://overpass-api.de/api/interpreter?data=' . urlencode($overpass_query); + } else { + $josm_url = null; + } + // Fonction utilitaire pour extraire clé/valeur de la requête Overpass + $extractTag = function($query) { + if (preg_match('/\\[([a-zA-Z0-9:_-]+)\\]="([^"]+)"/', $query, $matches)) { + return [$matches[1], $matches[2]]; + } + return [null, null]; + }; + list($tagKey, $tagValue) = $extractTag($themeQueries[$theme] ?? ''); + foreach ($places as $place) { + $match = false; + // Cas particulier healthcare + if ($theme === 'healthcare') { + $main_tag = $place->getMainTag(); + if ($main_tag && ( + str_starts_with($main_tag, 'healthcare=') || + in_array($main_tag, [ + 'amenity=doctors', + 'amenity=pharmacy', + 'amenity=hospital', + 'amenity=clinic', + 'amenity=social_facility' + ]) + )) { + $match = true; + } + } elseif ($tagKey && $tagValue) { + // On tente de retrouver la valeur du tag dans les propriétés Place + $main_tag = $place->getMainTag(); + if ($main_tag === "$tagKey=$tagValue") { + $match = true; + } + // Cas particuliers pour certains tags stockés ailleurs + if (!$match) { + if ($tagKey === 'highway' && method_exists($place, 'getOsmKind') && $place->getOsmKind() === $tagValue) { + $match = true; + } + } + } + if ($match && $place->getLat() && $place->getLon()) { + $objects[] = [ + 'id' => $place->getOsmId(), + 'osm_kind' => $place->getOsmKind(), + 'lat' => $place->getLat(), + 'lon' => $place->getLon(), + 'name' => $place->getName(), + 'tags' => [ 'main_tag' => $place->getMainTag() ], + 'is_complete' => !empty($place->getName()), + 'osm_url' => 'https://www.openstreetmap.org/' . $place->getOsmKind() . '/' . $place->getOsmId(), + ]; + } + } + $geojson = [ + 'type' => 'FeatureCollection', + 'features' => array_map(function($obj) { + return [ + 'type' => 'Feature', + 'geometry' => [ + 'type' => 'Point', + 'coordinates' => [$obj['lon'], $obj['lat']] + ], + 'properties' => $obj + ]; + }, $objects) + ]; + + // Centre de la carte : centre géographique des objets ou de la ville + $center = null; + if (count($objects) > 0) { + $lat = array_sum(array_column($objects, 'lat')) / count($objects); + $lon = array_sum(array_column($objects, 'lon')) / count($objects); + $center = [$lon, $lat]; + } elseif ($stats->getPlaces()->count() > 0) { + $first = $stats->getPlaces()->first(); + $center = [$first->getLon(), $first->getLat()]; + } return $this->render('admin/followup_theme_graph.html.twig', [ 'stats' => $stats, @@ -523,6 +607,10 @@ final class AdminController extends AbstractController 'count_data' => json_encode($countData), 'completion_data' => json_encode($completionData), 'icons' => \App\Service\FollowUpService::getFollowUpIcons(), + 'geojson' => json_encode($geojson), + 'josm_url' => $josm_url, + 'center' => $center, + 'maptiler_token' => $_ENV['MAPTILER_TOKEN'] ?? null, ]); } diff --git a/templates/admin/followup_theme_graph.html.twig b/templates/admin/followup_theme_graph.html.twig index 4fd5e1b..442f5b1 100644 --- a/templates/admin/followup_theme_graph.html.twig +++ b/templates/admin/followup_theme_graph.html.twig @@ -4,6 +4,7 @@ {% block stylesheets %} {{ parent() }} + {% endblock %} {% block body %}
+ {# DEBUG : Affichage des objets Place trouvés pour cette ville #} + {% if places is defined %} +
+ DEBUG : Objets Place trouvés pour cette ville (avant filtrage)
+ + + + + + {% for p in places %} + + + + + + + + + + {% endfor %} + +
#idmain_tagosm_kindnomlatlon
{{ loop.index }}{{ p.getOsmId() }}{{ p.getMainTag() }}{{ p.getOsmKind() }}{{ p.getName() }}{{ p.getLat() }}{{ p.getLon() }}
+
+ {% endif %}
@@ -125,6 +163,15 @@
+ {% if josm_url %} + + Ouvrir tous les objets dans JOSM + + {% else %} +
Aucun objet sélectionné pour ce thème, rien à charger dans JOSM.
+ {% endif %} +
+
-
@@ -165,6 +212,65 @@ {% block javascripts %} {{ parent() }} + + diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig index b68edc5..52c1c9f 100644 --- a/templates/admin/stats.html.twig +++ b/templates/admin/stats.html.twig @@ -218,14 +218,12 @@
- +
- - @@ -294,79 +292,51 @@
Catégorie Thème Nombre ComplétionProgression 7j Actions
- {% for group_name, group_types in theme_groups %} -
-
- {% if group_name == 'emergency' %}🚨 Urgence - {% elseif group_name == 'transport' %}🚌 Transport - {% elseif group_name == 'healthcare' %}🏥 Santé - {% elseif group_name == 'education' %}🎓 Éducation - {% elseif group_name == 'security' %}🛡️ Sécurité - {% elseif group_name == 'infrastructure' %}🏗️ Infrastructure - {% else %}{{ group_name|capitalize }} + {% set all_types = followup_labels|keys %} +
+ {% for type in all_types %} + {% set data = latestFollowups[type]|default(null) %} + {% set overpass_query = '[out:json][timeout:60];\narea["ref:INSEE"="' ~ stats.zone ~ '"]->.searchArea;\n(' ~ overpass_type_queries[type]|default('') ~ ');\n(._;>;);\nout meta;\n>;' %} + {% set completion = data and data.completion is defined ? data.completion.getMeasure() : null %} + {% set completion_class = '' %} + {% if completion is not null %} + {% if completion < 40 %} + {% set completion_class = 'completion-low' %} + {% elseif completion < 80 %} + {% set completion_class = 'completion-medium' %} + {% else %} + {% set completion_class = 'completion-high' %} {% endif %} -
-
- {% for type in group_types %} - {% set data = latestFollowups[type]|default(null) %} - {% set overpass_query = '[out:json][timeout:60];\narea["ref:INSEE"="' ~ stats.zone ~ '"]->.searchArea;\n(' ~ overpass_type_queries[type]|default('') ~ ');\n(._;>;);\nout meta;\n>;' %} - {% set completion = data and data.completion is defined ? data.completion.getMeasure() : null %} - {% set completion_class = '' %} - {% if completion is not null %} - {% if completion < 40 %} - {% set completion_class = 'completion-low' %} - {% elseif completion < 80 %} - {% set completion_class = 'completion-medium' %} - {% else %} - {% set completion_class = 'completion-high' %} - {% endif %} - {% endif %} -
-
-
-
- - -
- -
- {{ data and data.count is defined ? data.count.getMeasure() : '?' }} | - {{ completion is not null ? completion : '?' }}% -
-
- - - -
- {% if progression7Days[type] is defined %} - {% set countDelta = progression7Days[type].count %} - {% set completionDelta = progression7Days[type].completion %} - {% if countDelta is not null or completionDelta is not null %} - - {% if countDelta is not null %} - - {{ countDelta > 0 ? '+' ~ countDelta : countDelta == 0 ? '0' : countDelta }} - - {% endif %} - {% if completionDelta is not null %} - - {{ completionDelta > 0 ? '+' ~ completionDelta|round(1) : completionDelta == 0 ? '0' : completionDelta|round(1) }}% - - {% endif %} - - {% endif %} - {% endif %} -
+ {% endif %} +
+
+
+
+ + +
+ +
+ {{ data and data.count is defined ? data.count.getMeasure() : '?' }} | + {{ completion is not null ? completion : '?' }}% +
+
- {% endfor %} +
-
- {% endfor %} + {% endfor %} +
@@ -603,6 +573,48 @@
+ + + +
+
+
+ Tester les JSON Complète tes commerces +
+
+
    + {% set ctc_jsons = stats.getAllCTCUrlsMap() %} + {% for key, url in ctc_jsons %} +
  • {{ key }}
  • + {% endfor %} +
+
+
+ + +
+
+
+
+
+ + {% endblock %} @@ -1048,4 +1060,35 @@ if(dc ){ }); }); + {% endblock %}