import { useEffect, useRef, useState } from "react"; import L from "leaflet"; import "leaflet/dist/leaflet.css"; import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; import "leaflet-contextmenu"; const MapComponent = ({ locations, onAddLocation, onLocationUpdate, dataStatic, mapData }) => { const [map, setMap] = useState(null); const mapRef = useRef(null); const [online, setOnline] = useState(navigator.onLine); const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png"; const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; // Funktionen zur Überwachung der Internetverbindung const checkInternet = () => { console.log("Checking internet connectivity..."); fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) .then(response => setOnline(response.ok)) .catch(() => setOnline(false)); }; // Initialize map useEffect(() => { if (mapRef.current && !map) { console.log("Initializing map..."); const initializedMap = L.map(mapRef.current, { center: [53.111111, 8.4625], zoom: 10, contextmenu: true, contextmenuWidth: 140, contextmenuItems: [ { text: "Station hinzufügen", callback: showAddStationPopup }, { text: "Station öffnen (Tab)", icon: "img/screen_new.png", callback: newLink }, { text: "Station öffnen", icon: "img/screen_same.png", callback: sameLink }, "-", // Divider { text: "Reinzoomen", callback: (e) => zoomIn(e, initializedMap) }, { text: "Rauszoomen", callback: (e) => zoomOut(e, initializedMap) }, { text: "Hier zentrieren", callback: (e) => centerMap(e, initializedMap) }, "-", // Divider { text: "Koordinaten", icon: "img/not_listed_location.png", callback: showCoordinates }, { text: "Get Data to Console", icon: "img/not_listed_location.png", callback: showData } ] }); // Adding initial tile layer const tileLayer = L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { attribution: '© OpenStreetMap contributors', minZoom: 7, maxZoom: 19 }); tileLayer.addTo(initializedMap); setMap(initializedMap); // Cleanup function return () => { initializedMap.remove(); }; } }, [mapRef, online]); // React only on online changes for initialization // Handle online/offline status useEffect(() => { window.addEventListener("online", checkInternet); window.addEventListener("offline", checkInternet); return () => { window.removeEventListener("online", checkInternet); window.removeEventListener("offline", checkInternet); }; }, []); // Update map layers based on online status useEffect(() => { if (map) { const newLayer = L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { minZoom: 7, maxZoom: online ? 19 : 14, attribution: 'Map data © OpenStreetMap contributors' }); map.eachLayer(layer => { if (layer instanceof L.TileLayer) { map.removeLayer(layer); } }); newLayer.addTo(map); } }, [online, map]); // Marker handling useEffect(() => { // Remove old markers if (map) { map.eachLayer(layer => { if (layer instanceof L.Marker) { map.removeLayer(layer); } }); // Add new markers locations.forEach(location => { const { latitude, longitude } = parsePoint(location.position); const marker = L.marker([latitude, longitude], { icon: L.icon({ iconUrl: "/location.svg", iconSize: [34, 34], iconAnchor: [17, 34], popupAnchor: [0, -34] }), draggable: true, id: location.idPoi }); marker.bindPopup(`${location.description || "Unbekannt"}
Type: ${location.idPoiTyp || "N/A"}
Lat: ${latitude.toFixed(5)}, Lng: ${longitude.toFixed(5)}`); marker.on("dragend", function (e) { const newLat = e.target.getLatLng().lat; const newLng = e.target.getLatLng().lng; const markerId = e.target.options.id; updateLocationInDatabase(markerId, newLat, newLng).then(() => { onLocationUpdate(markerId, newLat, newLng); }); }); marker.addTo(map); }); } }, [map, locations, onLocationUpdate]); //------------------------------------------ function parsePoint(pointString) { const match = pointString.match( /POINT\s*\((\d+(\.\d+)?)\s+(\d+(\.\d+)?)\)/ ); if (match) { return { longitude: parseFloat(match[1]), latitude: parseFloat(match[3]), // Achtung: Index 3 für die zweite Koordinate, wegen der Gruppe (\.\d+)? }; } else { // Handle the error or return a default/fallback value console.error("Invalid POINT format:", pointString); return null; // Oder eine sinnvolle Standardantwort } } //---------------------------------- const centerMap = (e) => { if (!map) { console.error("Die Karte wurde noch nicht initialisiert."); return; } if (!e || !e.latlng) { console.error("Fehlerhafte Event-Daten: ", e); return; } console.log("Zentrierung auf: ", e.latlng); map.panTo(e.latlng); }; //-----Kontextmenu---------------- const newLink = (e) => { try { if (!e.relatedTarget || !e.relatedTarget.options) { throw new Error("relatedTarget or options not defined"); } alert("Neues Fenster: " + e.relatedTarget.options.test); window .open(`../devices/${e.relatedTarget.options.test}`, "_blank") .focus(); } catch (error) { console.error("Failed in newLink function:", error); } }; const sameLink = (e) => { alert(e.relatedTarget.options.test); window .open("../devices/" + e.relatedTarget.options.test, "_parent") .focus(); }; const zoomIn = (e) => { if (!map) { console.error("Karte ist noch nicht initialisiert."); return; } map.flyTo(e.latlng, map.getZoom() + 1); }; const zoomOut = (e) => { if (!map) { console.error("Karte ist noch nicht initialisiert."); return; } // Annahme: Du willst beim Rauszoomen die aktuelle Position halten // und nur den Zoom-Level ändern. Hier reduzieren wir den Zoom-Level um 1. const currentZoom = map.getZoom(); map.flyTo(e.latlng, map.getZoom() - 1); }; const showCoordinates = (e) => { alert("Breitengrad: " + e.latlng.lat + "\nLängengrad: " + e.latlng.lng); }; const showData = (e) => { console.log(e); }; const showTalas = (e) => { map.addLayer(TALAS); loadData(); }; const hideTalas = (e) => { map.removeLayer(TALAS); loadData(); }; const showGSM = (e) => { map.addLayer(GMA); loadData(); }; const hideGSM = (e) => { map.removeLayer(GMA); loadData(); }; //-----Kontextmenu----ende------------ const showAddStationPopup = (e, map) => { const popupContent = `
`; L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(map); // Verzögerung hinzufügen, um sicherzustellen, dass das Formular im DOM verfügbar ist setTimeout(() => { const form = document.getElementById("addStationForm"); if (form) { form.addEventListener("submit", async (event) => { event.preventDefault(); const name = event.target.name.value; const type = event.target.type.value; const lat = event.target.lat.value; const lng = event.target.lng.value; // Hier wird `onAddLocation` mit den Werten aufgerufen, die aus dem Formular gesammelt wurden await onAddLocation(name, type, lat, lng); map.closePopup(); }); } }, 10); }; return
; }; export default MapComponent;