diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php
index 0e3117e7..943bac7e 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 4fd5e1bd..442f5b17 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)
+
+
+ # | id | main_tag | osm_kind | nom | lat | lon |
+
+
+ {% for p in places %}
+
+ {{ loop.index }} |
+ {{ p.getOsmId() }} |
+ {{ p.getMainTag() }} |
+ {{ p.getOsmKind() }} |
+ {{ p.getName() }} |
+ {{ p.getLat() }} |
+ {{ p.getLon() }} |
+
+ {% endfor %}
+
+
+
+ {% endif %}