// components/MapComponent.js import React, { useEffect, useRef, useState, useCallback } 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"; import "leaflet.smooth_marker_bouncing"; import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; import DataSheet from "./DataSheet.js"; import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import AddPoiModalWindow from "./pois/AddPoiModalWindow.js"; import { InformationCircleIcon } from "@heroicons/react/20/solid"; import PoiUpdateModal from "./pois/PoiUpdateModal.js"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import plusRoundIcon from "./PlusRoundIcon.js"; import { createAndSetDevices } from "../utils/createAndSetDevices.js"; import { restoreMapSettings, checkOverlappingMarkers } from "../utils/mapUtils.js"; import { fetchPoiData, fetchUserRights } from "../services/apiService.js"; import { APP_VERSION } from "../config/appVersion"; import * as layers from "../config/layers.js"; import { initializeMap } from "../utils/initializeMap.js"; import { addItemsToMapContextMenu } from "./useMapContextMenu.js"; import useGmaMarkersLayer from "../hooks/layers/useGmaMarkersLayer.js"; // Import the custom hook import useSmsfunkmodemMarkersLayer from "../hooks/layers/useSmsfunkmodemMarkersLayer.js"; import useBereicheMarkersLayer from "../hooks/layers/useBereicheMarkersLayer.js"; import { fetchGisStationsStaticDistrict, fetchGisStationsStatusDistrict, fetchGisStationsMeasurements, fetchGisSystemStatic } from "../services/fetchData.js"; import { setupPolylines } from "../utils/setupPolylines.js"; import { setupPOIs } from "../utils/setupPOIs.js"; import VersionInfoModal from "./VersionInfoModal.js"; import useDrawLines from "../hooks/layers/useDrawLines"; import useFetchPoiData from "../hooks/useFetchPoiData"; import usePoiTypData from "../hooks/usePoiTypData"; import useLayerVisibility from "../hooks/useLayerVisibility"; import useLineData from "../hooks/useLineData.js"; //import { useCreateAndSetDevices } from "../hooks/useCreateAndSetDevices"; import { useMapComponentState } from "../hooks/useMapComponentState"; import { disablePolylineEvents, enablePolylineEvents } from "../utils/setupPolylines"; import { updateLocation } from "../utils/updateBereichUtil"; import { initGeocoderFeature } from "../components/features/GeocoderFeature"; //-------------------------------------------- import { currentPoiState } from "../redux/slices/currentPoiSlice.js"; import { selectGisStationsStaticDistrict, setGisStationsStaticDistrict } from "../redux/slices/gisStationsStaticDistrictSlice"; import { mapIdState, userIdState } from "../redux/slices/urlParameterSlice.js"; import { poiLayerVisibleState } from "../redux/slices/poiLayerVisibleSlice.js"; import { selectedPoiState } from "../redux/slices/selectedPoiSlice.js"; import { poiReadFromDbTriggerAtom } from "../redux/slices/poiReadFromDbTriggerSlice"; import { gisStationsStaticDistrictState } from "../redux/slices/gisStationsStaticDistrictSlice"; import { gisSystemStaticState } from "../redux/slices/gisSystemStaticSlice"; import { mapLayersState } from "../redux/slices/mapLayersSlice"; import { selectedAreaState } from "../redux/slices/selectedAreaSlice"; import { zoomTriggerState } from "../redux/slices/zoomTriggerSlice.js"; import { polylineEventsDisabledState } from "../redux/slices/polylineEventsDisabledSlice"; import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleSlice"; //-------------------------------------------- import { useSelector, useDispatch } from "react-redux"; import { selectCurrentPoi, setCurrentPoi, clearCurrentPoi } from "../redux/slices/currentPoiSlice"; const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const dispatch = useDispatch(); const currentPoi = useSelector(selectCurrentPoi); //const setCurrentPoi = useSetRecoilState(currentPoiState); const polylineVisible = useRecoilValue(polylineLayerVisibleState); const [editMode, setEditMode] = useState(false); // editMode Zustand const { deviceName, setDeviceName } = useMapComponentState(); const { poiTypData, isPoiTypLoaded } = usePoiTypData("/api/talas_v5_DB/poiTyp/readPoiTyp"); //const [deviceName, setDeviceName] = useState(""); const [locationDeviceData, setLocationDeviceData] = useState([]); const [priorityConfig, setPriorityConfig] = useState([]); const [menuItemAdded, setMenuItemAdded] = useState(false); const poiLayerVisible = useRecoilValue(poiLayerVisibleState); const [isRightsLoaded, setIsRightsLoaded] = useState(false); const [hasRights, setHasRights] = useState(false); const [mapId, setMapId] = useRecoilState(mapIdState); const [userId, setUserId] = useRecoilState(userIdState); const [AddPoiModalWindowState, setAddPoiModalWindowState] = useState(false); const [userRights, setUserRights] = useState(null); const setSelectedPoi = useSetRecoilState(selectedPoiState); const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false); const [currentPoiData, setCurrentPoiData] = useState(null); const [showVersionInfoModal, setShowVersionInfoModal] = useState(false); const zoomTrigger = useRecoilValue(zoomTriggerState); const [gisSystemStaticLoaded, setGisSystemStaticLoaded] = useState(false); const [poiTypMap, setPoiTypMap] = useState(new Map()); const [showPopup, setShowPopup] = useState(false); const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); const poiLayerRef = useRef(null); // Referenz auf die Layer-Gruppe für Datenbank-Marker const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte const [map, setMap] = useState(null); // Zustand der Karteninstanz const [oms, setOms] = useState(null); // State für OMS-Instanz //const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = useRecoilState(gisStationsStaticDistrictState); const GisStationsStaticDistrict = useSelector(selectGisStationsStaticDistrict); const [GisStationsStatusDistrict, setGisStationsStatusDistrict] = useState([]); // Zustand für Statusdaten const [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten const [GisSystemStatic, setGisSystemStatic] = useRecoilState(gisSystemStaticState); // Zustand für Systemdaten // Konstanten für die URLs const mapGisStationsStaticDistrictUrl = config.mapGisStationsStaticDistrictUrl; const mapGisStationsStatusDistrictUrl = config.mapGisStationsStatusDistrictUrl; const mapGisStationsMeasurementsUrl = config.mapGisStationsMeasurementsUrl; const mapGisSystemStaticUrl = config.mapGisSystemStaticUrl; const webserviceGisLinesStatusUrl = config.webserviceGisLinesStatusUrl; //console.log("priorityConfig in MapComponent1: ", priorityConfig); const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 alle sind untetschiedlich Nummern const [talasMarkers, setTalasMarkers] = useState([]); const [eciMarkers, setEciMarkers] = useState([]); const [gsmModemMarkers, setGsmModemMarkers] = useState([]); const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]); const [wagoMarkers, setWagoMarkers] = useState([]); const [siemensMarkers, setSiemensMarkers] = useState([]); const [otdrMarkers, setOtdrMarkers] = useState([]); const [wdmMarkers, setWdmMarkers] = useState([]); const [messstellenMarkers, setMessstellenMarkers] = useState([]); const [talasiclMarkers, setTalasiclMarkers] = useState([]); const [dauzMarkers, setDauzMarkers] = useState([]); const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]); const [ulafMarkers, setUlafMarkers] = useState([]); const [sonstigeMarkers, setSonstigeMarkers] = useState([]); const [tkComponentsMarkers, setTkComponentsMarkers] = useState([]); //const [lteModemMarkers, setLteModemMarkers] = useState([]); const [lineStatusData, setLineStatusData] = useState([]); const [linesData, setLinesData] = useState([]); const mapLayersVisibility = useRecoilValue(mapLayersState); const selectedArea = useRecoilValue(selectedAreaState); const poiData = useFetchPoiData("/api/talas_v5_DB/pois/poi-icons"); const [linePositions, setLinePositions] = useState([]); const { lineColors, tooltipContents } = useLineData(webserviceGisLinesStatusUrl, setLineStatusData); const [polylines, setPolylines] = useState([]); const [markers, setMarkers] = useState([]); const closePopup = () => setShowPopup(false); const [newPoint, setNewPoint] = useState(null); const [newCoords, setNewCoords] = useState(null); const [tempMarker, setTempMarker] = useState(null); const [popupCoordinates, setPopupCoordinates] = useState({ lat: 52.52, lng: 13.405, }); const handleAddStation = (stationData) => { setAddPoiModalWindowState(false); closePopup(); // Schließt das Popup nach dem Hinzufügen }; const openVersionInfoModal = () => { setShowVersionInfoModal(true); }; const closeVersionInfoModal = () => { setShowVersionInfoModal(false); }; const [currentZoom, setCurrentZoom] = useState(() => { const storedZoom = localStorage.getItem("mapZoom"); return storedZoom ? parseInt(storedZoom, 10) : 12; }); const [currentCenter, setCurrentCenter] = useState(() => { const storedCenter = localStorage.getItem("mapCenter"); try { return storedCenter ? JSON.parse(storedCenter) : [53.111111, 8.4625]; } catch (e) { console.error("Error parsing stored map center:", e); return [53.111111, 8.4625]; } }); const [polylineEventsDisabled, setPolylineEventsDisabled] = useRecoilState(polylineEventsDisabledState); // Recoil State //--------------------------------------------------------------- /* useEffect(() => { fetchGisStatusStations(12, 484); // Beispielaufruf mit idMap = 10 und idUser = 484 }, []); */ useEffect(() => { const params = new URL(window.location.href).searchParams; setMapId(params.get("m")); setUserId(params.get("u")); }, [setMapId, setUserId]); /* useEffect(() => { if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded && isRightsLoaded) { //console.log("Überprüfung der Berechtigung vor addItemsToMapContextMenu: ", hasRights); addItemsToMapContextMenu(hasRights); } }, [ map, poiLayerRef, isPoiTypLoaded, menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern hasRights, // Sicherstellen, dass hasRights berücksichtigt wird isRightsLoaded, // Überprüfung, ob die Rechte geladen sind ]); */ useEffect(() => { const fetchAndSetUserRights = async () => { const rights = await fetchUserRights(); setUserRights(rights); setIsRightsLoaded(true); // Sicherstellen, dass `rights` ein Array ist, bevor `.includes()` aufgerufen wird setHasRights(localStorage.getItem("editMode") && Array.isArray(rights) && rights.includes(56)); }; fetchAndSetUserRights(); }, []); useGmaMarkersLayer( map, gmaMarkers, GisStationsMeasurements, layers.MAP_LAYERS.GMA, oms, mapLayersVisibility.GMA // Übergebe die Sichtbarkeitsbedingung als Parameter ); /* useSmsfunkmodemMarkersLayer( map, oms, GisSystemStatic, priorityConfig, mapLayersVisibility.SMSFunkmodem // Sichtbarkeitsstatus aus dem State ); */ useEffect(() => { const fetchWebServiceMap = async () => { try { // Zähler für externe API-Aufrufe in localStorage speichern let requestCount = localStorage.getItem("fetchWebServiceMap") || 0; requestCount = parseInt(requestCount, 10); const fetchOptions = { method: "GET", headers: { Connection: "close", // Keep-Alive-Header hinzufügen }, }; // Fetch GIS Stations Static District await fetchGisStationsStaticDistrict(mapGisStationsStaticDistrictUrl, dispatch, fetchOptions); requestCount++; // Zähler erhöhen localStorage.setItem("fetchWebServiceMap", requestCount); //console.log(`fetchWebServiceMap in MapComponent wurde ${requestCount} Mal aufgerufen.`); // Fetch GIS Stations Status District await fetchGisStationsStatusDistrict(mapGisStationsStatusDistrictUrl, setGisStationsStatusDistrict, fetchOptions); requestCount++; // Zähler erhöhen localStorage.setItem("fetchWebServiceMap", requestCount); //console.log(`fetchWebServiceMap in MapComponent wurde ${requestCount} Mal aufgerufen.`); // Fetch GIS Stations Measurements await fetchGisStationsMeasurements(mapGisStationsMeasurementsUrl, setGisStationsMeasurements, fetchOptions); requestCount++; // Zähler erhöhen localStorage.setItem("fetchWebServiceMap", requestCount); //console.log(`fetchWebServiceMap in MapComponent wurde ${requestCount} Mal aufgerufen.`); // Fetch GIS System Static await fetchGisSystemStatic(mapGisSystemStaticUrl, setGisSystemStatic, setGisSystemStaticLoaded, fetchOptions); requestCount++; // Zähler erhöhen localStorage.setItem("fetchWebServiceMap", requestCount); //console.log(`fetchWebServiceMap in MapComponent wurde ${requestCount} Mal aufgerufen.`); } catch (error) { console.error("Error fetching data:", error); } }; fetchWebServiceMap(); }, [dispatch, mapGisStationsStaticDistrictUrl]); //-------------------------------------------------------- useDrawLines(setLinePositions); // Linien auf die Karte zeichnen //-------------------------------------------- // POIs Popup Informationen anzeigen useEffect(() => { const fetchPoiTypData = async () => { try { const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"); const data = await response.json(); const map = new Map(); data.forEach((item) => map.set(item.idPoiTyp, item.name)); setPoiTypMap(map); } catch (error) { console.error("Fehler beim Abrufen der poiTyp-Daten-1:", error); } }; const fetchPoiData = async () => { try { const response = await fetch("/api/talas_v5_DB/pois/poi-icons"); if (!response.ok) { throw new Error("Network response was not ok"); } const data = await response.json(); } catch (error) { console.error("Fehler beim Abrufen der poiData-2:", error); } }; fetchPoiTypData(); fetchPoiData(); }, []); //-------------------------------------------- /* useEffect(() => { if (map) { const dbLayer = new L.LayerGroup().addTo(map); // Define dbLayer here return () => { dbLayer.remove(); }; } }, [map]); */ //-------------------------------------------- // POIs auf die Karte zeichnen useEffect(() => { if (map && !poiLayerRef.current) { poiLayerRef.current = new L.LayerGroup().addTo(map); } return () => { if (map && poiLayerRef.current) { map.removeLayer(poiLayerRef.current); poiLayerRef.current = new L.LayerGroup().addTo(map); } locations.forEach((location) => {}); }; //console.log("trigger in MapComponent.js:", poiReadTrigger); }, [map, locations, poiReadTrigger]); //-------------------------------------------- // POIs auf die Karte zeichnen useEffect(() => { if (poiData.length === 0) return; setupPOIs(map, locations, poiData, poiTypMap, userRights, poiLayerRef, setSelectedPoi, setLocationDeviceData, setDeviceName, setCurrentPoi, poiLayerVisible, fetchPoiData, toast, setShowPoiUpdateModal, setCurrentPoiData, deviceName); }, [map, locations, onLocationUpdate, poiReadTrigger, isPoiTypLoaded, userRights, poiLayerVisible, poiData, poiTypMap]); //--------------------------------------------- //console.log("priorityConfig in MapComponent2: ", priorityConfig); useEffect(() => { if (gisSystemStaticLoaded && map) { } }, [gisSystemStaticLoaded, map, GisSystemStatic, priorityConfig]); //useCreateAndSetDevices(1, talasMarkers, GisSystemStatic, priorityConfig); useLayerVisibility(map, talasMarkers, mapLayersVisibility, "TALAS", oms); useLayerVisibility(map, eciMarkers, mapLayersVisibility, "ECI", oms); useLayerVisibility(map, gsmModemMarkers, mapLayersVisibility, "GSMModem", oms); useLayerVisibility(map, ciscoRouterMarkers, mapLayersVisibility, "CiscoRouter", oms); //useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms); useLayerVisibility(map, wagoMarkers, mapLayersVisibility, "WAGO", oms); useLayerVisibility(map, siemensMarkers, mapLayersVisibility, "Siemens", oms); useLayerVisibility(map, otdrMarkers, mapLayersVisibility, "OTDR", oms); useLayerVisibility(map, wdmMarkers, mapLayersVisibility, "WDM", oms); useLayerVisibility(map, gmaMarkers, mapLayersVisibility, "GMA", oms); useLayerVisibility(map, sonstigeMarkers, mapLayersVisibility, "Sonstige", oms); useLayerVisibility(map, tkComponentsMarkers, mapLayersVisibility, "TKKomponenten", oms); useLayerVisibility(map, talasiclMarkers, mapLayersVisibility, "TALASICL", oms); useLayerVisibility(map, dauzMarkers, mapLayersVisibility, "DAUZ", oms); useLayerVisibility(map, smsfunkmodemMarkers, mapLayersVisibility, "SMSModem", oms); useLayerVisibility(map, messstellenMarkers, mapLayersVisibility, "Messstellen", oms); useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF", oms); useEffect(() => { if (map) { var x = 51.41321407879154; var y = 7.739617925303934; var zoom = 7; if (map && map.flyTo) { map.flyTo([x, y], zoom); } else { console.error("Map object is not ready or does not have flyTo method"); } } }, [map, zoomTrigger]); //-------------------------------------------- const allMarkers = [ ...talasMarkers, ...eciMarkers, ...gsmModemMarkers, ...ciscoRouterMarkers, ...wagoMarkers, ...siemensMarkers, ...otdrMarkers, ...wdmMarkers, ...gmaMarkers, ...messstellenMarkers, ...talasiclMarkers, ...dauzMarkers, ...smsfunkmodemMarkers, ...sonstigeMarkers, ...tkComponentsMarkers, ...ulafMarkers, ]; useEffect(() => { if (map) { // Sammle alle Marker in einer einzigen Liste const editMode = localStorage.getItem("editMode") === "true"; // EditMode prüfen const visibility = mapLayersVisibility || {}; // Sichtbarkeitsstatus aus Recoil allMarkers.forEach((marker) => { const layerKey = marker.options?.layerKey; // Layer-Key aus den Marker-Optionen const isVisible = visibility[layerKey]; // Sichtbarkeitsstatus prüfen if (!layerKey || isVisible === undefined) return; if (editMode || !isVisible) { // Entferne Marker, wenn EditMode aktiv ist oder Layer unsichtbar if (map.hasLayer(marker)) map.removeLayer(marker); } else { // Füge Marker hinzu, wenn EditMode deaktiviert ist und Layer sichtbar if (!map.hasLayer(marker)) marker.addTo(map); } }); // Überprüfe überlappende Marker und füge das "Plus"-Icon hinzu checkOverlappingMarkers(map, allMarkers, plusRoundIcon); } }, [ map, talasMarkers, eciMarkers, gsmModemMarkers, ciscoRouterMarkers, wagoMarkers, siemensMarkers, otdrMarkers, wdmMarkers, gmaMarkers, messstellenMarkers, talasiclMarkers, dauzMarkers, smsfunkmodemMarkers, sonstigeMarkers, tkComponentsMarkers, ulafMarkers, mapLayersVisibility, // Neu: Abhängigkeit für Sichtbarkeitsstatus ]); //-------------------------------------------- useEffect(() => { const fetchData = async () => { try { const response1 = await fetch(webserviceGisLinesStatusUrl); const data1 = await response1.json(); //console.log("data1.Statis", data1.Statis); const reversedData = data1.Statis.reverse(); setLineStatusData(reversedData); const response2 = await fetch("/api/talas_v5_DB/gisLines/readGisLines"); const data2 = await response2.json(); const colorsByModule = {}; reversedData.forEach((stat) => { const matchingLine = data2.find((item) => item.idLD === stat.IdLD && item.idModul === stat.Modul); if (matchingLine) { colorsByModule[matchingLine.idModul] = stat.PrioColor; //console.log("Übereinstimmung gefunden für: ", stat); setLinesData(matchingLine); } }); //setLineColors(colorsByModule); } catch (error) { console.error("Error fetching data:", error); } }; fetchData(); }, []); //-------------------------------------------- //Tooltip an mouse position anzeigen für die Linien useEffect(() => { if (!map) return; // Entferne alte Marker und Polylinien markers.forEach((marker) => marker.remove()); polylines.forEach((polyline) => polyline.remove()); // Setze neue Marker und Polylinien mit den aktuellen Daten const { markers: newMarkers, polylines: newPolylines } = setupPolylines( map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, polylineVisible // polylineVisible wird jetzt korrekt übergeben ); newPolylines.forEach((polyline, index) => { const tooltipContent = tooltipContents[`${linePositions[index].idLD}-${linePositions[index].idModul}`] || "Standard-Tooltip-Inhalt"; polyline.bindTooltip(tooltipContent, { permanent: false, direction: "auto", sticky: true, offset: [20, 0], pane: "tooltipPane", }); polyline.on("mouseover", (e) => { const tooltip = polyline.getTooltip(); if (tooltip) { const mousePos = e.containerPoint; const mapSize = map.getSize(); let direction = "right"; if (mousePos.x > mapSize.x - 100) { direction = "left"; } else if (mousePos.x < 100) { direction = "right"; } if (mousePos.y > mapSize.y - 100) { direction = "top"; } else if (mousePos.y < 100) { direction = "bottom"; } tooltip.options.direction = direction; polyline.openTooltip(e.latlng); } }); polyline.on("mouseout", () => { polyline.closeTooltip(); }); }); setMarkers(newMarkers); setPolylines(newPolylines); }, [map, linePositions, lineColors, tooltipContents, newPoint, newCoords, tempMarker, polylineVisible]); //-------------------------------------------- useEffect(() => { if (map) { restoreMapSettings(map); } }, [map]); useEffect(() => { if (map) { const handleMapMoveEnd = (event) => { const newCenter = map.getCenter(); const newZoom = map.getZoom(); setCurrentCenter([newCenter.lat, newCenter.lng]); setCurrentZoom(newZoom); localStorage.setItem("mapCenter", JSON.stringify([newCenter.lat, newCenter.lng])); localStorage.setItem("mapZoom", newZoom); }; map.on("moveend", handleMapMoveEnd); map.on("zoomend", handleMapMoveEnd); return () => { map.off("moveend", handleMapMoveEnd); map.off("zoomend", handleMapMoveEnd); }; } }, [map]); //-------------------------------------------- useEffect(() => { if (selectedArea && map) { const station = GisStationsStaticDistrict.find((s) => s.Area_Name === selectedArea); if (station) { map.flyTo([station.X, station.Y], 14); } } }, [selectedArea, map, GisStationsStaticDistrict]); useEffect(() => { if (zoomTrigger && map) { map.flyTo([51.41321407879154, 7.739617925303934], 7); } }, [zoomTrigger, map]); useEffect(() => { if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded && isRightsLoaded) { addItemsToMapContextMenu(map, menuItemAdded, setMenuItemAdded, hasRights, setShowPopup, setPopupCoordinates); } }, [map, poiLayerRef, isPoiTypLoaded, menuItemAdded, hasRights, isRightsLoaded]); //-------------------------------------------- // rote Marker ganz oben wenn überlappen sind useEffect(() => { const fetchPriorityConfig = async () => { try { const res = await fetch("/api/talas_v5_DB/priorityConfig"); if (!res.ok) { throw new Error(`HTTP error! status: ${res.status}`); } const data = await res.json(); setPriorityConfig(data); } catch (error) { console.error("Failed to load priority configuration:", error); } }; fetchPriorityConfig(); }, []); //-------------------------------------------- useEffect(() => { if (mapRef.current && !map) { initializeMap(mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, setPolylineEventsDisabled); } }, [mapRef, map, hasRights, setPolylineEventsDisabled]); useEffect(() => { if (map) { if (polylineEventsDisabled) { disablePolylineEvents(window.polylines); } else { enablePolylineEvents(window.polylines, window.lineColors); } } }, [map, polylineEventsDisabled]); useEffect(() => { if (map) { console.log("6- Karteninstanz (map) wurde jetzt erfolgreich initialisiert"); // Setze die Karteninstanz in den Recoil-Atom } }, [map]); //-------------------------------------------- useEffect(() => { const initializeContextMenu = () => { if (map) { map.whenReady(() => { setTimeout(() => { if (map.contextmenu) { //console.log("Contextmenu ist vorhanden"); } else { console.warn("Contextmenu ist nicht verfügbar."); } }, 500); }); } }; initializeContextMenu(); }, [map]); //-------------------------------------------- //Tooltip Werte aktualisieren useEffect(() => { if (!map) return; // Stelle sicher, dass die Karte initialisiert ist const updateGmaData = async () => { try { const fetchOptions = { method: "GET", headers: { Connection: "close", }, }; // Aktualisiere die Messdaten await fetchGisStationsMeasurements(mapGisStationsMeasurementsUrl, setGisStationsMeasurements, fetchOptions); // Aktualisiere die Marker-Layer // useGmaMarkersLayer(map, gmaMarkers, GisStationsMeasurements, layers.MAP_LAYERS.GMA, oms); } catch (error) { console.error("Fehler beim Aktualisieren der GMA-Daten:", error); } }; // Initialer Datenabruf updateGmaData(); // Setze ein Intervall, um die Daten alle 5 Sekunden zu aktualisieren /* const intervalId = setInterval(() => { updateGmaData(); }, 5000); // Cleanup-Funktion, um das Intervall zu entfernen, wenn die Komponente entladen wird return () => clearInterval(intervalId); */ }, [map, gmaMarkers, layers.MAP_LAYERS.GMA, oms, mapGisStationsMeasurementsUrl]); //--------------------------------- const gmaLayerRef = useRef(null); const talasLayerRef = useRef(null); const eciMarkersLayerRef = useRef(null); const gsmModemMarkersLayerRef = useRef(null); const ciscoRouterMarkersLayerRef = useRef(null); const wagoMarkersLayerRef = useRef(null); const siemensMarkersLayerRef = useRef(null); const otdrMarkersLayerRef = useRef(null); const wdmMarkersLayerRef = useRef(null); const messstellenMarkersLayerRef = useRef(null); const talasiclMarkersLayerRef = useRef(null); const dauzMarkersLayerRef = useRef(null); const smsfunkmodemMarkersLayerRef = useRef(null); const ulafMarkersLayerRef = useRef(null); const sonstigeMarkersLayerRef = useRef(null); const tkComponentsMarkersRef = useRef(null); useEffect(() => { if (!gisSystemStaticLoaded || !map) return; // Sicherstellen, dass die Karte und Daten geladen sind const layerGroups = [ { ref: gmaLayerRef, id: 11, setState: setGmaMarkers }, { ref: talasLayerRef, id: 1, setState: setTalasMarkers }, { ref: eciMarkersLayerRef, id: 2, setState: setEciMarkers }, { ref: gsmModemMarkersLayerRef, id: 5, setState: setGsmModemMarkers }, { ref: ciscoRouterMarkersLayerRef, id: 6, setState: setCiscoRouterMarkers }, { ref: wagoMarkersLayerRef, id: 7, setState: setWagoMarkers }, { ref: siemensMarkersLayerRef, id: 8, setState: setSiemensMarkers }, { ref: otdrMarkersLayerRef, id: 9, setState: setOtdrMarkers }, { ref: wdmMarkersLayerRef, id: 10, setState: setWdmMarkers }, { ref: messstellenMarkersLayerRef, id: 13, setState: setMessstellenMarkers }, { ref: talasiclMarkersLayerRef, id: 100, setState: setTalasiclMarkers }, { ref: dauzMarkersLayerRef, id: 110, setState: setDauzMarkers }, { ref: smsfunkmodemMarkersLayerRef, id: 111, setState: setSmsfunkmodemMarkers }, { ref: ulafMarkersLayerRef, id: 0, setState: setUlafMarkers }, { ref: sonstigeMarkersLayerRef, id: 200, setState: setSonstigeMarkers }, { ref: tkComponentsMarkersRef, id: 30, setState: setTkComponentsMarkers }, ]; // Initialisiere LayerGroups nur einmal layerGroups.forEach(({ ref }) => { if (!ref.current) { ref.current = new L.LayerGroup().addTo(map); } }); //-------------------------------------------- //-------------------------------------------- const updateMarkers = ({ ref, id, setState }) => { if (ref.current) { ref.current.clearLayers(); // Entferne alte Marker } // Erstelle und füge neue Marker hinzu createAndSetDevices( id, (newMarkers) => { setState(newMarkers); // Zustand aktualisieren newMarkers.forEach((marker) => ref.current.addLayer(marker)); // Marker zur LayerGroup hinzufügen // Überprüfe auf überlappende Marker und füge das Plus-Icon hinzu checkOverlappingMarkers(map, newMarkers, plusRoundIcon); }, GisSystemStatic, priorityConfig ); }; // Aktualisiere alle Marker-Gruppen const updateAllMarkers = () => { layerGroups.forEach(updateMarkers); }; // Initiales Update updateAllMarkers(); // Setze ein Intervall für regelmäßige Updates /* const intervalId = setInterval(() => { updateAllMarkers(); }, 60000); // 20 Sekunden // Aufräumen bei Komponentenentladung return () => { clearInterval(intervalId); // Entferne Intervall // LayerGroups leeren layerGroups.forEach(({ ref }) => { if (ref.current) { ref.current.clearLayers(); } }); }; */ }, [gisSystemStaticLoaded, map, GisSystemStatic, priorityConfig]); //--------------------------------------- // Initialisiere Leaflet-Karte // Rufe useBereicheMarkersLayer direkt auf //const [bereichUrl, setBereichUrl] = useState(null); const urlParams = new URLSearchParams(window.location.search); // URL-Parameter parsen const mValue = urlParams.get("m"); // Wert von "m" holen const hostname = window.location.hostname; // Dynamischer Hostname const port = 3000; // Definiere den gewünschten Port const bereichUrl = `http://${hostname}:${port}/api/talas_v5_DB/bereich/readBereich?m=${mValue}`; // Dynamischer Hostname und Port // Bereichs-Marker basierend auf dynamischer URL laden const handleLocationUpdate = async (idLocation, idMap, newCoords) => { try { const result = await updateLocation(idLocation, idMap, newCoords); // Update-API console.log("Koordinaten erfolgreich aktualisiert:", result); } catch (error) { console.error("Fehler beim Aktualisieren der Location:", error); } }; // Bereichs-Marker basierend auf dynamischer URL laden const bereicheMarkers = useBereicheMarkersLayer(map, oms, bereichUrl, handleLocationUpdate); /* Bereichsmarker werden jetzt nur angezeigt, wenn der editMode aktiviert ist. Marker werden bei deaktiviertem editMode aus der Karte entfernt. Dynamische Überwachung von Änderungen im editMode über localStorage und Event Listener implementiert. Dragging für Marker im editMode aktiviert und Z-Index angepasst. */ useEffect(() => { const editMode = localStorage.getItem("editMode") === "true"; // Prüfe, ob der editMode deaktiviert ist if (!editMode) { // Entferne alle Marker aus der Karte bereicheMarkers.forEach((marker) => { if (map.hasLayer(marker)) { map.removeLayer(marker); } }); } else { // Wenn editMode aktiviert ist, füge die Marker hinzu und aktiviere Dragging bereicheMarkers.forEach((marker) => { if (!map.hasLayer(marker)) { marker.addTo(map); // Layer hinzufügen } marker.dragging.enable(); marker.setZIndexOffset(1000); // Marker nach oben setzen }); } }, [bereicheMarkers, map]); //---------------------------------- useEffect(() => { const handleVisibilityChange = () => { // Erneut die Marker-Überprüfung auslösen checkOverlappingMarkers(map, allMarkers, plusRoundIcon); }; window.addEventListener("visibilityChanged", handleVisibilityChange); return () => { window.removeEventListener("visibilityChanged", handleVisibilityChange); }; }, [map, allMarkers]); //--------------------------------------- useEffect(() => { if (map) { initGeocoderFeature(map); // Geocoder-Feature initialisieren, kann von .env.local ausgeschaltet werden } }, [map]); //-------------------------------------------- return ( <>
{showPoiUpdateModal && setShowPoiUpdateModal(false)} poiData={currentPoiData} onSubmit={() => {}} latlng={popupCoordinates} />}
{showPopup && (
e.stopPropagation()}>
)}
TALAS.Map
Version {APP_VERSION}
); }; export default MapComponent;