import { Controller } from "@hotwired/stimulus" import L, { circleMarker } from "leaflet" // Connects to data-controller="maps" export default class extends Controller { static targets = ["container"] connect() { console.log("Map controller connected") var markers = JSON.parse(this.element.dataset.coordinates) var center = markers[markers.length - 1] || JSON.parse(this.element.dataset.center) var center = (center === undefined) ? [52.516667, 13.383333] : center; var map = L.map(this.containerTarget, { layers: [this.osmMapLayer(), this.osmHotMapLayer()] }).setView([center[0], center[1]], 14); var markersArray = this.markersArray(markers) var markersLayer = L.layerGroup(markersArray) var polylineCoordinates = markers.map(element => element.slice(0, 2)); var polylineLayer = L.polyline(polylineCoordinates, { color: 'blue', opacity: 0.6, weight: 3 }) var controlsLayer = { "Points": markersLayer, "Polyline": polylineLayer } var layerControl = L.control.layers(this.baseMaps(), controlsLayer).addTo(map); this.addTileLayer(map); // markersLayer.addTo(map); polylineLayer.addTo(map); this.addLastMarker(map, markers); } disconnect() { this.map.remove(); } osmMapLayer() { return L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }) } osmHotMapLayer() { return L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap contributors, Tiles style by Humanitarian OpenStreetMap Team hosted by OpenStreetMap France' }) } baseMaps() { return { "OpenStreetMap": this.osmMapLayer(), "OpenStreetMap.HOT": this.osmHotMapLayer() } } controlsLayer() { return { "Points": this.markersLayer, "Polyline": this.polylineLayer } } markersArray(markers_data) { var markersArray = [] for (var i = 0; i < markers_data.length; i++) { var lat = markers_data[i][0]; var lon = markers_data[i][1]; var popupContent = this.popupContent(markers_data[i]); var circleMarker = L.circleMarker([lat, lon], {radius: 4}) markersArray.push(circleMarker.bindPopup(popupContent).openPopup()) } return markersArray } popupContent(marker) { return ` Timestamp: ${this.formatDate(marker[4])}
Latitude: ${marker[0]}
Longitude: ${marker[1]}
Altitude: ${marker[3]}m
Velocity: ${marker[5]}km/h
Battery: ${marker[2]}% `; } formatDate(timestamp) { let date = new Date(timestamp * 1000); // Multiply by 1000 because JavaScript works with milliseconds let timezone = this.element.dataset.timezone; return date.toLocaleString('en-GB', { timeZone: timezone }); } addTileLayer(map) { L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' }).addTo(map); } addMarkers(map, markers_data) { var markers = [] for (var i = 0; i < markers_data.length; i++) { var lat = markers_data[i][0]; var lon = markers_data[i][1]; var popupContent = this.popupContent(markers_data[i]); var circleMarker = L.circleMarker([lat, lon], {radius: 4}) markers.push(circleMarker.bindPopup(popupContent).openPopup()) } L.layerGroup(markers).addTo(map); } addPolyline(map, markers) { var coordinates = markers.map(element => element.slice(0, 2)); L.polyline(coordinates).addTo(map); } addLastMarker(map, markers) { if (markers.length > 0) { var lastMarker = markers[markers.length - 1].slice(0, 2) L.marker(lastMarker).addTo(map); } } }