// components/MapComponent.js import React, { useEffect, useRef, useState } from "react"; import L from "leaflet"; import "leaflet/dist/leaflet.css"; import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; import "leaflet-contextmenu"; import * as config from "../config/config.js"; const MapComponent = ({ locations, onLocationUpdate }) => { const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte const [map, setMap] = useState(null); // Zustand der Karteninstanz const [online, setOnline] = useState(navigator.onLine); // Zustand der Internetverbindung const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = useState( [] ); // Zustand für statische Daten const [dataStatus, setDataStatus] = useState([]); // Zustand für Statusdaten const [dataIcons, setDataIcons] = useState([]); // Zustand für Icons const [dataSystem, setDataSystem] = useState([]); // Zustand für Systemdaten // Konstanten für die URLs const mapGisStationsStaticDistrictUrl = config.mapGisStationsStaticDistrictUrl; const mapDataStatusUrl = config.mapDataStatusUrl; const mapDataIconUrl = config.mapDataIconUrl; const mapDataSystemUrl = config.mapDataSystemUrl; console.log("GisStationsStaticDistrict 1 :", GisStationsStaticDistrict); console.log("map:", map); //------------------------------------------ // API-Daten laden für GisStationsStaticDistrict //http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStaticDistrict?idMap=10&idUser=485 useEffect(() => { const fetchData = async () => { try { console.log("Datenabruf gestartet..."); const response = await fetch(config.mapGisStationsStaticDistrictUrl); const jsonResponse = await response.json(); // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält if (jsonResponse && jsonResponse.Points) { console.log( "GisStationsStaticDistrict geladen:", jsonResponse.Points ); setGisStationsStaticDistrict(jsonResponse.Points); // Direkter Zugriff auf 'Points' } else { console.error( 'Erwartete Daten im "Points"-Array nicht gefunden', jsonResponse ); setGisStationsStaticDistrict([]); } } catch (error) { console.error("Fehler beim Laden der Daten: ", error); setGisStationsStaticDistrict([]); } }; fetchData(); }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen //------------------------------------------ useEffect(() => { // Prüfen der Internetverbindung beim Start console.log("Prüfen der Internetverbindung..."); checkInternet(); // Asynchrones Laden der Kartendaten beim Initialisieren der Komponente const fetchData = async () => { try { console.log("Datenabruf gestartet..."); const responses = await Promise.all([ fetch(config.mapGisStationsStaticDistrictUrl).then((res) => res.json() ), fetch(config.mapDataStatusUrl).then((res) => res.json()), fetch(config.mapDataIconUrl).then((res) => res.json()), fetch(config.mapDataSystemUrl).then((res) => res.json()), ]); console.log("Daten erfolgreich geladen."); setGisStationsStaticDistrict(responses[0].Points); setDataStatus(responses[1].Statis); setDataIcons(responses[2].List); setDataSystem( responses[3].Systems.filter((system) => system.Allow === 1) ); } catch (error) { console.error("Fehler beim Laden der Daten: ", error); } }; fetchData(); }, []); // Leeres Abhängigkeitsarray, um nur beim ersten Mount zu laden const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png"; const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; // Create map layers const TALAS = new L.layerGroup(); const ECI = new L.layerGroup(); const ULAF = new L.layerGroup(); const GSMModem = new L.layerGroup(); const CiscoRouter = new L.layerGroup(); const WAGO = new L.layerGroup(); const Siemens = new L.layerGroup(); const OTDR = new L.layerGroup(); const WDM = new L.layerGroup(); const GMA = new L.layerGroup(); const Sonstige = new L.layerGroup(); const TALASICL = new L.layerGroup(); let initialMap = []; useEffect(() => { console.log("Server URL from config:", config.serverURL); if (typeof window !== "undefined") { console.log("Window height from config:", config.windowHeight); } }, []); // 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)); }; // Initialisiere die Karte useEffect(() => { if (mapRef.current && !map) { initialMap = L.map(mapRef.current, { center: [53.111111, 8.4625], zoom: 10, layers: [ TALAS, ECI, ULAF, GSMModem, CiscoRouter, WAGO, Siemens, OTDR, WDM, GMA, Sonstige, TALASICL, ], zoomControl: false, // Deaktiviere die Standard-Zoomsteuerung contextmenu: true, 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, }, { text: "Koordinaten", icon: "img/screen_same.png", callback: lata, }, "-", // Divider { text: "Reinzoomen", callback: zoomIn }, { text: "Rauszoomen", callback: zoomOut }, { text: "Hier zentrieren", callback: centerHere }, ], }); L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { attribution: '© OpenStreetMap contributors', }).addTo(initialMap); setMap(initialMap); } }, [mapRef, map]); // 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 } } //---------------------------------- //-----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 lata = (e) => { alert("Breitengrad: " + e.latlng.lat); }; const zoomIn = (e) => { initialMap.flyTo(e.latlng, 12); }; const zoomOut = (e) => { fly(); }; const centerHere = (e) => { initialMap.panTo(e.latlng); }; 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------------ // Ensure this function is only called when map is initialized and available const showAddStationPopup = (e) => { if (!initialMap) { console.log("Map is not initialized."); return; } const popupContent = L.DomUtil.create("div"); popupContent.innerHTML = `
`; L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(initialMap); // Attach event listener here L.DomEvent.on(popupContent, "submit", handleSubmit); }; /* const handleSubmit = (event) => { event.preventDefault(); const form = event.target; const data = { name: form.name.value, type: form.type.value, latitude: form.lat.value, longitude: form.lng.value, }; onAddLocation(name, type, lat, lng); console.log("Name: ", name, "Type: ", type, "Lat: ", lat, "Lng: ", lng); map.closePopup(); }; */ // Funktion zum Hinzufügen eines neuen Standorts async function handleSubmit(event) { event.preventDefault(); const form = event.target; const data = { name: form.name.value, type: form.type.value, latitude: form.lat.value, longitude: form.lng.value, }; try { const response = await fetch("/api/addLocation", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); const result = await response.json(); if (response.ok) { console.log("Standort hinzugefügt:", result); alert("Standort erfolgreich hinzugefügt!"); form.reset(); // Formular zurücksetzen // Hier könntest du weitere Aktionen durchführen, wie das Schließen des Popups oder das Aktualisieren der Marker auf der Karte } else { throw new Error( result.error || "Ein unbekannter Fehler ist aufgetreten." ); } } catch (error) { console.error("Fehler beim Hinzufügen des Standorts:", error); alert(error.message); } } function fly(stationValue) { var x = 51.41321407879154; var y = 7.739617925303934; var zoom = 7; /* for (var i = 0; i < GisStationsStaticDistrictlength; i++) { var gisStatics = GisStationsStaticDistrict[i]; if (stationValue === gisStatics.Area_Name) { //console.log(gisStatics.X+","+gisStatics.Y); x = gisStatics.X; y = gisStatics.Y; } } if (y === 7.739617925303934) { zoom = 8; } */ initialMap.flyTo([x, y], zoom); /* var popup = new L.Popup(); oms.addListener("click", function (marker) { popup.setContent(marker.desc); popup.setLatLng(marker.getLatLng()); map.openPopup(popup); }); for (var i = 0; i < window.mapData.length; i++) { var datum = window.mapData[i]; var loc = new L.LatLng(datum.lat, datum.lon); var marker = new L.Marker(loc); marker.desc = datum.d; map.addLayer(marker); //oms.addMarker(marker); // <-- here } */ } return (
); }; export default MapComponent;