up dashboard osmose de ville
This commit is contained in:
parent
1535cf8ee3
commit
684bf1da66
3 changed files with 108 additions and 27 deletions
|
@ -2410,6 +2410,9 @@ final class AdminController extends AbstractController
|
||||||
// Récupérer tous les thèmes disponibles
|
// Récupérer tous les thèmes disponibles
|
||||||
$themes = $this->followUpService->getFollowUpThemes();
|
$themes = $this->followUpService->getFollowUpThemes();
|
||||||
|
|
||||||
|
// Liste complète des items Osmose à utiliser
|
||||||
|
$allOsmoseItems = '7051%2C7070%2C7100%2C7150%2C7160%2C7170%2C7190%2C7220%2C7240%2C7250%2C8010%2C8020%2C8021%2C8030%2C8031%2C8050%2C8051%2C8090%2C8091%2C8101%2C8110%2C8121%2C8150%2C8151%2C8180%2C8191%2C8201%2C8211%2C8221%2C8230%2C8240';
|
||||||
|
|
||||||
// Récupérer les problèmes Osmose pour cette ville
|
// Récupérer les problèmes Osmose pour cette ville
|
||||||
$osmoseIssues = $this->getOsmoseIssuesForCity($city, $theme);
|
$osmoseIssues = $this->getOsmoseIssuesForCity($city, $theme);
|
||||||
|
|
||||||
|
@ -2485,6 +2488,24 @@ final class AdminController extends AbstractController
|
||||||
// Ajouter le libellé pour "Autres"
|
// Ajouter le libellé pour "Autres"
|
||||||
$themes['other'] = 'Autres problèmes';
|
$themes['other'] = 'Autres problèmes';
|
||||||
|
|
||||||
|
// Calculer la bounding box pour la ville
|
||||||
|
$bbox = $this->calculateBoundingBox($city->getLat(), $city->getLon(), 5);
|
||||||
|
|
||||||
|
// Récupérer les items Osmose correspondant aux thèmes si un thème spécifique est sélectionné
|
||||||
|
$itemsParam = $theme !== 'all' ?
|
||||||
|
(!empty($this->getOsmoseItemIdsForTheme($theme)) ? implode('%2C', $this->getOsmoseItemIdsForTheme($theme)) : $allOsmoseItems) :
|
||||||
|
$allOsmoseItems;
|
||||||
|
|
||||||
|
// Construire l'URL de l'API Osmose pour le GeoJSON
|
||||||
|
$jsonOsmoseUrl = sprintf(
|
||||||
|
'https://osmose.openstreetmap.fr/api/0.3/issues.geojson?zoom=14&item=%s&level=1%%2C2%%2C3&class=&source=&limit=500&bbox=%f%%2C%f%%2C%f%%2C%f',
|
||||||
|
$itemsParam,
|
||||||
|
$bbox['min_lon'],
|
||||||
|
$bbox['min_lat'],
|
||||||
|
$bbox['max_lon'],
|
||||||
|
$bbox['max_lat']
|
||||||
|
);
|
||||||
|
|
||||||
return $this->render('admin/osmose_issues_map.html.twig', [
|
return $this->render('admin/osmose_issues_map.html.twig', [
|
||||||
'city' => $city,
|
'city' => $city,
|
||||||
'theme' => $theme,
|
'theme' => $theme,
|
||||||
|
@ -2492,7 +2513,18 @@ final class AdminController extends AbstractController
|
||||||
'osmoseIssues' => $osmoseIssues,
|
'osmoseIssues' => $osmoseIssues,
|
||||||
'issuesByTheme' => $issuesByTheme,
|
'issuesByTheme' => $issuesByTheme,
|
||||||
'issuesByLevel' => $issuesByLevel,
|
'issuesByLevel' => $issuesByLevel,
|
||||||
'osmoseApiUrl' => 'https://osmose.openstreetmap.fr/fr/map/#zoom=14&lat=' . $city->getLat() . '&lon=' . $city->getLon()
|
|
||||||
|
'mapbox_token' => $_ENV['MAPBOX_TOKEN'] ?? null,
|
||||||
|
'maptiler_token' => $_ENV['MAPTILER_TOKEN'] ?? null,
|
||||||
|
'jsonOsmose' => $jsonOsmoseUrl,
|
||||||
|
'osmoseApiUrl' => sprintf(
|
||||||
|
'https://osmose.openstreetmap.fr/fr/map/#zoom=14&lat=%s&lon=%s&item=%s&level=1%%2C2%%2C3&loc=14/%s/%s',
|
||||||
|
$city->getLat(),
|
||||||
|
$city->getLon(),
|
||||||
|
$allOsmoseItems,
|
||||||
|
$city->getLat(),
|
||||||
|
$city->getLon()
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2531,36 +2563,62 @@ final class AdminController extends AbstractController
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Appeler l'API Osmose
|
// Appeler l'API Osmose
|
||||||
$response = file_get_contents($osmoseApiUrl);
|
$context = stream_context_create([
|
||||||
|
'http' => [
|
||||||
|
'timeout' => 30, // Augmenter le timeout à 30 secondes
|
||||||
|
'user_agent' => 'OSM-Commerces/1.0'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = file_get_contents($osmoseApiUrl, false, $context);
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
throw new \Exception('Échec de la récupération des données Osmose');
|
throw new \Exception('Échec de la récupération des données Osmose');
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = json_decode($response, true);
|
$data = json_decode($response, true);
|
||||||
if (isset($data['issues'])) {
|
if (isset($data['issues']) && is_array($data['issues'])) {
|
||||||
foreach ($data['issues'] as $issue) {
|
foreach ($data['issues'] as $issue) {
|
||||||
|
// Vérifier si l'issue a les propriétés nécessaires
|
||||||
|
if (!isset($issue['lat']) || !isset($issue['lon'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Vérifier si l'issue est dans les limites de la ville (approximativement)
|
// Vérifier si l'issue est dans les limites de la ville (approximativement)
|
||||||
if ($this->isPointInCity($issue['lat'], $issue['lon'], $lat, $lon, 5)) {
|
// Utiliser un rayon plus grand (10km) pour inclure plus d'issues
|
||||||
|
if ($this->isPointInCity($issue['lat'], $issue['lon'], $lat, $lon, 10)) {
|
||||||
$issues[] = [
|
$issues[] = [
|
||||||
'id' => $issue['id'],
|
'id' => $issue['id'] ?? '',
|
||||||
'title' => $issue['title'] ?? 'Problème sans titre',
|
'title' => $issue['title'] ?? 'Problème sans titre',
|
||||||
'subtitle' => $issue['subtitle'] ?? '',
|
'subtitle' => $issue['subtitle'] ?? '',
|
||||||
'lat' => $issue['lat'],
|
'lat' => $issue['lat'],
|
||||||
'lon' => $issue['lon'],
|
'lon' => $issue['lon'],
|
||||||
'item' => $issue['item'],
|
'item' => $issue['item'] ?? '',
|
||||||
'class' => $issue['class'],
|
'class' => $issue['class'] ?? '',
|
||||||
'level' => $issue['level'] ?? 2,
|
'level' => $issue['level'] ?? 2,
|
||||||
'update_timestamp' => $issue['update_timestamp'] ?? null,
|
'update_timestamp' => $issue['update_timestamp'] ?? null,
|
||||||
'url' => sprintf('https://osmose.openstreetmap.fr/fr/issue/%s', $issue['uuid'])
|
'url' => isset($issue['uuid']) ? sprintf('https://osmose.openstreetmap.fr/fr/issue/%s', $issue['uuid']) : '#'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Si aucune issue n'a été trouvée, ajouter un message de log
|
||||||
|
if (empty($issues)) {
|
||||||
|
$this->actionLogger->log('osmose_no_issues', [
|
||||||
|
'insee_code' => $city->getZone(),
|
||||||
|
'theme' => $theme,
|
||||||
|
'url' => $osmoseApiUrl
|
||||||
|
]);
|
||||||
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->actionLogger->log('error_osmose_api', [
|
$this->actionLogger->log('error_osmose_api', [
|
||||||
'insee_code' => $city->getZone(),
|
'insee_code' => $city->getZone(),
|
||||||
'error' => $e->getMessage()
|
'error' => $e->getMessage(),
|
||||||
|
'url' => $osmoseApiUrl
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Ajouter un message flash pour informer l'utilisateur
|
||||||
|
$this->addFlash('warning', 'Impossible de récupérer les problèmes Osmose : ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $issues;
|
return $issues;
|
||||||
|
|
|
@ -102,9 +102,14 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 text-end">
|
<div class="col-md-6 text-end">
|
||||||
<a href="{{ osmoseApiUrl }}" target="_blank" class="btn btn-primary">
|
<div class="btn-group">
|
||||||
<i class="fas fa-external-link-alt"></i> Voir sur Osmose
|
<a href="{{ osmoseApiUrl }}" target="_blank" class="btn btn-primary">
|
||||||
</a>
|
<i class="fas fa-external-link-alt"></i> Voir sur Osmose
|
||||||
|
</a>
|
||||||
|
<a href="{{ jsonOsmose }}" target="_blank" class="btn btn-success">
|
||||||
|
<i class="fas fa-download"></i> Télécharger GeoJSON
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -268,11 +273,17 @@
|
||||||
// Initialiser la carte avec MapLibre
|
// Initialiser la carte avec MapLibre
|
||||||
const map = new maplibregl.Map({
|
const map = new maplibregl.Map({
|
||||||
container: 'map',
|
container: 'map',
|
||||||
style: 'https://demotiles.maplibre.org/style.json', // style URL
|
style: 'https://api.maptiler.com/maps/streets/style.json?key={{ maptiler_token|default("") }}', // Utiliser MapTiler si disponible
|
||||||
center: [{{ city.lon }}, {{ city.lat }}], // Note: MapLibre uses [longitude, latitude] order
|
center: [{{ city.lon }}, {{ city.lat }}], // Note: MapLibre uses [longitude, latitude] order
|
||||||
zoom: 13
|
zoom: 13
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Gérer les erreurs de chargement de la carte
|
||||||
|
map.on('error', function(e) {
|
||||||
|
console.error('Erreur de chargement de la carte:', e.error);
|
||||||
|
document.getElementById('map').innerHTML = '<div class="alert alert-danger">Erreur de chargement de la carte. Veuillez réessayer plus tard.</div>';
|
||||||
|
});
|
||||||
|
|
||||||
// Ajouter les contrôles de navigation
|
// Ajouter les contrôles de navigation
|
||||||
map.addControl(new maplibregl.NavigationControl());
|
map.addControl(new maplibregl.NavigationControl());
|
||||||
|
|
||||||
|
@ -299,6 +310,13 @@
|
||||||
});
|
});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
// Vérifier s'il y a des problèmes à afficher
|
||||||
|
if (features.length === 0) {
|
||||||
|
// Ajouter un message si aucun problème n'est trouvé
|
||||||
|
const mapContainer = document.getElementById('map');
|
||||||
|
mapContainer.insertAdjacentHTML('afterend', '<div class="alert alert-info mt-3">Aucun problème Osmose trouvé pour cette ville avec le filtre actuel.</div>');
|
||||||
|
}
|
||||||
|
|
||||||
// Ajouter la source de données à la carte
|
// Ajouter la source de données à la carte
|
||||||
map.addSource('issues', {
|
map.addSource('issues', {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
|
|
|
@ -294,20 +294,25 @@
|
||||||
<div class="row mb-4" id="themes">
|
<div class="row mb-4" id="themes">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h2 class="section-anchor">Thèmes</h2>
|
<h2 class="section-anchor">Thèmes</h2>
|
||||||
<ul class="nav nav-tabs" id="themeTabs" role="tablist">
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
<li class="nav-item" role="presentation">
|
<ul class="nav nav-tabs" id="themeTabs" role="tablist">
|
||||||
<button class="nav-link active" id="tab-table" data-bs-toggle="tab"
|
<li class="nav-item" role="presentation">
|
||||||
data-bs-target="#tabTableContent" type="button" role="tab"
|
<button class="nav-link active" id="tab-table" data-bs-toggle="tab"
|
||||||
aria-controls="tabTableContent" aria-selected="true">Tableau
|
data-bs-target="#tabTableContent" type="button" role="tab"
|
||||||
</button>
|
aria-controls="tabTableContent" aria-selected="true">Tableau
|
||||||
</li>
|
</button>
|
||||||
<li class="nav-item" role="presentation">
|
</li>
|
||||||
<button class="nav-link" id="tab-cards" data-bs-toggle="tab"
|
<li class="nav-item" role="presentation">
|
||||||
data-bs-target="#tabCardsContent" type="button" role="tab"
|
<button class="nav-link" id="tab-cards" data-bs-toggle="tab"
|
||||||
aria-controls="tabCardsContent" aria-selected="false">Cartes
|
data-bs-target="#tabCardsContent" type="button" role="tab"
|
||||||
</button>
|
aria-controls="tabCardsContent" aria-selected="false">Cartes
|
||||||
</li>
|
</button>
|
||||||
</ul>
|
</li>
|
||||||
|
</ul>
|
||||||
|
<a href="{{ path('app_admin_osmose_issues_map', {'inseeCode': stats.zone}) }}" class="btn btn-primary">
|
||||||
|
<i class="bi bi-exclamation-triangle"></i> Voir les alertes Osmose
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div class="tab-content" id="themeTabsContent">
|
<div class="tab-content" id="themeTabsContent">
|
||||||
<div class="tab-pane fade show active" id="tabTableContent" role="tabpanel"
|
<div class="tab-pane fade show active" id="tabTableContent" role="tabpanel"
|
||||||
aria-labelledby="tab-table">
|
aria-labelledby="tab-table">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue