diff --git a/src/Entity/Place.php b/src/Entity/Place.php index 50070a3..8f23bcc 100644 --- a/src/Entity/Place.php +++ b/src/Entity/Place.php @@ -106,6 +106,17 @@ class Place #[ORM\Column(nullable: true)] private ?\DateTime $osm_data_date = null; + #[ORM\Column(nullable: true)] + private ?int $osm_version = null; + + #[ORM\Column(length: 255, nullable: true)] + private ?string $osm_user = null; + + #[ORM\Column(nullable: true)] + private ?int $osm_uid = null; + + #[ORM\Column(nullable: true)] + private ?int $osm_changeset = null; public function getPlaceTypeName(): ?string { @@ -198,7 +209,7 @@ class Place /** * mettre à jour le lieu selon les tags osm */ - public function update_place_from_overpass_data(array $overpass_data) { + public function update_place_from_overpass_data(array $overpass_data) { if ( ! isset($overpass_data['tags']) || $overpass_data['tags'] == null) { return; @@ -216,7 +227,8 @@ class Place 'addr:street' => '', 'website' => '', 'wheelchair' => '', - 'note' => '' + 'note' => '', + 'fixme' => '', ], $overpass_data['tags'] ); @@ -231,15 +243,37 @@ class Place ->setLon($orignal_overpass_data['lon']) ->setName(isset($overpass_data['name']) && $overpass_data['name'] != '' ? $overpass_data['name'] : null); + // Traiter le timestamp OSM si disponible + if (isset($orignal_overpass_data['timestamp']) && $orignal_overpass_data['timestamp']) { + try { + $osmDate = new \DateTime($orignal_overpass_data['timestamp']); + $this->setOsmDataDate($osmDate); + } catch (\Exception $e) { + // En cas d'erreur de parsing de la date, on ignore + } + } + + // Traiter les autres métadonnées OSM + if (isset($orignal_overpass_data['version'])) { + $this->setOsmVersion($orignal_overpass_data['version']); + } + if (isset($orignal_overpass_data['user'])) { + $this->setOsmUser($orignal_overpass_data['user']); + } + if (isset($orignal_overpass_data['uid'])) { + $this->setOsmUid($orignal_overpass_data['uid']); + } + if (isset($orignal_overpass_data['changeset'])) { + $this->setOsmChangeset($orignal_overpass_data['changeset']); + } + $mapping = [ ['key' => 'postcode', 'setter' => 'setZipCode', 'source' => $overpass_data], ['key' => 'email', 'setter' => 'setEmail', 'source' => $overpass_data], ['key' => 'opening_hours', 'setter' => 'setHasOpeningHours', 'source' => $overpass_data['tags'] ?? []], - ['key' => 'note', 'setter' => 'setNote', 'source' => $overpass_data['tags'] ?? []], ['key' => 'addr:housenumber', 'setter' => 'setHasAddress', 'source' => $overpass_data['tags'] ?? []], ['key' => 'website', 'setter' => 'setHasWebsite', 'source' => $overpass_data['tags'] ?? []], ['key' => 'wheelchair', 'setter' => 'setHasWheelchair', 'source' => $overpass_data['tags'] ?? []], - ['key' => 'note', 'setter' => 'setHasNote', 'source' => $overpass_data['tags'] ?? []], ['key' => 'siret', 'setter' => 'setSiret', 'source' => $overpass_data['tags'] ?? []], ['key' => 'addr:street', 'setter' => 'setStreet', 'source' => $overpass_data['tags'] ?? []], ['key' => 'addr:housenumber', 'setter' => 'setHousenumber', 'source' => $overpass_data['tags'] ?? []], @@ -251,6 +285,26 @@ class Place } } + // Traiter les notes et fixme + $noteContent = ''; + $hasNote = false; + + if (isset($orignal_overpass_data['tags']['note']) && $orignal_overpass_data['tags']['note'] !== '') { + $noteContent .= $orignal_overpass_data['tags']['note']; + $hasNote = true; + } + + if (isset($orignal_overpass_data['tags']['fixme']) && $orignal_overpass_data['tags']['fixme'] !== '') { + if ($noteContent !== '') { + $noteContent .= "\n\n"; + } + $noteContent .= "FIXME: " . $orignal_overpass_data['tags']['fixme']; + $hasNote = true; + } + + $this->setNoteContent($noteContent); + $this->setHasNote($hasNote); + $this // ->setOsmId($overpass_data['id']) // ->setOsmKind($overpass_data['type']) @@ -263,8 +317,7 @@ class Place ->setHasOpeningHours($overpass_data['opening_hours'] ? true : false) ->setHasAddress($overpass_data['addr:housenumber'] && $overpass_data['addr:street'] ? true : false) ->setHasWebsite($overpass_data['website'] ? true : false) - ->setHasWheelchair($overpass_data['wheelchair'] and $overpass_data['wheelchair'] != '' ? true : false) - ->setHasNote($overpass_data['note'] and $overpass_data['note'] != '' ? true : false); + ->setHasWheelchair($overpass_data['wheelchair'] and $overpass_data['wheelchair'] != '' ? true : false); } public function __construct() @@ -643,4 +696,52 @@ class Place return $this; } + + public function getOsmVersion(): ?int + { + return $this->osm_version; + } + + public function setOsmVersion(?int $osm_version): static + { + $this->osm_version = $osm_version; + + return $this; + } + + public function getOsmUser(): ?string + { + return $this->osm_user; + } + + public function setOsmUser(?string $osm_user): static + { + $this->osm_user = $osm_user; + + return $this; + } + + public function getOsmUid(): ?int + { + return $this->osm_uid; + } + + public function setOsmUid(?int $osm_uid): static + { + $this->osm_uid = $osm_uid; + + return $this; + } + + public function getOsmChangeset(): ?int + { + return $this->osm_changeset; + } + + public function setOsmChangeset(?int $osm_changeset): static + { + $this->osm_changeset = $osm_changeset; + + return $this; + } } diff --git a/src/Service/Motocultrice.php b/src/Service/Motocultrice.php index 6cd6fed..b75f001 100644 --- a/src/Service/Motocultrice.php +++ b/src/Service/Motocultrice.php @@ -101,10 +101,10 @@ public function find_siret($tags) { public function get_export_query($zone) { return <<.searchArea; {$this->overpass_base_places} -out skel qt; +out meta; QUERY; } @@ -112,7 +112,7 @@ QUERY; return '[out:json][timeout:25]; area["ref:INSEE"="'.$zone.'"]->.searchArea; '.$this->overpass_base_places.' -out center tags;'; +out meta;'; } private $more_tags = ['image', 'ref:FR:SIRET']; @@ -180,7 +180,14 @@ out center tags;'; 'name' => $element['tags']['name'] ?? '', 'lat' => $element['lat'] ?? null, 'lon' => $element['lon'] ?? null, - 'tags' => $element['tags'] + 'tags' => $element['tags'], + // Métadonnées OSM + 'timestamp' => $element['timestamp'] ?? null, + 'version' => $element['version'] ?? null, + 'user' => $element['user'] ?? null, + 'uid' => $element['uid'] ?? null, + 'changeset' => $element['changeset'] ?? null, + 'modified' => $element['timestamp'] ?? null ]; } } diff --git a/templates/admin/stats_history.html.twig b/templates/admin/stats_history.html.twig index ab5508e..39786d7 100644 --- a/templates/admin/stats_history.html.twig +++ b/templates/admin/stats_history.html.twig @@ -11,33 +11,124 @@ document.addEventListener('DOMContentLoaded', function() { const ctx = document.getElementById('completionHistoryChart').getContext('2d'); + // Préparer les données pour chaque aspect + const labels = [ + {% for stat in statsHistory %} + '{{ stat.date|date('d/m/Y') }}'{% if not loop.last %},{% endif %} + {% endfor %} + ]; + + const completionData = [ + {% for stat in statsHistory %} + {{ stat.completionPercent }}{% if not loop.last %},{% endif %} + {% endfor %} + ]; + + const openingHoursData = [ + {% for stat in statsHistory %} + {% if stat.placesCount > 0 %} + {{ ((stat.openingHoursCount / stat.placesCount) * 100)|round(1) }}{% if not loop.last %},{% endif %} + {% else %} + 0{% if not loop.last %},{% endif %} + {% endif %} + {% endfor %} + ]; + + const addressData = [ + {% for stat in statsHistory %} + {% if stat.placesCount > 0 %} + {{ ((stat.addressCount / stat.placesCount) * 100)|round(1) }}{% if not loop.last %},{% endif %} + {% else %} + 0{% if not loop.last %},{% endif %} + {% endif %} + {% endfor %} + ]; + + const websiteData = [ + {% for stat in statsHistory %} + {% if stat.placesCount > 0 %} + {{ ((stat.websiteCount / stat.placesCount) * 100)|round(1) }}{% if not loop.last %},{% endif %} + {% else %} + 0{% if not loop.last %},{% endif %} + {% endif %} + {% endfor %} + ]; + + const siretData = [ + {% for stat in statsHistory %} + {% if stat.placesCount > 0 %} + {{ ((stat.siretCount / stat.placesCount) * 100)|round(1) }}{% if not loop.last %},{% endif %} + {% else %} + 0{% if not loop.last %},{% endif %} + {% endif %} + {% endfor %} + ]; + new Chart(ctx, { type: 'line', data: { - labels: [ - {% for stat in statsHistory %} - '{{ stat.date|date('d/m/Y') }}'{% if not loop.last %},{% endif %} - {% endfor %} - ], - datasets: [{ - label: 'Taux de complétion (%)', - data: [ - {% for stat in statsHistory %} - {{ stat.completionPercent }}{% if not loop.last %},{% endif %} - {% endfor %} - ], - borderColor: 'rgb(75, 192, 192)', - backgroundColor: 'rgba(75, 192, 192, 0.2)', - tension: 0.3, - fill: true - }] + labels: labels, + datasets: [ + { + label: 'Taux de complétion global (%)', + data: completionData, + borderColor: 'rgb(75, 192, 192)', + backgroundColor: 'rgba(75, 192, 192, 0.1)', + tension: 0.3, + fill: false, + borderWidth: 3 + }, + { + label: 'Horaires d\'ouverture (%)', + data: openingHoursData, + borderColor: 'rgb(255, 99, 132)', + backgroundColor: 'rgba(255, 99, 132, 0.1)', + tension: 0.3, + fill: false, + borderWidth: 2 + }, + { + label: 'Adresses (%)', + data: addressData, + borderColor: 'rgb(54, 162, 235)', + backgroundColor: 'rgba(54, 162, 235, 0.1)', + tension: 0.3, + fill: false, + borderWidth: 2 + }, + { + label: 'Sites web (%)', + data: websiteData, + borderColor: 'rgb(255, 205, 86)', + backgroundColor: 'rgba(255, 205, 86, 0.1)', + tension: 0.3, + fill: false, + borderWidth: 2 + }, + { + label: 'SIRET (%)', + data: siretData, + borderColor: 'rgb(153, 102, 255)', + backgroundColor: 'rgba(153, 102, 255, 0.1)', + tension: 0.3, + fill: false, + borderWidth: 2 + } + ] }, options: { responsive: true, plugins: { title: { display: true, - text: 'Évolution du taux de complétion au fil du temps' + text: 'Évolution des taux de complétion par aspect au fil du temps' + }, + legend: { + position: 'top', + labels: { + usePointStyle: true, + padding: 20 + } } }, scales: { @@ -46,7 +137,7 @@ document.addEventListener('DOMContentLoaded', function() { max: 100, title: { display: true, - text: 'Complétion (%)' + text: 'Pourcentage (%)' } }, x: { @@ -55,6 +146,10 @@ document.addEventListener('DOMContentLoaded', function() { text: 'Date' } } + }, + interaction: { + intersect: false, + mode: 'index' } } }); diff --git a/templates/public/home.html.twig b/templates/public/home.html.twig index d03cd22..437bc69 100644 --- a/templates/public/home.html.twig +++ b/templates/public/home.html.twig @@ -128,7 +128,7 @@ {% block javascripts %} {{ parent() }} - +{# #}