From 908478caf27ed365cab920830ade272d808b0ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A4r=20Thernstr=C3=B6m?= Date: Sat, 11 May 2024 15:21:48 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=BA=EF=B8=8F=20B=C3=B6rjar=20bli=20fii?= =?UTF-8?q?in?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/ApiController.php | 56 ++++++++--- .../views/components/events-map.blade.php | 98 +++++++++++++------ resources/views/design.blade.php | 5 +- routes/api.php | 1 + 4 files changed, 112 insertions(+), 48 deletions(-) diff --git a/app/Http/Controllers/ApiController.php b/app/Http/Controllers/ApiController.php index 9130d9fa..e0c7660f 100644 --- a/app/Http/Controllers/ApiController.php +++ b/app/Http/Controllers/ApiController.php @@ -13,10 +13,8 @@ /** * Controller för plats, översikt och detalj */ -class ApiController extends Controller -{ - public function eventsNearby(Request $request, Response $response) - { +class ApiController extends Controller { + public function eventsNearby(Request $request, Response $response) { // The number of events to get. Max 50. Default 10. $lat = (float) $request->input("lat"); $lng = (float) $request->input("lng"); @@ -31,7 +29,7 @@ public function eventsNearby(Request $request, Response $response) $numTries = 0; $maxNumTries = 20; $nearbyCount = 25; - + $nearbyInKm = $request->input('distance'); $allowNearbyExpand = false; if (!is_numeric($nearbyInKm)) { @@ -101,8 +99,7 @@ public function eventsNearby(Request $request, Response $response) return response()->json($json)->withCallback($request->input('callback')); } - public function events(Request $request, Response $response) - { + public function events(Request $request, Response $response) { // The number of events to get. Max 50. Default 10. $limit = (int) $request->input("limit", 10); @@ -228,8 +225,7 @@ public function events(Request $request, Response $response) return response()->json($json)->withCallback($callback); } - public function event(Request $request, Response $response, $eventID) - { + public function event(Request $request, Response $response, $eventID) { $event = CrimeEvent::findOrFail($eventID); $eventArray = $event->toArray(); @@ -261,8 +257,7 @@ public function event(Request $request, Response $response, $eventID) return response()->json($json)->withCallback($request->input('callback')); } - public function areas(Request $request, Response $response) - { + public function areas(Request $request, Response $response) { $data = [ "data" => [], ]; @@ -285,8 +280,7 @@ public function areas(Request $request, Response $response) * @param Response $response [description] * @return JsonResponse */ - public function eventsInMedia(Request $request, Response $response) - { + public function eventsInMedia(Request $request, Response $response) { $limit = (int) $request->input("limit", 10); @@ -299,7 +293,7 @@ public function eventsInMedia(Request $request, Response $response) $callback = $request->input('callback'); - $events = CrimeEvent::whereHas('newsarticles', function($query) use ($media) { + $events = CrimeEvent::whereHas('newsarticles', function ($query) use ($media) { $query->where('url', 'like', "%{$media}%"); })->with('newsarticles')->orderBy("created_at", "desc")->paginate($limit); @@ -347,7 +341,7 @@ public function eventsInMedia(Request $request, Response $response) // Keep only some keys from the articles array. $newsArticles = $item->newsarticles->toArray(); $keysToKeep = array_flip(['title', 'shortdesc', 'url']); - $newsArticles = array_map(function($itemArticle) use ($keysToKeep) { + $newsArticles = array_map(function ($itemArticle) use ($keysToKeep) { return array_intersect_key($itemArticle, $keysToKeep); }, $newsArticles); @@ -392,7 +386,7 @@ public function eventsInMedia(Request $request, Response $response) public function mostViewedRecently(Request $request, Response $response) { $events = Helper::getMostViewedEventsRecently($request->input('minutes', 10), $request->input('limit', 10)); - $events = $events->map(function($data) { + $events = $events->map(function ($data) { $item = $data->crimeEvent; return [ @@ -431,4 +425,34 @@ public function mostViewedRecently(Request $request, Response $response) { return response()->json($json)->withCallback($request->input('callback')); } + /** + * Hämta data för eventsMap-komponenten. + */ + public function eventsMap() { + + $events = CrimeEvent::orderBy("created_at", "desc")->limit(300)->get(); + + $json = [ + "data" => [], + ]; + + // create array with data is a format more suited for app and web + foreach ($events as $item) { + $event = [ + "id" => $item->id, + 'time' => $item->getParsedDateInFormat('%H:%M'), + 'headline' => $item->getHeadline(), + "type" => $item->parsed_title, + "lat" => (float) $item->location_lat, + "lng" => (float) $item->location_lng, + "image" => $item->getStaticImageSrc(320, 320, 2), + "permalink" => $item->getPermalink(true), + ]; + + $json["data"][] = $event; + } + + // return json or jsonp if ?callback is set + return $json; + } } diff --git a/resources/views/components/events-map.blade.php b/resources/views/components/events-map.blade.php index 30e502ad..d8e5626c 100644 --- a/resources/views/components/events-map.blade.php +++ b/resources/views/components/events-map.blade.php @@ -23,7 +23,7 @@ // Invalidate size after css anim has finished. setTimeout(() => { map.invalidateSize({ - pan: false + pan: true }); }, 250); }); @@ -40,8 +40,20 @@ return new L.Control.Watermark(opts); } + var markerIconFar = L.divIcon({ + className: 'EventsMap-marker-icon EventsMap-marker-icon--far', + }); + + var markerIconNear = L.divIcon({ + className: 'EventsMap-marker-icon EventsMap-marker-icon--near', + }); + class EventsMap { - mapContainer = null; + map; + mapContainer; + zoom = { + default: 4, + }; constructor(mapContainer) { this.mapContainer = mapContainer; @@ -49,15 +61,38 @@ class EventsMap { this.initMap(); } + async loadMarkers() { + console.log('EventsMap.loadMarkers:', this); + + const response = await fetch('/api/eventsMap'); + const data = await response.json(); + const events = data.data + console.log('EventsMap.loadMarkers data:', events); + + events.forEach(event => { + L.marker([event.lat, event.lng]) + .setIcon(markerIconFar) + .addTo(this.map) + .bindPopup(`${event.time} ${event.headline}`); + }); + } + initMap() { console.log('EventsMap.initMap:', this.mapContainer); // Init in Jönköping - let map = L.map(this.mapContainer).setView([59.1, 14.5], 6); + let map = L.map(this.mapContainer); + this.map = map; window.map = map; console.log('window.map now available', window.map); + map.on('load', () => { + this.loadMarkers(); + }); + + map.setView([62, 15.5], this.zoom.default); + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OSM' }).addTo(map); @@ -65,37 +100,14 @@ class EventsMap { L.control.watermark({ position: 'topright' }).addTo(map); - - // map.on("click", function(evt) { - // console.log("click expand", evt); - // evt.stopPropagation(); - // map.getContainer().classList.toggle('is-expanded'); - // map.invalidateSize(); - // }); - - - // L.marker([51.5, -0.09]).addTo(map) - // .bindPopup('A pretty CSS3 popup.
Easily customizable.') - // .openPopup(); } } document.addEventListener('DOMContentLoaded', function() { let mapContainers = document.querySelectorAll('.EventsMap'); mapContainers.forEach(element => { - console.log('element:', element); new EventsMap(element); }); - - // var map = L.map('EventsMap').setView([51.505, -0.09], 13); - - // L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - // attribution: '© OpenStreetMap' - // }).addTo(map); - - // L.marker([51.5, -0.09]).addTo(map) - // .bindPopup('A pretty CSS3 popup.
Easily customizable.') - // .openPopup(); }); @endpush @@ -118,14 +130,40 @@ class EventsMap { padding: 2px; cursor: pointer; } + .EventsMap-control-expand img { display: block; } + + .EventsMap .leaflet-marker-icon, + .EventsMap .leaflet-marker-shadow { + animation: fadein .75s; + } + + .EventsMap .leaflet-popup { + max-width: 50vw; + } + + .EventsMap-marker-icon { + --icon-size: 10px; + background-color: var(--color-red); + border-radius: 50%; + border: 1px solid rgba(255, 255, 255, .25); + width: var(--icon-size); + height: var(--icon-size); + } + + @keyframes fadein { + from { + opacity: 0; + } + + to { + opacity: 1; + } + } @endpush @endonce -
-

Karta.

-
Laddar karta...
-
+
Laddar karta...
diff --git a/resources/views/design.blade.php b/resources/views/design.blade.php index 4e3f81fd..115cf686 100644 --- a/resources/views/design.blade.php +++ b/resources/views/design.blade.php @@ -15,11 +15,12 @@ - - + + +

En huvudrubrik av storlek h1. Lite överdrivet lång kanske men vi måste ju testa radbrytningar och så vidare

diff --git a/routes/api.php b/routes/api.php index 3fee7821..5f88b42c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -25,3 +25,4 @@ Route::get('/events', [ApiController::class, 'events']); Route::get('/eventsInMedia', [ApiController::class, 'eventsInMedia']); Route::get('/mostViewedRecently', [ApiController::class, 'mostViewedRecently']); +Route::get('/eventsMap', [ApiController::class, 'eventsMap']);