mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
153 lines
5.2 KiB
JavaScript
153 lines
5.2 KiB
JavaScript
import { Controller } from "@hotwired/stimulus"
|
|
import L from "leaflet"
|
|
import { osmMapLayer } from "../maps/layers"
|
|
import { createPopupContent } from "../maps/popups"
|
|
import { osmHotMapLayer } from "../maps/layers"
|
|
import { OPNVMapLayer } from "../maps/layers"
|
|
import { openTopoMapLayer } from "../maps/layers"
|
|
import { cyclOsmMapLayer } from "../maps/layers"
|
|
import { esriWorldStreetMapLayer } from "../maps/layers"
|
|
import { esriWorldTopoMapLayer } from "../maps/layers"
|
|
import { esriWorldImageryMapLayer } from "../maps/layers"
|
|
import { esriWorldGrayCanvasMapLayer } from "../maps/layers"
|
|
import { fetchAndDisplayPhotos } from '../maps/helpers';
|
|
|
|
export default class extends Controller {
|
|
static targets = ["container"]
|
|
|
|
connect() {
|
|
this.coordinates = JSON.parse(this.element.dataset.coordinates)
|
|
this.apiKey = this.element.dataset.api_key
|
|
this.userSettings = JSON.parse(this.element.dataset.user_settings)
|
|
this.timezone = this.element.dataset.timezone
|
|
this.distanceUnit = this.element.dataset.distance_unit
|
|
|
|
// Initialize layer groups
|
|
this.markersLayer = L.layerGroup()
|
|
this.polylinesLayer = L.layerGroup()
|
|
this.photoMarkers = L.layerGroup()
|
|
|
|
const center = [this.coordinates[0][0], this.coordinates[0][1]]
|
|
|
|
// Initialize map
|
|
this.map = L.map(this.containerTarget).setView(center, 14)
|
|
|
|
// Add base map layer
|
|
osmMapLayer(this.map, "OpenStreetMap")
|
|
|
|
// Add scale control to bottom right
|
|
L.control.scale({
|
|
position: 'bottomright',
|
|
imperial: this.distanceUnit === 'mi',
|
|
metric: this.distanceUnit === 'km',
|
|
maxWidth: 120
|
|
}).addTo(this.map)
|
|
|
|
const overlayMaps = {
|
|
"Points": this.markersLayer,
|
|
"Route": this.polylinesLayer,
|
|
"Photos": this.photoMarkers
|
|
}
|
|
|
|
// Add layer control
|
|
L.control.layers(this.baseMaps(), overlayMaps).addTo(this.map)
|
|
|
|
// Add event listener for layer changes
|
|
this.map.on('overlayadd', (e) => {
|
|
if (e.name === 'Photos' && this.coordinates?.length > 0) {
|
|
const firstCoord = this.coordinates[0];
|
|
const lastCoord = this.coordinates[this.coordinates.length - 1];
|
|
|
|
// Convert Unix timestamp to a Date object
|
|
const startDate = new Date(firstCoord[4] * 1000).toISOString().split('T')[0];
|
|
const endDate = new Date(lastCoord[4] * 1000).toISOString().split('T')[0];
|
|
|
|
fetchAndDisplayPhotos({
|
|
map: this.map,
|
|
photoMarkers: this.photoMarkers,
|
|
apiKey: this.apiKey,
|
|
startDate: startDate,
|
|
endDate: endDate,
|
|
userSettings: this.userSettings
|
|
});
|
|
}
|
|
});
|
|
|
|
// Add markers and route
|
|
if (this.coordinates?.length > 0) {
|
|
this.addMarkers()
|
|
this.addPolyline()
|
|
this.fitMapToBounds()
|
|
}
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.map) {
|
|
this.map.remove()
|
|
}
|
|
}
|
|
|
|
baseMaps() {
|
|
let selectedLayerName = this.userSettings.preferred_map_layer || "OpenStreetMap";
|
|
|
|
return {
|
|
OpenStreetMap: osmMapLayer(this.map, selectedLayerName),
|
|
"OpenStreetMap.HOT": osmHotMapLayer(this.map, selectedLayerName),
|
|
OPNV: OPNVMapLayer(this.map, selectedLayerName),
|
|
openTopo: openTopoMapLayer(this.map, selectedLayerName),
|
|
cyclOsm: cyclOsmMapLayer(this.map, selectedLayerName),
|
|
esriWorldStreet: esriWorldStreetMapLayer(this.map, selectedLayerName),
|
|
esriWorldTopo: esriWorldTopoMapLayer(this.map, selectedLayerName),
|
|
esriWorldImagery: esriWorldImageryMapLayer(this.map, selectedLayerName),
|
|
esriWorldGrayCanvas: esriWorldGrayCanvasMapLayer(this.map, selectedLayerName)
|
|
};
|
|
}
|
|
|
|
addMarkers() {
|
|
this.coordinates.forEach(coord => {
|
|
const marker = L.circleMarker([coord[0], coord[1]], {radius: 4})
|
|
|
|
const popupContent = createPopupContent(coord, this.timezone, this.distanceUnit)
|
|
marker.bindPopup(popupContent)
|
|
|
|
// Add to markers layer instead of directly to map
|
|
this.markersLayer.addTo(this.map)
|
|
marker.addTo(this.markersLayer)
|
|
})
|
|
}
|
|
|
|
addPolyline() {
|
|
const points = this.coordinates.map(coord => [coord[0], coord[1]])
|
|
const polyline = L.polyline(points, {
|
|
color: 'blue',
|
|
weight: 3,
|
|
opacity: 0.6
|
|
})
|
|
// Add to polylines layer instead of directly to map
|
|
this.polylinesLayer.addTo(this.map)
|
|
polyline.addTo(this.polylinesLayer)
|
|
}
|
|
|
|
fitMapToBounds() {
|
|
const bounds = L.latLngBounds(
|
|
this.coordinates.map(coord => [coord[0], coord[1]])
|
|
)
|
|
this.map.fitBounds(bounds, { padding: [50, 50] })
|
|
}
|
|
|
|
baseMaps() {
|
|
let selectedLayerName = this.userSettings.preferred_map_layer || "OpenStreetMap";
|
|
|
|
return {
|
|
OpenStreetMap: osmMapLayer(this.map, selectedLayerName),
|
|
"OpenStreetMap.HOT": osmHotMapLayer(this.map, selectedLayerName),
|
|
OPNV: OPNVMapLayer(this.map, selectedLayerName),
|
|
openTopo: openTopoMapLayer(this.map, selectedLayerName),
|
|
cyclOsm: cyclOsmMapLayer(this.map, selectedLayerName),
|
|
esriWorldStreet: esriWorldStreetMapLayer(this.map, selectedLayerName),
|
|
esriWorldTopo: esriWorldTopoMapLayer(this.map, selectedLayerName),
|
|
esriWorldImagery: esriWorldImageryMapLayer(this.map, selectedLayerName),
|
|
esriWorldGrayCanvas: esriWorldGrayCanvasMapLayer(this.map, selectedLayerName)
|
|
};
|
|
}
|
|
}
|