From afc120ef2afc41b48c501b0b3a810054fa3e5457 Mon Sep 17 00:00:00 2001 From: Tykayn Date: Sun, 29 Jun 2025 17:23:54 +0200 Subject: [PATCH] add overpass query and josm --- src/Controller/FollowUpController.php | 48 ++++++++++++++++++++++++ src/Service/Motocultrice.php | 2 + templates/admin/followup_graph.html.twig | 29 +++++++++++++- templates/admin/stats.html.twig | 31 +++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/Controller/FollowUpController.php b/src/Controller/FollowUpController.php index 8a13e06..5105e1b 100644 --- a/src/Controller/FollowUpController.php +++ b/src/Controller/FollowUpController.php @@ -85,6 +85,14 @@ class FollowUpController extends AbstractController 'label' => 'Sous-stations électriques', 'objects' => array_filter($elements, fn($el) => ($el['tags']['power'] ?? null) === 'substation') ], + 'laboratory' => [ + 'label' => 'Laboratoires d\'analyse', + 'objects' => array_filter($elements, fn($el) => ($el['tags']['healthcare'] ?? null) === 'laboratory') + ], + 'school' => [ + 'label' => 'Écoles', + 'objects' => array_filter($elements, fn($el) => ($el['tags']['amenity'] ?? null) === 'school') + ], ]; $now = new \DateTime(); foreach ($types as $type => $data) { @@ -130,6 +138,14 @@ class FollowUpController extends AbstractController $completed = array_filter($data['objects'], function($el) { return !empty($el['tags']['substation'] ?? null); }); + } elseif ($type === 'laboratory') { + $completed = array_filter($data['objects'], function($el) { + return !empty($el['tags']['website'] ?? null) || !empty($el['tags']['contact:website'] ?? null); + }); + } elseif ($type === 'school') { + $completed = array_filter($data['objects'], function($el) { + return !empty($el['tags']['ref:UAI'] ?? null) && !empty($el['tags']['isced:level'] ?? null) && !empty($el['tags']['school:FR'] ?? null); + }); } $completion = count($data['objects']) > 0 ? round(count($completed) / count($data['objects']) * 100) : 0; $followupCompletion = new CityFollowUp(); @@ -195,6 +211,14 @@ class FollowUpController extends AbstractController 'label' => 'Sous-stations électriques', 'objects' => array_filter($elements, fn($el) => ($el['tags']['power'] ?? null) === 'substation') ], + 'laboratory' => [ + 'label' => 'Laboratoires d\'analyse', + 'objects' => array_filter($elements, fn($el) => ($el['tags']['healthcare'] ?? null) === 'laboratory') + ], + 'school' => [ + 'label' => 'Écoles', + 'objects' => array_filter($elements, fn($el) => ($el['tags']['amenity'] ?? null) === 'school') + ], ]; $now = new \DateTime(); foreach ($types as $type => $data) { @@ -238,6 +262,14 @@ class FollowUpController extends AbstractController $completed = array_filter($data['objects'], function($el) { return !empty($el['tags']['substation'] ?? null); }); + } elseif ($type === 'laboratory') { + $completed = array_filter($data['objects'], function($el) { + return !empty($el['tags']['website'] ?? null) || !empty($el['tags']['contact:website'] ?? null); + }); + } elseif ($type === 'school') { + $completed = array_filter($data['objects'], function($el) { + return !empty($el['tags']['ref:UAI'] ?? null) && !empty($el['tags']['isced:level'] ?? null) && !empty($el['tags']['school:FR'] ?? null); + }); } $completion = count($data['objects']) > 0 ? round(count($completed) / count($data['objects']) * 100) : 0; $followupCompletion = new CityFollowUp(); @@ -316,6 +348,14 @@ class FollowUpController extends AbstractController 'label' => 'Sous-stations électriques', 'objects' => array_filter($elements, fn($el) => ($el['tags']['power'] ?? null) === 'substation') ], + 'laboratory' => [ + 'label' => 'Laboratoires d\'analyse', + 'objects' => array_filter($elements, fn($el) => ($el['tags']['healthcare'] ?? null) === 'laboratory') + ], + 'school' => [ + 'label' => 'Écoles', + 'objects' => array_filter($elements, fn($el) => ($el['tags']['amenity'] ?? null) === 'school') + ], ]; foreach ($types as $type => $data) { // Suivi du nombre @@ -358,6 +398,14 @@ class FollowUpController extends AbstractController $completed = array_filter($data['objects'], function($el) { return !empty($el['tags']['substation'] ?? null); }); + } elseif ($type === 'laboratory') { + $completed = array_filter($data['objects'], function($el) { + return !empty($el['tags']['website'] ?? null) || !empty($el['tags']['contact:website'] ?? null); + }); + } elseif ($type === 'school') { + $completed = array_filter($data['objects'], function($el) { + return !empty($el['tags']['ref:UAI'] ?? null) && !empty($el['tags']['isced:level'] ?? null) && !empty($el['tags']['school:FR'] ?? null); + }); } $completion = count($data['objects']) > 0 ? round(count($completed) / count($data['objects']) * 100) : 0; $followupCompletion = new CityFollowUp(); diff --git a/src/Service/Motocultrice.php b/src/Service/Motocultrice.php index b8fe30b..7313add 100644 --- a/src/Service/Motocultrice.php +++ b/src/Service/Motocultrice.php @@ -573,6 +573,8 @@ area["ref:INSEE"="$zone"]->.searchArea; nwr["man_made"="surveillance"](area.searchArea); nwr["amenity"="recycling"](area.searchArea); nwr["power"="substation"](area.searchArea); + nwr["healthcare"="laboratory"](area.searchArea); + nwr["amenity"="school"](area.searchArea); ); out body; >; diff --git a/templates/admin/followup_graph.html.twig b/templates/admin/followup_graph.html.twig index 6c26b4b..c1feb97 100644 --- a/templates/admin/followup_graph.html.twig +++ b/templates/admin/followup_graph.html.twig @@ -19,11 +19,34 @@ 'defibrillator': 'Défibrillateurs', 'camera': 'Caméras de surveillance', 'recycling': 'Points de recyclage', - 'substation': 'Sous-stations électriques' + 'substation': 'Sous-stations électriques', + 'laboratory': "Laboratoires d'analyse", + 'school': 'Écoles' } %} {% for type in type_labels|keys %}

{{ type_labels[type] }}

+
+ {% set overpass_queries = { + 'fire_hydrant': 'nwr["emergency"="fire_hydrant"](area.searchArea);', + 'charging_station': 'nwr["amenity"="charging_station"](area.searchArea);', + 'toilets': 'nwr["amenity"="toilets"](area.searchArea);', + 'bus_stop': 'nwr["highway"="bus_stop"](area.searchArea);', + 'defibrillator': 'nwr["emergency"="defibrillator"](area.searchArea);', + 'camera': 'nwr["man_made"="surveillance"](area.searchArea);', + 'recycling': 'nwr["amenity"="recycling"](area.searchArea);', + 'substation': 'nwr["power"="substation"](area.searchArea);', + 'laboratory': 'nwr["healthcare"="laboratory"](area.searchArea);', + 'school': 'nwr["amenity"="school"](area.searchArea);' + } %} + {% set overpass_query = '[out:json][timeout:60];\narea["ref:INSEE"="' ~ stats.zone ~ '"]->.searchArea;\n(' ~ overpass_queries[type]|default('') ~ ');\n\n(._;>;);\n\nout meta;\n>;' %} + + Voir sur Overpass Turbo + + + Ouvrir dans JOSM + +
{% endfor %}

Données brutes

@@ -66,7 +89,9 @@ defibrillator: 'Défibrillateurs', camera: 'Caméras de surveillance', recycling: 'Points de recyclage', - substation: 'Sous-stations électriques' + substation: 'Sous-stations électriques', + laboratory: "Laboratoires d'analyse", + school: 'Écoles' }; function formatDelta(val) { if (val === null) return '-'; diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig index 35922f4..d9fbd14 100644 --- a/templates/admin/stats.html.twig +++ b/templates/admin/stats.html.twig @@ -329,6 +329,37 @@ +{% set followup_icons = { + 'fire_hydrant': 'bi-droplet', + 'charging_station': 'bi-lightning-charge', + 'toilets': 'bi-toilet', + 'bus_stop': 'bi-bus-front', + 'defibrillator': 'bi-heart-pulse', + 'camera': 'bi-camera-video', + 'recycling': 'bi-recycle', + 'substation': 'bi-plug', + 'laboratory': 'bi-beaker', + 'school': 'bi-mortarboard', + 'places': 'bi-geo-alt' +} %} + +
+ {% for type, data in latestFollowups %} + {% if data.count or data.completion %} +
+
+
+
+ {{ type_labels[type]|default(type|capitalize) }}
+ N = {{ data.count ? data.count.getMeasure() : '?' }}
+ Compl. = {{ data.completion ? data.completion.getMeasure() : '?' }}% +
+
+
+ {% endif %} + {% endfor %} +
+ {% endblock %} {% block javascripts %}