From a1860e9462e1cd5c9746a688acb4879b2e49786d Mon Sep 17 00:00:00 2001 From: yann64 Date: Thu, 4 Jun 2026 21:02:28 +0200 Subject: [PATCH] =?UTF-8?q?Page=20carte=20interactive=20des=20relev=C3=A9s?= =?UTF-8?q?=20(Leaflet=20+=20OpenStreetMap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CarteController : index() + data() (JSON) — requête lieux géolocalisés ayant des sources avec relevés, agrégats par lieu - Lieu model : relations sources() et releves() (hasManyThrough) - Vue carte/index.blade.php : carte Leaflet pleine hauteur, marqueurs colorés par nombre de sources (taille/couleur proportionnels), popup par lieu avec liste des sources, statuts, années et lien recherche - Tuiles OpenStreetMap inversées en mode sombre - Route GET /carte + GET /carte/data - Lien "Carte" dans la navigation desktop et mobile - @stack('head') dans le layout pour injecter Leaflet uniquement sur la page carte Co-Authored-By: Claude Sonnet 4.6 --- app/Http/Controllers/CarteController.php | 56 ++++++ app/Models/Lieu.php | 11 ++ resources/views/carte/index.blade.php | 170 +++++++++++++++++++ resources/views/layouts/app.blade.php | 1 + resources/views/layouts/navigation.blade.php | 7 + routes/web.php | 3 + 6 files changed, 248 insertions(+) create mode 100644 app/Http/Controllers/CarteController.php create mode 100644 resources/views/carte/index.blade.php diff --git a/app/Http/Controllers/CarteController.php b/app/Http/Controllers/CarteController.php new file mode 100644 index 0000000..9dfbd7f --- /dev/null +++ b/app/Http/Controllers/CarteController.php @@ -0,0 +1,56 @@ +whereNotNull('longitude') + ->whereHas('sources.releves') + ->with([ + 'sources' => function ($q) { + $q->withCount('releves') + ->select('id', 'nom', 'lieu_id', 'status', 'annee_debut', 'annee_fin') + ->orderBy('nom'); + }, + ]) + ->get() + ->map(function (Lieu $lieu) { + $relevesTotal = $lieu->sources->sum('releves_count'); + return [ + 'id' => $lieu->id, + 'nom' => $lieu->nom_long ?? $lieu->nom, + 'lat' => (float) $lieu->latitude, + 'lng' => (float) $lieu->longitude, + 'sources_count' => $lieu->sources->count(), + 'releves_count' => $relevesTotal, + 'sources' => $lieu->sources->map(fn ($s) => [ + 'id' => $s->id, + 'nom' => $s->nom, + 'releves_count' => $s->releves_count, + 'status' => $s->status->label(), + 'status_value' => $s->status->value, + 'annees' => $s->annee_debut + ? ($s->annee_debut === $s->annee_fin || ! $s->annee_fin + ? (string) $s->annee_debut + : "{$s->annee_debut}–{$s->annee_fin}") + : null, + ]), + ]; + }); + + return response()->json($lieux); + } +} diff --git a/app/Models/Lieu.php b/app/Models/Lieu.php index e8bca2a..4dd3ade 100644 --- a/app/Models/Lieu.php +++ b/app/Models/Lieu.php @@ -5,6 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; class Lieu extends Model { @@ -32,6 +33,16 @@ class Lieu extends Model return $this->hasMany(Section::class); } + public function sources(): HasMany + { + return $this->hasMany(Source::class); + } + + public function releves(): HasManyThrough + { + return $this->hasManyThrough(Releve::class, Source::class); + } + public function calculerNomLong(): string { $noms = [$this->nom]; diff --git a/resources/views/carte/index.blade.php b/resources/views/carte/index.blade.php new file mode 100644 index 0000000..db2dd6e --- /dev/null +++ b/resources/views/carte/index.blade.php @@ -0,0 +1,170 @@ + + +
+

Carte des relevés

+

+
+
+ + @push('head') + {{-- Leaflet CSS --}} + + + @endpush + + {{-- La carte occupe toute la hauteur disponible --}} +
+ + @push('head') + {{-- Leaflet JS (chargé en fin de head pour ne pas bloquer le rendu) --}} + + + + @endpush + +
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index b323ff8..635dabf 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -31,6 +31,7 @@ @vite(['resources/css/app.css', 'resources/js/app.js']) + @stack('head')
diff --git a/resources/views/layouts/navigation.blade.php b/resources/views/layouts/navigation.blade.php index 41db80f..7a5fc46 100644 --- a/resources/views/layouts/navigation.blade.php +++ b/resources/views/layouts/navigation.blade.php @@ -33,6 +33,10 @@ Recherche + + Carte + + @if(auth()->user()->isSectionManager())