From 7d253a2f53bf1e37a9159b362a451478ce3fa412 Mon Sep 17 00:00:00 2001 From: ISA Date: Wed, 8 May 2024 11:07:53 +0200 Subject: [PATCH] Fix: Markers priority and bounce --- components/MapComponent copy 2.js | 1740 ++++++++++++++++++++++++++++ components/MapComponent copy.js | 1761 +++++++++++++++++++++++++++++ components/MapComponent.js | 31 +- 3 files changed, 3530 insertions(+), 2 deletions(-) create mode 100644 components/MapComponent copy 2.js create mode 100644 components/MapComponent copy.js diff --git a/components/MapComponent copy 2.js b/components/MapComponent copy 2.js new file mode 100644 index 000000000..855ef0d0c --- /dev/null +++ b/components/MapComponent copy 2.js @@ -0,0 +1,1740 @@ +// components/MapComponent.js +import React, { useEffect, useRef, useState } from "react"; +//import ReactDOM from "react-dom/client"; // Import from 'react-dom/client' +import L, { marker } 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 dynamic from "next/dynamic"; +import "leaflet.smooth_marker_bouncing"; +import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; +import DataSheet from "./DataSheet.js"; +import { useRecoilState, useRecoilValue } from "recoil"; +import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js"; +import { gisSystemStaticState } from "../store/atoms/gisSystemState.js"; +import { mapLayersState } from "../store/atoms/mapLayersState.js"; +import { selectedAreaState } from "../store/atoms/selectedAreaState.js"; +import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js"; +import { poiTypState } from "../store/atoms/poiTypState.js"; +import ShowAddStationPopup from "./ShowAddStationPopup"; +import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom"; + +//import { createRoot } from "react-dom/client"; + +const plusRoundIcon = L.icon({ + //iconUrl: "/img/plus_round.png", // Update with your actual path + iconUrl: "/img/plus_round.png", // Update with your actual path + iconSize: [32, 32], + iconAnchor: [35, 55], + className: "absolute top-0 left-0 z-10", // Adjust with Tailwind CSS classes +}); + +const MapComponent = ({ locations, onLocationUpdate }) => { + const baseUrl = "http://10.10.0.13/talas5/devices/"; + const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false); + const [poiTypMap, setPoiTypMap] = useState(new Map()); + const [showPopup, setShowPopup] = useState(false); + const [popupCoordinates, setPopupCoordinates] = useState({ + lat: 52.52, + lng: 13.405, + }); // Beispielkoordinaten + const openPopup = () => setShowPopup(true); + const closePopup = () => setShowPopup(false); + + const handleAddStation = (stationData) => { + // Station-Daten speichern oder API-Aufruf durchführen + console.log("Neue Station:", stationData); + closePopup(); // Schließt das Popup nach dem Hinzufügen + }; + // Beispiel zum Öffnen des Popups mit bestimmten Koordinaten + const openAddStationPopupWithCoordinates = (lat, lng) => { + setPopupCoordinates({ lat, lng }); + setShowPopup(true); + }; + + const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); + const [poiTypData, setPoiTypData] = useState(poiTypState); // Recoil State verwenden + 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 [online, setOnline] = useState(navigator.onLine); // Zustand der Internetverbindung + const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = + useRecoilState(gisStationsStaticDistrictState); + 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 + const [DataIcons, setDataIcons] = useState([]); // Zustand für Icon-Daten + + // Konstanten für die URLs + const mapGisStationsStaticDistrictUrl = + config.mapGisStationsStaticDistrictUrl; + const mapGisStationsStatusDistrictUrl = + config.mapGisStationsStatusDistrictUrl; + const mapGisStationsMeasurementsUrl = config.mapGisStationsMeasurementsUrl; + const mapGisSystemStaticUrl = config.mapGisSystemStaticUrl; + const mapDataIconUrl = config.mapDataIconUrl; + + // Funktion zum Aktualisieren der Position in der Datenbank + const updateLocationInDatabase = async (id, newLatitude, newLongitude) => { + const response = await fetch("/api/updateLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + id, + latitude: newLatitude, + longitude: newLongitude, + }), + }); + + if (response.ok) { + //schreib die neue Kooridnaten in die Console + //akuellisiere die Position in der Datenbank mit den neuen Koordinaten mit updateLocation mit SQL Anweisung UPDATE + } else { + console.error("Fehler beim Aktualisieren der Position"); + } + }; + + // 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 { + const response = await fetch(mapGisStationsStaticDistrictUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && 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 1: ", error); + setGisStationsStaticDistrict([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + + //GisStationsStaticDistrict Daten laden + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisStationsStaticDistrictUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && 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 1: ", error); + setGisStationsStaticDistrict([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + //GisStationsStatusDistrict Daten laden + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisStationsStatusDistrictUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && jsonResponse.Statis) { + setGisStationsStatusDistrict(jsonResponse.Statis); // Direkter Zugriff auf 'Statis' + } else { + console.error( + 'Erwartete Daten im "Statis"-Array nicht gefunden', + jsonResponse + ); + setGisStationsStatusDistrict([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten 2: ", error); + setGisStationsStatusDistrict([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + //GisStationsMeasurements Daten laden + + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisStationsMeasurementsUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && jsonResponse.Statis) { + setGisStationsMeasurements(jsonResponse.Statis); // Direkter Zugriff auf 'Statis' + } else { + console.error( + 'Erwartete Daten im "Statis"-Array nicht gefunden', + + jsonResponse + ); + setGisStationsMeasurements([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten 3: ", error); + setGisStationsMeasurements([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + + //GisSystemStatic Daten laden + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisSystemStaticUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && jsonResponse.Systems) { + setGisSystemStatic(jsonResponse.Systems); // Direkter Zugriff auf 'Systems' + // console.log("GisSystemStatic:", jsonResponse.Systems); + } else { + console.error( + 'Erwartete Daten im "Systems"-Array nicht gefunden', + jsonResponse + ); + setGisSystemStatic([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten 4: ", error); + setGisSystemStatic([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + + const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png"; + const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; + //const onlineTileLayer = "mapTiles/{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(); + + useEffect(() => { + if (typeof window !== "undefined") { + //console.log("Window height from config:", config.windowHeight); + } + }, []); + + // Funktionen zur Überwachung der Internetverbindung + const checkInternet = () => { + fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) + .then((response) => setOnline(response.ok)) + .catch(() => setOnline(false)); + }; + let initMap = []; + // Initialisierung der karte und hinzuügen der Layers + useEffect(() => { + if (mapRef.current && !map) { + initMap = L.map(mapRef.current, { + center: [53.111111, 8.4625], + zoom: 8, + layers: [ + TALAS, + ECI, + ULAF, + GSMModem, + CiscoRouter, + WAGO, + Siemens, + OTDR, + WDM, + GMA, + Sonstige, + TALASICL, + ], + minZoom: 5, // Minimale Zoomstufe + maxZoom: 15, // Maximale Zoomstufe + zoomControl: false, + contextmenu: true, + contextmenuItems: [ + { + text: "Station hinzufügen", + icon: "img/add_station.png", + //style background red color + className: "background-red", + callback: addStationCallback, + }, + { + text: "Koordinaten", + icon: "img/not_listed_location.png", + callback: showCoordinates, + }, + "-", // Divider + { text: "Reinzoomen", icon: "img/zoom_in.png", callback: zoomIn }, + { + text: "Rauszoomen", + icon: "img/zoom_out.png", + callback: zoomOut, + }, + { + text: "Hier zentrieren", + icon: "img/center_focus.png", + callback: centerHere, + }, + ], + }); + + L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { + attribution: + '© OpenStreetMap contributors', + }).addTo(initMap); + + const overlappingMarkerSpiderfier = + new window.OverlappingMarkerSpiderfier(initMap, { + nearbyDistance: 20, + }); + + setMap(initMap); + setOms(overlappingMarkerSpiderfier); + + initMap.on("zoomend", function () { + // Überprüfen, ob der aktuelle Zoom außerhalb der Grenzen liegt + if (initMap.getZoom() > 15) { + initMap.setZoom(15); + } else if (initMap.getZoom() < 5) { + initMap.setZoom(5); + } + }); + + // Nach der Initialisierung der Map und Setzen im State kannst du Funktionen aufrufen, die `map` benötigen. + initMap.whenReady(() => { + console.log("Karte ist jetzt bereit und initialisiert."); + // Rufe hier Funktionen auf, die eine initialisierte Karte benötigen. + }); + } + console.log("trigger in MapComponent.js:", poiReadTrigger); + }, [mapRef, map, poiReadTrigger]); // Prüfe die Abhängigkeiten sorgfältig + + //------------------------------------------ + 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 + } + } + //---------------------------------- + // poiTyp Daten hinzufügen + //------------------------------------------ + // Funktion zum Abrufen der poiTyp Daten + + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch("/api/readPoiTyp"); + const data = await response.json(); + setPoiTypData(data); // Daten im Recoil State speichern + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp Daten:", error); + } + }; + console.log( + "trigger in MapComponent.js in fetchPoiTypData:", + poiReadTrigger + ); + fetchPoiTypData(); + }, []); + + // Effekt zum Loggen der poiTypData, wenn sie sich ändern + useEffect(() => { + console.log("poiTypData aktualisiert:", poiTypData); + }, [poiTypData]); + + //---------------------------------------------------- + //-----Kontextmenu---------------- + function addContextMenuToMarker(marker) { + marker.bindContextMenu({ + contextmenu: true, + contextmenuWidth: 140, + contextmenuItems: [ + { + text: "Station öffnen (Tab)", + icon: "/img/screen_new.png", + callback: (e) => openInNewTab(e, marker), + }, + { + text: "Station öffnen", + icon: "/img/screen_same.png", + callback: (e) => openInSameWindow(e, marker), + }, + ], + }); + } + // Funktion zum Öffnen in einem neuen Tab + function openInNewTab(e, marker) { + console.log("Marker data:", baseUrl + marker.options.link); + window.open(baseUrl + marker.options.link, "_blank"); + } + + // Funktion zum Öffnen im gleichen Fenster + function openInSameWindow(e, marker) { + console.log("Marker data:", baseUrl + marker.options.link); + window.location.href = baseUrl + marker.options.link; + } + + const zoomIn = (e) => { + initMap.flyTo(e.latlng, 12); + //console.log("ZoomIn koordinaten in MapComponent", e.latlng); + }; + + const zoomOut = (e) => { + fly(); + }; + const centerHere = (e) => { + initMap.panTo(e.latlng); + }; + + // Funktion zum Anzeigen der Koordinaten + const showCoordinates = (e) => { + alert( + "Breitengrad: " + + e.latlng.lat.toFixed(5) + + "\nLängengrad: " + + e.latlng.lng.toFixed(5) + ); + }; + const showData = (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(); + }; + + // Kontextmenü Callback für "Station hinzufügen" + const addStationCallback = (event) => { + setPopupCoordinates(event.latlng); // Koordinaten des Klicks verwenden + setShowPopup(true); // Popup öffnen + }; + //-----Kontextmenu----ende------------ + // Ensure this function is only called when map is initialized and available + /* const showAddStationPopup = (e, map) => { + const container = L.DomUtil.create("div"); + + // Create a root container for the React component inside the popup + const root = ReactDOM.createRoot(container); + + root.render( + + + + ); + + // Create and configure the popup + L.popup().setLatLng(e.latlng).setContent(container).openOn(initMap); + + // Cleanup when the popup is closed + initMap.on("popupclose", () => { + root.unmount(); // Use unmount method from the root + }); + }; */ + + // Inside your ShowAddStationPopup component + /* useEffect(() => { + // Cleanup function to unmount React component + return () => { + if (container._reactRoot) { + container._reactRoot.unmount(); + } + }; + }, []); */ + + //------------------------------------------ + + // Hinzufügen eines neuen Standorts (Marker) in MySQL-DB-Tabelle (poi) + /* async function handleSubmit(event) { + event.preventDefault(); + const form = event.target; + + // Einfache Validierung, um sicherzustellen, dass idPoiTyp eine Zahl ist + if (!form.idPoiTyp.value || isNaN(form.idPoiTyp.value)) { + alert("Bitte geben Sie eine gültige ID für den Poi-Typ ein."); + return; // Beendet die Funktion, um das Senden von ungültigen Daten zu verhindern + } + + const data = { + name: form.name.value, + type: form.type.value, + idPoi: form.idPoi.value, + idPoiTyp: form.idPoiTyp.value, + latitude: form.lat.value, + longitude: form.lng.value, + }; + + // Senden der Daten an den Server + const response = await fetch("/api/addLocation", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + + if (response.ok) { + console.log("Station erfolgreich hinzugefügt"); + // Weitere Aktionen nach erfolgreichem Hinzufügen + } else { + console.error("Fehler beim Hinzufügen der Station"); + // Fehlerbehandlung + } + } */ + + //--------------------------------------- + + function fly(stationValue) { + var x = 51.41321407879154; + var y = 7.739617925303934; + var zoom = 7; + + initMap.flyTo([x, y], zoom); + } + + function getIconPath(status, iconNumber, marker) { + let path = status + ? `TileMap/img/icons/${status}-marker-icon-${iconNumber}.png` + : `TileMap/img/icons/marker-icon-${iconNumber}.png`; + + // Wenn der Pfad das Wort "critical" oder "major" enthält, dann den Marker bouncing options setzen + if ( + path.includes("critical") || // Priorität 1 + path.includes("major") || // Priorität 2 + path.includes("minor") || // Priorität 3 + path.includes("system") // Priorität 4 + ) { + // Setze Bouncing-Optionen + marker.setBouncingOptions({ + bounceHeight: 15, // Höhe des Bounces + contractHeight: 12, // Höhe des Einzugs beim Landen + bounceSpeed: 52, // Geschwindigkeit des Bounces + contractSpeed: 52, // Geschwindigkeit des Einzugs + shadowAngle: null, // Standard-Schattenwinkel + }); + // Check if the icon path includes 'critical' + if (path.includes("critical")) { + // marker.bounce(3); + } + } + + return path; + } + //------------------------------------------ + // Funktion, um die name und idPoiTyp von `poiTyp` MySQL DB Tabelle in einer Map zu speichern + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch("/api/readPoiTyp"); + const data = await response.json(); + const map = new Map(); + data.forEach((item) => map.set(item.idPoiTyp, item.name)); + setPoiTypMap(map); + setIsPoiTypLoaded(true); // Daten wurden erfolgreich geladen + console.log("poiTypMap:", map); + const poiTypName = poiTypMap.get(0) || "Unbekannt"; + //console.log("poiTypName:", poiTypName); + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp-Daten:", error); + } + }; + + fetchPoiTypData(); + }, []); + //------------------------------------------ + let dbLayer = null; + useEffect(() => { + if (map) { + // Schicht für Datenbank-Marker, sicherstellen, dass map nicht null ist + dbLayer = new L.LayerGroup().addTo(map); + + // Fügen Sie Ihre Marker hier innerhalb dieser useEffect hinzu, da map nicht null ist + + return () => { + // Bereinigung, entfernt dbLayer, wenn die Komponente unmountet + dbLayer.remove(); + }; + } + }, [map]); + + //------------------------------------------ + + useEffect(() => { + // Initialisierung der dbLayer, wenn die Karte verfügbar ist + if (map && !poiLayerRef.current) { + poiLayerRef.current = new L.LayerGroup().addTo(map); + } + + return () => { + if (map && poiLayerRef.current) { + // Entfernen der dbLayer bei Unmount + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + } + locations.forEach((location) => { + // Fügen Sie hier die Logik hinzu, um Marker zu erstellen und zu konfigurieren + }); + }; + console.log("trigger in MapComponent.js:", poiReadTrigger); + }, [map, locations, poiReadTrigger]); // Dieser Effekt läuft nur, wenn sich `map` ändert + + //------------------------------------------ + // poiLayerRef(poiDbLayer) POI hinzufügen + //-------------------------------------------- + + useEffect(() => { + if (map && poiLayerRef.current && isPoiTypLoaded) { + // Entfernen Sie die bestehende Ebene und erstellen Sie eine neue + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + + // Fügen Sie die aktualisierten Marker hinzu + locations.forEach((location) => { + const { latitude, longitude } = parsePoint(location.position); + const poiTypName = poiTypMap.get(location.idPoiTyp) || "Unbekannt "; + const marker = L.marker([latitude, longitude], { + icon: L.icon({ + iconUrl: "/img/icons/green-marker-icon.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + draggable: true, + id: location.idPoi, + }); + + // Popup konfigurieren + marker.bindPopup(` +
+ ${location.description || "Unbekannt"}
+ Type: ${poiTypName}
+ Lat: ${latitude.toFixed(5)}, Lng: ${longitude.toFixed(5)} +
+ `); + + // Event-Handler hinzufügen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + marker.on("dragend", (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); + console.log("trigger in MapComponent.js:", poiReadTrigger); + }); + }); + + marker.addTo(poiLayerRef.current); + /* //-------------- + const plusMarker = L.marker([latitude, longitude], { + icon: plusRoundIcon, + zIndexOffset: 1000, // Higher z-index for visibility + }); + + // Add to the poiLayer + plusMarker.addTo(poiLayerRef.current); + console.log("Adding plus icon marker at", [latitude, longitude]); + //------------ */ + }); + } + }, [map, locations, onLocationUpdate, poiReadTrigger, isPoiTypLoaded]); + + //------------------------------------------ + + function parsePoint(position) { + const [longitude, latitude] = position.slice(6, -1).split(" "); + return { latitude: parseFloat(latitude), longitude: parseFloat(longitude) }; + } + //----------------------------------------------------------------- + // TALAS Marker hinzufügen + //----------------------------------------------------------------- + // Reihenfolge nach API sortiert mit der Attribute "System" + const [talasVisible, setTalasVisible] = useRecoilState(mapLayersState); + const [eciVisible, setEciVisible] = useRecoilState(mapLayersState); + const [gsmModemVisible, setGsmModemVisible] = useRecoilState(mapLayersState); + const [ciscoRouterVisible, setCiscoRouterVisible] = + useRecoilState(mapLayersState); + const [wagoVisible, setWagoVisible] = useRecoilState(mapLayersState); + const [siemensVisible, setSiemensVisible] = useRecoilState(mapLayersState); + const [otdrVisible, setOtdrVisible] = useRecoilState(mapLayersState); + const [wdmVisible, setWdmVisible] = useRecoilState(mapLayersState); + const [gmaVisible, setGmaVisible] = useRecoilState(mapLayersState); + const [messstellenVisible, setMessstellenVisible] = + useRecoilState(mapLayersState); + const [talasiclVisible, setTalasiclVisible] = useRecoilState(mapLayersState); + const [dauzVisible, setDauzVisible] = useRecoilState(mapLayersState); + const [smsfunkmodemVisible, setSmsfunkmodemVisible] = + useRecoilState(mapLayersState); + const [sonstigeVisible, setSonstigeVisible] = useRecoilState(mapLayersState); + const [ulafVisible, setUlafVisible] = useRecoilState(mapLayersState); + + const [talasMarkers, setTalasMarkers] = useState([]); //----------------station.System === 1 + const [eciMarkers, setEciMarkers] = useState([]); //--------------------station.System === 2 + const [gsmModemMarkers, setGsmModemMarkers] = useState([]); //----------station.System === 5 + const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]); //----station.System === 6 + const [wagoMarkers, setWagoMarkers] = useState([]); //------------------station.System === 7 + const [siemensMarkers, setSiemensMarkers] = useState([]); //------------station.System === 8 + const [otdrMarkers, setOtdrMarkers] = useState([]); //------------------station.System === 9 + const [wdmMarkers, setWdmMarkers] = useState([]); //--------------------station.System === 10 + const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 + const [messstellenMarkers, setMessstellenMarkers] = useState([]); //----station.System === 13 + const [talasiclMarkers, setTalasiclMarkers] = useState([]); //----------station.System === 100 + const [dauzMarkers, setDauzMarkers] = useState([]); //------------------station.System === 110 + const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]); //--station.System === 111 + const [sonstigeMarkers, setSonstigeMarkers] = useState([]); //----------station.System === 200 + const [ulafMarkers, setUlafMarkers] = useState([]); //------------------ no exist + //-------------------------------------------------------------------------------- + function determinePriority(iconPath) { + if (iconPath.includes("critical")) return 1; // Highest priority + if (iconPath.includes("major")) return 2; + if (iconPath.includes("minor")) return 3; + if (iconPath.includes("system")) return 4; + return 5; // Default priority (lowest) + } + // Daten von einer externen Quelle laden + const createAndSetMarkers = async (systemId, setMarkersFunction) => { + try { + const response1 = await fetch(config.mapGisStationsStaticDistrictUrl); + const jsonResponse = await response1.json(); + const response2 = await fetch(config.mapGisStationsStatusDistrictUrl); + const statusResponse = await response2.json(); + + const systemStaticMap = new Map( + GisSystemStatic.map((system) => [system.IdSystem, system.Allow]) + ); + + if (jsonResponse.Points && statusResponse.Statis) { + const statisMap = new Map( + statusResponse.Statis.map((s) => [s.IdLD, s]) + ); + let markersData = jsonResponse.Points.filter( + (station) => + station.System === systemId && + systemStaticMap.get(station.System) === 1 + ).map((station) => { + const statis = statisMap.get(station.IdLD); + const iconPath = statis + ? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png` + : `img/icons/marker-icon-${station.Icon}.png`; + + const marker = L.marker([station.X, station.Y], { + icon: L.icon({ + iconUrl: iconPath, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + areaName: station.Area_Name, + link: station.Link, + bounceOnAdd: !!statis, + }); + + marker.bindPopup(` +
+

${station.LD_Name}

+

Gerät: ${station.Device}

+

Zone: ${station.Area_Short} (${station.Area_Name})

+

Standort: ${station.Location_Short} (${station.Location_Name})

+
+ `); + return marker; + }); + + setMarkersFunction(markersData); + } + } catch (error) { + console.error("Error fetching data: ", error); + } + }; + useEffect(() => { + if (!map) return; + createAndSetMarkers(1, setTalasMarkers); // TALAS-System + createAndSetMarkers(2, setEciMarkers); // ECI-System + createAndSetMarkers(5, setGsmModemMarkers); // GSM-Modem-System + createAndSetMarkers(6, setCiscoRouterMarkers); // Cisco-Router-System + createAndSetMarkers(7, setWagoMarkers); // WAGO-System + createAndSetMarkers(8, setSiemensMarkers); // Siemens-System + createAndSetMarkers(9, setOtdrMarkers); // OTDR-System + createAndSetMarkers(10, setWdmMarkers); // WDM-System + createAndSetMarkers(11, setGmaMarkers); // GMA-System + createAndSetMarkers(13, setMessstellenMarkers); // Messstellen-System + createAndSetMarkers(100, setTalasiclMarkers); // TALASICL-System + createAndSetMarkers(110, setDauzMarkers); // DAUZ-System + createAndSetMarkers(111, setSmsfunkmodemMarkers); // SMS-Funkmodem-System + createAndSetMarkers(200, setSonstigeMarkers); // Sonstige-System + createAndSetMarkers(0, setUlafMarkers); // ULAF-System + }, [map]); + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && talasMarkers.length) { + talasMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + //console.log("Talas marker:", marker._latlng.lat, marker._latlng.lng); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + /* //-------------- + const latitude = marker._latlng.lat; + const longitude = marker._latlng.lng; + const plusMarker = L.marker([latitude, longitude], { + icon: plusRoundIcon, + zIndexOffset: 1000, // Higher z-index for visibility + }); + + // Add to the poiLayer + plusMarker.addTo(poiLayerRef.current); + console.log("Adding plus icon marker at", [latitude, longitude]); + //------------ */ + addContextMenuToMarker(marker); + }); + map.addLayer(TALAS); + + // Call the function here + checkOverlappingMarkers(oms, map, plusRoundIcon); + } + }, [map, talasMarkers]); // Abhängigkeiten auf `map` und `talasMarkers` beschränken + + //console.log("talasMarkers", talasMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && eciMarkers.length) { + eciMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(ECI); + } + }, [map, eciMarkers]); + + //console.log("eciMarkers", eciMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && gsmModemMarkers.length) { + gsmModemMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GSMModem); + } + }, [map, gsmModemMarkers]); + + //console.log("gsmModemMarkers", gsmModemMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && ciscoRouterMarkers.length) { + ciscoRouterMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(CiscoRouter); + } + }, [map, ciscoRouterMarkers]); + + //console.log("ciscoRouterMarkers", ciscoRouterMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && wagoMarkers.length) { + wagoMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(WAGO); + + //toggleLayer(mapLayersVisibility.WAGO); + } + // }, [map, wagoMarkers, mapLayersVisibility.WAGO]); + }, [map, wagoMarkers]); + //console.log("wagoMarkers", wagoMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && siemensMarkers.length) { + siemensMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(Siemens); + } + }, [map, siemensMarkers]); + + //console.log("siemensMarkers", siemensMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && otdrMarkers.length) { + otdrMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(OTDR); + } + }, [map, otdrMarkers]); + + //console.log("otdrMarkers", otdrMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && wdmMarkers.length) { + wdmMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(WDM); + } + }, [map, wdmMarkers]); + + //console.log("wdmMarkers", wdmMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && gmaMarkers.length) { + // Filtern des Arrays um nur "GMA" Messungen zu erhalten + const gmaMeasurements = GisStationsMeasurements.filter( + (m) => m.Gr === "GMA" + ); + let area_name = ""; + let measurements = {}; + + gmaMeasurements.forEach((m) => { + //console.log(`Messung: ${m.Area_Name}, Na: ${m.Na}, Wert: ${m.Val}`); + area_name = m.Area_Name; // Dies überschreibt area_name mit dem letzten Area_Name im Array + measurements[m.Na] = m.Val; // Speichert den Wert von Val unter dem Code Na in einem Objekt + }); + + // Zugriff auf die Werte über die Codes + let measurementLT = measurements["LT"]; + let measurementFTP = measurements["FTP"]; + let measurementGT = measurements["GT"]; + let measurementRLF = measurements["RLF"]; + + /* console.log( + "area_name", + area_name, + "------measurementLT", + measurements.LT, + "-------measurementFBT", + measurements.FBT, + "------measurementGT", + measurements.GT, + "------measurementRLF", + measurements.RLF + ); + console.log("measurements", measurements); */ + gmaMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Tooltip beim Überfahren mit der Maus anzeigen + marker.bindTooltip( + ` +
+
+ ${area_name} +
+
+ LT : ${measurements.LT} °C +
+
+ FBT : ${measurements.FBT} °C +
+
+ GT : ${measurements.GT === "nicht ermittelbar" ? measurements.GT : `${measurements.GT} °C`} +
+
+ RLF : ${measurements.RLF} % +
+
+ `, + { + permanent: true, // Tooltip wird ständig angezeigt + direction: "auto", // Automatische Ausrichtung + offset: [20, 0], // Offset-Werte + } + ); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GMA); + } + }, [map, gmaMarkers]); // Abhängigkeiten auf `map` und `gmaMarkers` beschränken + + //console.log("gmaMarkers", gmaMarkers); + + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && messstellenMarkers.length) { + messstellenMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GMA); + } + }, [map, messstellenMarkers]); + + //console.log("messstellenMarkers", messstellenMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && talasiclMarkers.length) { + talasiclMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(TALASICL); + } + }, [map, talasiclMarkers]); + + //console.log("talasiclMarkers", talasiclMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && dauzMarkers.length) { + dauzMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, dauzMarkers]); + + //console.log("dauzMarkers", dauzMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && smsfunkmodemMarkers.length) { + smsfunkmodemMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, smsfunkmodemMarkers]); + + //console.log("smsfunkmodemMarkers", smsfunkmodemMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && ulafMarkers.length) { + ulafMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, ulafMarkers]); + + //console.log("ulafMarkers", ulafMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && sonstigeMarkers.length) { + sonstigeMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, sonstigeMarkers]); + + //console.log("sonstige", sonstigeMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + + const mapLayersVisibility = useRecoilValue(mapLayersState); + + /* useEffect(() => { + if (!map || !talasMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + talasMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + talasMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Apply visibility state to the TALAS layer + toggleLayer(mapLayersVisibility.TALAS); + }, [map, talasMarkers, mapLayersVisibility.TALAS]); */ // Depend on map, markers array, and visibility state + + const handleCheckboxChange = (name, event) => { + const { checked } = event.target; + const internalName = layerNames[name] || name; // Nutzt den internen Namen, wenn vorhanden, sonst den originalen Namen + + setMapLayersVisibility((prev) => { + return { + ...prev, + [internalName]: checked, + }; + }); + }; + + //------------------------------------------ + + // Funktion zum Ein- und Ausblenden der TALAS-Marker basierend auf dem Zustand von mapLayersVisibility.TALAS + + useEffect(() => { + if (!map || !talasMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + talasMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + talasMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Apply visibility state to the TALAS layer + toggleLayer(mapLayersVisibility.TALAS); + }, [map, talasMarkers, mapLayersVisibility.TALAS]); + + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der ECI-Marker basierend auf dem Zustand von mapLayersVisibility.ECI + + useEffect(() => { + if (!map || !eciMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + eciMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + eciMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility state to the ECI layer + toggleLayer(mapLayersVisibility.ECI); + }, [map, eciMarkers, mapLayersVisibility.ECI]); + + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der ULAF-Marker basierend auf dem Zustand von mapLayersVisibility.ULAF + + useEffect(() => { + if (!map || !ulafMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + ulafMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + ulafMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.ULAF); + }, [map, ulafMarkers, mapLayersVisibility.ULAF]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der GSMModem-Marker basierend auf dem Zustand von mapLayersVisibility.GSMModem + + useEffect(() => { + if (!map || !gsmModemMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + gsmModemMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + gsmModemMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.GSMModem); + }, [map, gsmModemMarkers, mapLayersVisibility.GSMModem]); + + //------------------------------------------ */ + const layerNames = { + "GSM Modem": "GSMMODEM", + "Cisco Router": "CiscoRouter", + "TALAS ICL": "TALASICL", + "SMS-Funkmodem": "GSMModem", + }; + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der CiscoRouter-Marker basierend auf dem Zustand von mapLayersVisibility.CiscoRouter + + useEffect(() => { + if (!map || !ciscoRouterMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + ciscoRouterMarkers.forEach((marker) => marker.addTo(map)); + } else { + ciscoRouterMarkers.forEach((marker) => map.removeLayer(marker)); + } + }; + // Nutzt die Map, um den internen Namen zu bekommen + const internalName = layerNames["Cisco Router"] || "CiscoRouter"; + toggleLayer(mapLayersVisibility[internalName]); + //console.log("internalName Cisco Router: ", internalName); + }, [map, ciscoRouterMarkers, mapLayersVisibility]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der WAGO-Marker basierend auf dem Zustand von mapLayersVisibility.WAGO + + useEffect(() => { + if (!map || !wagoMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + wagoMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + wagoMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.WAGO); + }, [map, wagoMarkers, mapLayersVisibility.WAGO]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der Siemens-Marker basierend auf dem Zustand von mapLayersVisibility.Siemens + + useEffect(() => { + if (!map || !siemensMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + siemensMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + siemensMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.Siemens); + }, [map, siemensMarkers, mapLayersVisibility.Siemens]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der OTDR-Marker basierend auf dem Zustand von mapLayersVisibility.OTDR + + useEffect(() => { + if (!map || !otdrMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + otdrMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + otdrMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.OTDR); + }, [map, otdrMarkers, mapLayersVisibility.OTDR]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der WDM-Marker basierend auf dem Zustand von mapLayersVisibility.WDM + + useEffect(() => { + if (!map || !wdmMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + wdmMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + wdmMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.WDM); + }, [map, wdmMarkers, mapLayersVisibility.WDM]); + + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der GMA-Marker basierend auf dem Zustand von mapLayersVisibility.GMA + + useEffect(() => { + if (!map || !gmaMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + gmaMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + gmaMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Apply visibility + toggleLayer(mapLayersVisibility.GMA); + }, [map, gmaMarkers, mapLayersVisibility.GMA]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der Sonstige-Marker basierend auf dem Zustand von mapLayersVisibility.Sonstige + + useEffect(() => { + if (!map || !sonstigeMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + sonstigeMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + sonstigeMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.Sonstige); + }, [map, sonstigeMarkers, mapLayersVisibility.Sonstige]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der TALASICL-Marker basierend auf dem Zustand von mapLayersVisibility.TALASICL + + useEffect(() => { + if (!map || !talasiclMarkers) return; + //console.log("talasiclMarkers", talasiclMarkers); + const toggleLayer = (isVisible) => { + if (isVisible) { + talasiclMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + talasiclMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Verwendung der Map, um den internen Namen zu bekommen, und Fallback auf "TALASICL", falls nicht gefunden + const internalName = + layerNames["TALAS ICL"] || "TALASICL || talasiclMarkers "; + toggleLayer(mapLayersVisibility[internalName]); + //console.log("internalName for TALAS ICL in MapComponent: ", internalName); + }, [map, talasiclMarkers, mapLayersVisibility]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der DAUZ-Marker basierend auf dem Zustand von mapLayersVisibility.DAUZ + + useEffect(() => { + if (!map || !dauzMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + dauzMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + dauzMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.DAUZ); + }, [map, dauzMarkers, mapLayersVisibility.DAUZ]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der SMSFunkmodem-Marker basierend auf dem Zustand von mapLayersVisibility.SMSFunkmodem + + useEffect(() => { + if (!map || !smsfunkmodemMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + smsfunkmodemMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + smsfunkmodemMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.SMSFunkmodem); + }, [map, smsfunkmodemMarkers, mapLayersVisibility.SMSFunkmodem]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der Messstellen-Marker basierend auf dem Zustand von mapLayersVisibility.Messstellen + + useEffect(() => { + if (!map || !messstellenMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + messstellenMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + messstellenMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.Messstellen); + }, [map, messstellenMarkers, mapLayersVisibility.Messstellen]); + + //------------------------------------------ */ + const selectedArea = useRecoilValue(selectedAreaState); + + // Combine all markers into a single array + const allMarkers = [ + ...talasMarkers, + ...eciMarkers, + ...gsmModemMarkers, + ...ciscoRouterMarkers, + ...wagoMarkers, + ...siemensMarkers, + ...otdrMarkers, + ...wdmMarkers, + ...gmaMarkers, + ...messstellenMarkers, + ...talasiclMarkers, + ...dauzMarkers, + ...smsfunkmodemMarkers, + ...sonstigeMarkers, + ...ulafMarkers, + ]; + + // Function to find a marker by areaName across all groups + const findMyMarker = (areaName) => { + return allMarkers.find((marker) => marker.options.areaName === areaName); + }; + + // Effect to handle navigation to selected area + useEffect(() => { + if (selectedArea && map) { + const marker = findMyMarker(selectedArea); + if (marker) { + map.flyTo(marker.getLatLng(), 14); // Adjust zoom level as needed + } + } + }, [selectedArea, map, allMarkers]); // Include allMarkers in the dependencies + + /* const findMyMarker = (areaName) => { + // Angenommen, jeder Marker hat eine option `areaName`, die beim Erstellen gesetzt wurde. + return talasMarkers.find((marker) => marker.options.areaName === areaName); + }; */ + + //------------------------------------------ + + const zoomTrigger = useRecoilValue(zoomTriggerState); + + 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"); + } // Ihre bereits existierende Funktion, die Zoom-Out ausführt + } + }, [map, zoomTrigger]); + + //--------------------------------------------------------- + useEffect(() => { + console.log("Aktualisierung in MapComponent.js:", poiReadTrigger); + + // Logik zur Aktualisierung der Map hier hinzufügen + // Beispiel: Daten neu laden oder aktualisieren + }, [poiReadTrigger]); + //--------------------------------------------------------- + // Now update checkOverlappingMarkers to check if oms is initialized + function checkOverlappingMarkers(map, markers, plusIcon) { + // Ensure markers is always an array + if (!Array.isArray(markers)) { + //console.error("The `markers` argument is not an array:", markers); + return; + } + + const overlappingGroups = {}; + + // Group markers by coordinates as strings + markers.forEach((marker) => { + const latlngStr = marker.getLatLng().toString(); + if (overlappingGroups[latlngStr]) { + overlappingGroups[latlngStr].push(marker); + } else { + overlappingGroups[latlngStr] = [marker]; + } + }); + + // Add plus markers at coordinates where overlaps occur + for (const coords in overlappingGroups) { + if (overlappingGroups[coords].length > 1) { + const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number)); + const plusMarker = L.marker(latLng, { icon: plusIcon }); + plusMarker.addTo(map); + + //console.log("Adding plus icon marker at", latLng); + } + } + } + + //--------------------------------------------------------- + useEffect(() => { + if (map) { + // Combine all markers from different layers + const allMarkers = [ + ...talasMarkers, + ...eciMarkers, + ...gsmModemMarkers, + ...ciscoRouterMarkers, + ...wagoMarkers, + ...siemensMarkers, + ...otdrMarkers, + ...wdmMarkers, + ...gmaMarkers, + ...messstellenMarkers, + ...talasiclMarkers, + ...dauzMarkers, + ...smsfunkmodemMarkers, + ...sonstigeMarkers, + ...ulafMarkers, + ]; + + // Call the function to check for overlaps and add plus icons + checkOverlappingMarkers(map, allMarkers, plusRoundIcon); + } + }, [ + map, + talasMarkers, + eciMarkers, + gsmModemMarkers, + ciscoRouterMarkers, + wagoMarkers, + siemensMarkers, + otdrMarkers, + wdmMarkers, + gmaMarkers, + messstellenMarkers, + talasiclMarkers, + dauzMarkers, + smsfunkmodemMarkers, + sonstigeMarkers, + ulafMarkers, + ]); + + //--------------------------------------------------------- + + return ( + <> +
+ {/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */} + {showPopup && ( +
+
e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters + > + {/* Schließen-Button oben rechts */} + + + {/* Formular-Komponente zum Hinzufügen einer Station */} + +
+
+ )} +
+ + + +
+ + ); +}; + +export default MapComponent; diff --git a/components/MapComponent copy.js b/components/MapComponent copy.js new file mode 100644 index 000000000..df667e9e5 --- /dev/null +++ b/components/MapComponent copy.js @@ -0,0 +1,1761 @@ +// components/MapComponent.js +import React, { useEffect, useRef, useState } from "react"; +//import ReactDOM from "react-dom/client"; // Import from 'react-dom/client' +import L, { marker } 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 dynamic from "next/dynamic"; +import "leaflet.smooth_marker_bouncing"; +import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; +import DataSheet from "./DataSheet.js"; +import { useRecoilState, useRecoilValue } from "recoil"; +import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js"; +import { gisSystemStaticState } from "../store/atoms/gisSystemState.js"; +import { mapLayersState } from "../store/atoms/mapLayersState.js"; +import { selectedAreaState } from "../store/atoms/selectedAreaState.js"; +import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js"; +import { poiTypState } from "../store/atoms/poiTypState.js"; +import ShowAddStationPopup from "./ShowAddStationPopup"; +import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom"; + +//import { createRoot } from "react-dom/client"; + +const plusRoundIcon = L.icon({ + //iconUrl: "/img/plus_round.png", // Update with your actual path + iconUrl: "/img/plus_round.png", // Update with your actual path + iconSize: [32, 32], + iconAnchor: [35, 55], + className: "absolute top-0 left-0 z-10", // Adjust with Tailwind CSS classes +}); + +const MapComponent = ({ locations, onLocationUpdate }) => { + const baseUrl = "http://10.10.0.13/talas5/devices/"; + const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false); + const [poiTypMap, setPoiTypMap] = useState(new Map()); + const [showPopup, setShowPopup] = useState(false); + const [popupCoordinates, setPopupCoordinates] = useState({ + lat: 52.52, + lng: 13.405, + }); // Beispielkoordinaten + const openPopup = () => setShowPopup(true); + const closePopup = () => setShowPopup(false); + + const handleAddStation = (stationData) => { + // Station-Daten speichern oder API-Aufruf durchführen + console.log("Neue Station:", stationData); + closePopup(); // Schließt das Popup nach dem Hinzufügen + }; + // Beispiel zum Öffnen des Popups mit bestimmten Koordinaten + const openAddStationPopupWithCoordinates = (lat, lng) => { + setPopupCoordinates({ lat, lng }); + setShowPopup(true); + }; + + const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom); + const [poiTypData, setPoiTypData] = useState(poiTypState); // Recoil State verwenden + 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 [online, setOnline] = useState(navigator.onLine); // Zustand der Internetverbindung + const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = + useRecoilState(gisStationsStaticDistrictState); + 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 + const [DataIcons, setDataIcons] = useState([]); // Zustand für Icon-Daten + + // Konstanten für die URLs + const mapGisStationsStaticDistrictUrl = + config.mapGisStationsStaticDistrictUrl; + const mapGisStationsStatusDistrictUrl = + config.mapGisStationsStatusDistrictUrl; + const mapGisStationsMeasurementsUrl = config.mapGisStationsMeasurementsUrl; + const mapGisSystemStaticUrl = config.mapGisSystemStaticUrl; + const mapDataIconUrl = config.mapDataIconUrl; + + // Funktion zum Aktualisieren der Position in der Datenbank + const updateLocationInDatabase = async (id, newLatitude, newLongitude) => { + const response = await fetch("/api/updateLocation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + id, + latitude: newLatitude, + longitude: newLongitude, + }), + }); + + if (response.ok) { + //schreib die neue Kooridnaten in die Console + //akuellisiere die Position in der Datenbank mit den neuen Koordinaten mit updateLocation mit SQL Anweisung UPDATE + } else { + console.error("Fehler beim Aktualisieren der Position"); + } + }; + + // 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 { + const response = await fetch(mapGisStationsStaticDistrictUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && 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 1: ", error); + setGisStationsStaticDistrict([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + + //GisStationsStaticDistrict Daten laden + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisStationsStaticDistrictUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && 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 1: ", error); + setGisStationsStaticDistrict([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + //GisStationsStatusDistrict Daten laden + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisStationsStatusDistrictUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && jsonResponse.Statis) { + setGisStationsStatusDistrict(jsonResponse.Statis); // Direkter Zugriff auf 'Statis' + } else { + console.error( + 'Erwartete Daten im "Statis"-Array nicht gefunden', + jsonResponse + ); + setGisStationsStatusDistrict([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten 2: ", error); + setGisStationsStatusDistrict([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + //GisStationsMeasurements Daten laden + + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisStationsMeasurementsUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && jsonResponse.Statis) { + setGisStationsMeasurements(jsonResponse.Statis); // Direkter Zugriff auf 'Statis' + } else { + console.error( + 'Erwartete Daten im "Statis"-Array nicht gefunden', + + jsonResponse + ); + setGisStationsMeasurements([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten 3: ", error); + setGisStationsMeasurements([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + + //GisSystemStatic Daten laden + useEffect(() => { + const fetchData = async () => { + try { + const response = await fetch(mapGisSystemStaticUrl); + const jsonResponse = await response.json(); + + // Prüfen, ob die Antwort das erwartete Format hat und Daten enthält + if (jsonResponse && jsonResponse.Systems) { + setGisSystemStatic(jsonResponse.Systems); // Direkter Zugriff auf 'Systems' + // console.log("GisSystemStatic:", jsonResponse.Systems); + } else { + console.error( + 'Erwartete Daten im "Systems"-Array nicht gefunden', + jsonResponse + ); + setGisSystemStatic([]); + } + } catch (error) { + console.error("Fehler beim Laden der Daten 4: ", error); + setGisSystemStatic([]); + } + }; + + fetchData(); + }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen + //------------------------------------------ + + const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png"; + const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; + //const onlineTileLayer = "mapTiles/{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(); + + useEffect(() => { + if (typeof window !== "undefined") { + //console.log("Window height from config:", config.windowHeight); + } + }, []); + + // Funktionen zur Überwachung der Internetverbindung + const checkInternet = () => { + fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) + .then((response) => setOnline(response.ok)) + .catch(() => setOnline(false)); + }; + let initMap = []; + // Initialisierung der karte und hinzuügen der Layers + useEffect(() => { + if (mapRef.current && !map) { + initMap = L.map(mapRef.current, { + center: [53.111111, 8.4625], + zoom: 8, + layers: [ + TALAS, + ECI, + ULAF, + GSMModem, + CiscoRouter, + WAGO, + Siemens, + OTDR, + WDM, + GMA, + Sonstige, + TALASICL, + ], + minZoom: 5, // Minimale Zoomstufe + maxZoom: 15, // Maximale Zoomstufe + zoomControl: false, + contextmenu: true, + contextmenuItems: [ + { + text: "Station hinzufügen", + icon: "img/add_station.png", + //style background red color + className: "background-red", + callback: addStationCallback, + }, + { + text: "Koordinaten", + icon: "img/not_listed_location.png", + callback: showCoordinates, + }, + "-", // Divider + { text: "Reinzoomen", icon: "img/zoom_in.png", callback: zoomIn }, + { + text: "Rauszoomen", + icon: "img/zoom_out.png", + callback: zoomOut, + }, + { + text: "Hier zentrieren", + icon: "img/center_focus.png", + callback: centerHere, + }, + ], + }); + + L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { + attribution: + '© OpenStreetMap contributors', + }).addTo(initMap); + + const overlappingMarkerSpiderfier = + new window.OverlappingMarkerSpiderfier(initMap, { + nearbyDistance: 20, + }); + + setMap(initMap); + setOms(overlappingMarkerSpiderfier); + + initMap.on("zoomend", function () { + // Überprüfen, ob der aktuelle Zoom außerhalb der Grenzen liegt + if (initMap.getZoom() > 15) { + initMap.setZoom(15); + } else if (initMap.getZoom() < 5) { + initMap.setZoom(5); + } + }); + + // Nach der Initialisierung der Map und Setzen im State kannst du Funktionen aufrufen, die `map` benötigen. + initMap.whenReady(() => { + console.log("Karte ist jetzt bereit und initialisiert."); + // Rufe hier Funktionen auf, die eine initialisierte Karte benötigen. + }); + } + console.log("trigger in MapComponent.js:", poiReadTrigger); + }, [mapRef, map, poiReadTrigger]); // Prüfe die Abhängigkeiten sorgfältig + + //------------------------------------------ + 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 + } + } + //---------------------------------- + // poiTyp Daten hinzufügen + //------------------------------------------ + // Funktion zum Abrufen der poiTyp Daten + + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch("/api/readPoiTyp"); + const data = await response.json(); + setPoiTypData(data); // Daten im Recoil State speichern + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp Daten:", error); + } + }; + console.log( + "trigger in MapComponent.js in fetchPoiTypData:", + poiReadTrigger + ); + fetchPoiTypData(); + }, []); + + // Effekt zum Loggen der poiTypData, wenn sie sich ändern + useEffect(() => { + console.log("poiTypData aktualisiert:", poiTypData); + }, [poiTypData]); + + //---------------------------------------------------- + //-----Kontextmenu---------------- + function addContextMenuToMarker(marker) { + marker.bindContextMenu({ + contextmenu: true, + contextmenuWidth: 140, + contextmenuItems: [ + { + text: "Station öffnen (Tab)", + icon: "/img/screen_new.png", + callback: (e) => openInNewTab(e, marker), + }, + { + text: "Station öffnen", + icon: "/img/screen_same.png", + callback: (e) => openInSameWindow(e, marker), + }, + ], + }); + } + // Funktion zum Öffnen in einem neuen Tab + function openInNewTab(e, marker) { + console.log("Marker data:", baseUrl + marker.options.link); + window.open(baseUrl + marker.options.link, "_blank"); + } + + // Funktion zum Öffnen im gleichen Fenster + function openInSameWindow(e, marker) { + console.log("Marker data:", baseUrl + marker.options.link); + window.location.href = baseUrl + marker.options.link; + } + + const zoomIn = (e) => { + initMap.flyTo(e.latlng, 12); + //console.log("ZoomIn koordinaten in MapComponent", e.latlng); + }; + + const zoomOut = (e) => { + fly(); + }; + const centerHere = (e) => { + initMap.panTo(e.latlng); + }; + + // Funktion zum Anzeigen der Koordinaten + const showCoordinates = (e) => { + alert( + "Breitengrad: " + + e.latlng.lat.toFixed(5) + + "\nLängengrad: " + + e.latlng.lng.toFixed(5) + ); + }; + const showData = (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(); + }; + + // Kontextmenü Callback für "Station hinzufügen" + const addStationCallback = (event) => { + setPopupCoordinates(event.latlng); // Koordinaten des Klicks verwenden + setShowPopup(true); // Popup öffnen + }; + //-----Kontextmenu----ende------------ + // Ensure this function is only called when map is initialized and available + /* const showAddStationPopup = (e, map) => { + const container = L.DomUtil.create("div"); + + // Create a root container for the React component inside the popup + const root = ReactDOM.createRoot(container); + + root.render( + + + + ); + + // Create and configure the popup + L.popup().setLatLng(e.latlng).setContent(container).openOn(initMap); + + // Cleanup when the popup is closed + initMap.on("popupclose", () => { + root.unmount(); // Use unmount method from the root + }); + }; */ + + // Inside your ShowAddStationPopup component + /* useEffect(() => { + // Cleanup function to unmount React component + return () => { + if (container._reactRoot) { + container._reactRoot.unmount(); + } + }; + }, []); */ + + //------------------------------------------ + + // Hinzufügen eines neuen Standorts (Marker) in MySQL-DB-Tabelle (poi) + /* async function handleSubmit(event) { + event.preventDefault(); + const form = event.target; + + // Einfache Validierung, um sicherzustellen, dass idPoiTyp eine Zahl ist + if (!form.idPoiTyp.value || isNaN(form.idPoiTyp.value)) { + alert("Bitte geben Sie eine gültige ID für den Poi-Typ ein."); + return; // Beendet die Funktion, um das Senden von ungültigen Daten zu verhindern + } + + const data = { + name: form.name.value, + type: form.type.value, + idPoi: form.idPoi.value, + idPoiTyp: form.idPoiTyp.value, + latitude: form.lat.value, + longitude: form.lng.value, + }; + + // Senden der Daten an den Server + const response = await fetch("/api/addLocation", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(data), + }); + + if (response.ok) { + console.log("Station erfolgreich hinzugefügt"); + // Weitere Aktionen nach erfolgreichem Hinzufügen + } else { + console.error("Fehler beim Hinzufügen der Station"); + // Fehlerbehandlung + } + } */ + + //--------------------------------------- + + function fly(stationValue) { + var x = 51.41321407879154; + var y = 7.739617925303934; + var zoom = 7; + + initMap.flyTo([x, y], zoom); + } + + function getIconPath(status, iconNumber, marker) { + let path = status + ? `TileMap/img/icons/${status}-marker-icon-${iconNumber}.png` + : `TileMap/img/icons/marker-icon-${iconNumber}.png`; + + // Wenn der Pfad das Wort "critical" oder "major" enthält, dann den Marker bouncing options setzen + if ( + path.includes("critical") || // Priorität 1 + path.includes("major") || // Priorität 2 + path.includes("minor") || // Priorität 3 + path.includes("system") // Priorität 4 + ) { + // Setze Bouncing-Optionen + marker.setBouncingOptions({ + bounceHeight: 15, // Höhe des Bounces + contractHeight: 12, // Höhe des Einzugs beim Landen + bounceSpeed: 52, // Geschwindigkeit des Bounces + contractSpeed: 52, // Geschwindigkeit des Einzugs + shadowAngle: null, // Standard-Schattenwinkel + }); + // Check if the icon path includes 'critical' + if (path.includes("critical")) { + // marker.bounce(3); + } + } + + return path; + } + //------------------------------------------ + // Funktion, um die name und idPoiTyp von `poiTyp` MySQL DB Tabelle in einer Map zu speichern + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch("/api/readPoiTyp"); + const data = await response.json(); + const map = new Map(); + data.forEach((item) => map.set(item.idPoiTyp, item.name)); + setPoiTypMap(map); + setIsPoiTypLoaded(true); // Daten wurden erfolgreich geladen + console.log("poiTypMap:", map); + const poiTypName = poiTypMap.get(0) || "Unbekannt"; + console.log("poiTypName:", poiTypName); + } catch (error) { + console.error("Fehler beim Abrufen der poiTyp-Daten:", error); + } + }; + + fetchPoiTypData(); + }, []); + //------------------------------------------ + let dbLayer = null; + useEffect(() => { + if (map) { + // Schicht für Datenbank-Marker, sicherstellen, dass map nicht null ist + dbLayer = new L.LayerGroup().addTo(map); + + // Fügen Sie Ihre Marker hier innerhalb dieser useEffect hinzu, da map nicht null ist + + return () => { + // Bereinigung, entfernt dbLayer, wenn die Komponente unmountet + dbLayer.remove(); + }; + } + }, [map]); + + //------------------------------------------ + + useEffect(() => { + // Initialisierung der dbLayer, wenn die Karte verfügbar ist + if (map && !poiLayerRef.current) { + poiLayerRef.current = new L.LayerGroup().addTo(map); + } + + return () => { + if (map && poiLayerRef.current) { + // Entfernen der dbLayer bei Unmount + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + } + locations.forEach((location) => { + // Fügen Sie hier die Logik hinzu, um Marker zu erstellen und zu konfigurieren + }); + }; + console.log("trigger in MapComponent.js:", poiReadTrigger); + }, [map, locations, poiReadTrigger]); // Dieser Effekt läuft nur, wenn sich `map` ändert + + //------------------------------------------ + // poiLayerRef(poiDbLayer) POI hinzufügen + //-------------------------------------------- + + useEffect(() => { + if (map && poiLayerRef.current && isPoiTypLoaded) { + // Entfernen Sie die bestehende Ebene und erstellen Sie eine neue + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + + // Fügen Sie die aktualisierten Marker hinzu + locations.forEach((location) => { + const { latitude, longitude } = parsePoint(location.position); + const poiTypName = poiTypMap.get(location.idPoiTyp) || "Unbekannt "; + const marker = L.marker([latitude, longitude], { + icon: L.icon({ + iconUrl: "/img/icons/green-marker-icon.png", + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + draggable: true, + id: location.idPoi, + }); + + // Popup konfigurieren + marker.bindPopup(` +
+ ${location.description || "Unbekannt"}
+ Type: ${poiTypName}
+ Lat: ${latitude.toFixed(5)}, Lng: ${longitude.toFixed(5)} +
+ `); + + // Event-Handler hinzufügen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + + marker.on("dragend", (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); + console.log("trigger in MapComponent.js:", poiReadTrigger); + }); + }); + + marker.addTo(poiLayerRef.current); + /* //-------------- + const plusMarker = L.marker([latitude, longitude], { + icon: plusRoundIcon, + zIndexOffset: 1000, // Higher z-index for visibility + }); + + // Add to the poiLayer + plusMarker.addTo(poiLayerRef.current); + console.log("Adding plus icon marker at", [latitude, longitude]); + //------------ */ + }); + } + }, [map, locations, onLocationUpdate, poiReadTrigger, isPoiTypLoaded]); + + //------------------------------------------ + + function parsePoint(position) { + const [longitude, latitude] = position.slice(6, -1).split(" "); + return { latitude: parseFloat(latitude), longitude: parseFloat(longitude) }; + } + //----------------------------------------------------------------- + // TALAS Marker hinzufügen + //----------------------------------------------------------------- + // Reihenfolge nach API sortiert mit der Attribute "System" + const [talasVisible, setTalasVisible] = useRecoilState(mapLayersState); + const [eciVisible, setEciVisible] = useRecoilState(mapLayersState); + const [gsmModemVisible, setGsmModemVisible] = useRecoilState(mapLayersState); + const [ciscoRouterVisible, setCiscoRouterVisible] = + useRecoilState(mapLayersState); + const [wagoVisible, setWagoVisible] = useRecoilState(mapLayersState); + const [siemensVisible, setSiemensVisible] = useRecoilState(mapLayersState); + const [otdrVisible, setOtdrVisible] = useRecoilState(mapLayersState); + const [wdmVisible, setWdmVisible] = useRecoilState(mapLayersState); + const [gmaVisible, setGmaVisible] = useRecoilState(mapLayersState); + const [messstellenVisible, setMessstellenVisible] = + useRecoilState(mapLayersState); + const [talasiclVisible, setTalasiclVisible] = useRecoilState(mapLayersState); + const [dauzVisible, setDauzVisible] = useRecoilState(mapLayersState); + const [smsfunkmodemVisible, setSmsfunkmodemVisible] = + useRecoilState(mapLayersState); + const [sonstigeVisible, setSonstigeVisible] = useRecoilState(mapLayersState); + const [ulafVisible, setUlafVisible] = useRecoilState(mapLayersState); + + const [talasMarkers, setTalasMarkers] = useState([]); //----------------station.System === 1 + const [eciMarkers, setEciMarkers] = useState([]); //--------------------station.System === 2 + const [gsmModemMarkers, setGsmModemMarkers] = useState([]); //----------station.System === 5 + const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]); //----station.System === 6 + const [wagoMarkers, setWagoMarkers] = useState([]); //------------------station.System === 7 + const [siemensMarkers, setSiemensMarkers] = useState([]); //------------station.System === 8 + const [otdrMarkers, setOtdrMarkers] = useState([]); //------------------station.System === 9 + const [wdmMarkers, setWdmMarkers] = useState([]); //--------------------station.System === 10 + const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 + const [messstellenMarkers, setMessstellenMarkers] = useState([]); //----station.System === 13 + const [talasiclMarkers, setTalasiclMarkers] = useState([]); //----------station.System === 100 + const [dauzMarkers, setDauzMarkers] = useState([]); //------------------station.System === 110 + const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]); //--station.System === 111 + const [sonstigeMarkers, setSonstigeMarkers] = useState([]); //----------station.System === 200 + const [ulafMarkers, setUlafMarkers] = useState([]); //------------------ no exist + //-------------------------------------------------------------------------------- + function determinePriority(iconPath) { + if (iconPath.includes("critical")) return 1; // Highest priority + if (iconPath.includes("major")) return 2; + if (iconPath.includes("minor")) return 3; + if (iconPath.includes("system")) return 4; + return 5; // Default priority (lowest) + } + // Daten von einer externen Quelle laden + const createAndSetMarkers = async (systemId, setMarkersFunction) => { + try { + const response1 = await fetch(config.mapGisStationsStaticDistrictUrl); + const jsonResponse = await response1.json(); + const response2 = await fetch(config.mapGisStationsStatusDistrictUrl); + const statusResponse = await response2.json(); + + if (jsonResponse.Points && statusResponse.Statis) { + const statisMap = new Map( + statusResponse.Statis.map((s) => [s.IdLD, s]) + ); + let markersData = jsonResponse.Points.filter( + (station) => station.System === systemId + ).map((station) => { + const statis = statisMap.get(station.IdLD); + const iconPath = statis + ? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png` + : `img/icons/marker-icon-${station.Icon}.png`; + + const priority = determinePriority(iconPath); + const zIndexOffset = 100 * (5 - priority); // Adjusted for simplicity and positive values + + /* console.log( + `Icon Path: ${iconPath}, Priority: ${priority}, zIndexOffset: ${zIndexOffset}` + ); */ + + const marker = L.marker([station.X, station.Y], { + icon: L.icon({ + iconUrl: iconPath, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + areaName: station.Area_Name, // Stelle sicher, dass dieser Bereich gesetzt wird + link: station.Link, + zIndexOffset: zIndexOffset, + bounceOnAdd: !!statis, + }); + + if (statis) { + marker.on("add", () => marker.bounce(3)); + } + + const statusInfo = statusResponse.Statis.filter( + (status) => status.IdLD === station.IdLD + ) + .reverse() + .map( + (status) => ` +
+
+ ${status.Me} (${status.Na}) +
+ ` + ) + .join(""); + + marker.bindPopup(` +
+

${station.LD_Name}

+

Gerät: ${station.Device}

+

Zone: ${station.Area_Short} (${station.Area_Name})

+

Standort: ${station.Location_Short} (${station.Location_Name})

+
${statusInfo}
+
+ `); + return marker; + }); + + setMarkersFunction(markersData); + } + } catch (error) { + console.error("Error fetching data: ", error); + } + }; + useEffect(() => { + if (!map) return; + createAndSetMarkers(1, setTalasMarkers); // TALAS-System + createAndSetMarkers(2, setEciMarkers); // ECI-System + createAndSetMarkers(5, setGsmModemMarkers); // GSM-Modem-System + createAndSetMarkers(6, setCiscoRouterMarkers); // Cisco-Router-System + createAndSetMarkers(7, setWagoMarkers); // WAGO-System + createAndSetMarkers(8, setSiemensMarkers); // Siemens-System + createAndSetMarkers(9, setOtdrMarkers); // OTDR-System + createAndSetMarkers(10, setWdmMarkers); // WDM-System + createAndSetMarkers(11, setGmaMarkers); // GMA-System + createAndSetMarkers(13, setMessstellenMarkers); // Messstellen-System + createAndSetMarkers(100, setTalasiclMarkers); // TALASICL-System + createAndSetMarkers(110, setDauzMarkers); // DAUZ-System + createAndSetMarkers(111, setSmsfunkmodemMarkers); // SMS-Funkmodem-System + createAndSetMarkers(200, setSonstigeMarkers); // Sonstige-System + createAndSetMarkers(0, setUlafMarkers); // ULAF-System + }, [map]); + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && talasMarkers.length) { + talasMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + //console.log("Talas marker:", marker._latlng.lat, marker._latlng.lng); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + /* //-------------- + const latitude = marker._latlng.lat; + const longitude = marker._latlng.lng; + const plusMarker = L.marker([latitude, longitude], { + icon: plusRoundIcon, + zIndexOffset: 1000, // Higher z-index for visibility + }); + + // Add to the poiLayer + plusMarker.addTo(poiLayerRef.current); + console.log("Adding plus icon marker at", [latitude, longitude]); + //------------ */ + addContextMenuToMarker(marker); + }); + map.addLayer(TALAS); + + // Call the function here + checkOverlappingMarkers(oms, map, plusRoundIcon); + } + }, [map, talasMarkers]); // Abhängigkeiten auf `map` und `talasMarkers` beschränken + + //console.log("talasMarkers", talasMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && eciMarkers.length) { + eciMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(ECI); + } + }, [map, eciMarkers]); + + //console.log("eciMarkers", eciMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && gsmModemMarkers.length) { + gsmModemMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GSMModem); + } + }, [map, gsmModemMarkers]); + + //console.log("gsmModemMarkers", gsmModemMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && ciscoRouterMarkers.length) { + ciscoRouterMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(CiscoRouter); + } + }, [map, ciscoRouterMarkers]); + + //console.log("ciscoRouterMarkers", ciscoRouterMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && wagoMarkers.length) { + wagoMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(WAGO); + + //toggleLayer(mapLayersVisibility.WAGO); + } + // }, [map, wagoMarkers, mapLayersVisibility.WAGO]); + }, [map, wagoMarkers]); + //console.log("wagoMarkers", wagoMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && siemensMarkers.length) { + siemensMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(Siemens); + } + }, [map, siemensMarkers]); + + //console.log("siemensMarkers", siemensMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && otdrMarkers.length) { + otdrMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(OTDR); + } + }, [map, otdrMarkers]); + + //console.log("otdrMarkers", otdrMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && wdmMarkers.length) { + wdmMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(WDM); + } + }, [map, wdmMarkers]); + + //console.log("wdmMarkers", wdmMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && gmaMarkers.length) { + // Filtern des Arrays um nur "GMA" Messungen zu erhalten + const gmaMeasurements = GisStationsMeasurements.filter( + (m) => m.Gr === "GMA" + ); + let area_name = ""; + let measurements = {}; + + gmaMeasurements.forEach((m) => { + //console.log(`Messung: ${m.Area_Name}, Na: ${m.Na}, Wert: ${m.Val}`); + area_name = m.Area_Name; // Dies überschreibt area_name mit dem letzten Area_Name im Array + measurements[m.Na] = m.Val; // Speichert den Wert von Val unter dem Code Na in einem Objekt + }); + + // Zugriff auf die Werte über die Codes + let measurementLT = measurements["LT"]; + let measurementFTP = measurements["FTP"]; + let measurementGT = measurements["GT"]; + let measurementRLF = measurements["RLF"]; + + /* console.log( + "area_name", + area_name, + "------measurementLT", + measurements.LT, + "-------measurementFBT", + measurements.FBT, + "------measurementGT", + measurements.GT, + "------measurementRLF", + measurements.RLF + ); + console.log("measurements", measurements); */ + gmaMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Tooltip beim Überfahren mit der Maus anzeigen + marker.bindTooltip( + ` +
+
+ ${area_name} +
+
+ LT : ${measurements.LT} °C +
+
+ FBT : ${measurements.FBT} °C +
+
+ GT : ${measurements.GT === "nicht ermittelbar" ? measurements.GT : `${measurements.GT} °C`} +
+
+ RLF : ${measurements.RLF} % +
+
+ `, + { + permanent: true, // Tooltip wird ständig angezeigt + direction: "auto", // Automatische Ausrichtung + offset: [20, 0], // Offset-Werte + } + ); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GMA); + } + }, [map, gmaMarkers]); // Abhängigkeiten auf `map` und `gmaMarkers` beschränken + + //console.log("gmaMarkers", gmaMarkers); + + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && messstellenMarkers.length) { + messstellenMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(GMA); + } + }, [map, messstellenMarkers]); + + //console.log("messstellenMarkers", messstellenMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && talasiclMarkers.length) { + talasiclMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + map.addLayer(TALASICL); + } + }, [map, talasiclMarkers]); + + //console.log("talasiclMarkers", talasiclMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && dauzMarkers.length) { + dauzMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, dauzMarkers]); + + //console.log("dauzMarkers", dauzMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && smsfunkmodemMarkers.length) { + smsfunkmodemMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, smsfunkmodemMarkers]); + + //console.log("smsfunkmodemMarkers", smsfunkmodemMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && ulafMarkers.length) { + ulafMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, ulafMarkers]); + + //console.log("ulafMarkers", ulafMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && sonstigeMarkers.length) { + sonstigeMarkers.forEach((marker) => { + marker.addTo(map); + oms.addMarker(marker); + + // Popup beim Überfahren mit der Maus öffnen und schließen + marker.on("mouseover", function () { + this.openPopup(); + }); + marker.on("mouseout", function () { + this.closePopup(); + }); + addContextMenuToMarker(marker); + }); + } + }, [map, sonstigeMarkers]); + + //console.log("sonstige", sonstigeMarkers); + //------------------------------------------- + //-------------------------------------------------------------------------------- + + const mapLayersVisibility = useRecoilValue(mapLayersState); + + /* useEffect(() => { + if (!map || !talasMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + talasMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + talasMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Apply visibility state to the TALAS layer + toggleLayer(mapLayersVisibility.TALAS); + }, [map, talasMarkers, mapLayersVisibility.TALAS]); */ // Depend on map, markers array, and visibility state + + const handleCheckboxChange = (name, event) => { + const { checked } = event.target; + const internalName = layerNames[name] || name; // Nutzt den internen Namen, wenn vorhanden, sonst den originalen Namen + + setMapLayersVisibility((prev) => { + return { + ...prev, + [internalName]: checked, + }; + }); + }; + + //------------------------------------------ + + // Funktion zum Ein- und Ausblenden der TALAS-Marker basierend auf dem Zustand von mapLayersVisibility.TALAS + + useEffect(() => { + if (!map || !talasMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + talasMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + talasMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Apply visibility state to the TALAS layer + toggleLayer(mapLayersVisibility.TALAS); + }, [map, talasMarkers, mapLayersVisibility.TALAS]); + + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der ECI-Marker basierend auf dem Zustand von mapLayersVisibility.ECI + + useEffect(() => { + if (!map || !eciMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + eciMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + eciMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility state to the ECI layer + toggleLayer(mapLayersVisibility.ECI); + }, [map, eciMarkers, mapLayersVisibility.ECI]); + + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der ULAF-Marker basierend auf dem Zustand von mapLayersVisibility.ULAF + + useEffect(() => { + if (!map || !ulafMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + ulafMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + ulafMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.ULAF); + }, [map, ulafMarkers, mapLayersVisibility.ULAF]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der GSMModem-Marker basierend auf dem Zustand von mapLayersVisibility.GSMModem + + useEffect(() => { + if (!map || !gsmModemMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + gsmModemMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + gsmModemMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.GSMModem); + }, [map, gsmModemMarkers, mapLayersVisibility.GSMModem]); + + //------------------------------------------ */ + const layerNames = { + "GSM Modem": "GSMMODEM", + "Cisco Router": "CiscoRouter", + "TALAS ICL": "TALASICL", + "SMS-Funkmodem": "GSMModem", + }; + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der CiscoRouter-Marker basierend auf dem Zustand von mapLayersVisibility.CiscoRouter + + useEffect(() => { + if (!map || !ciscoRouterMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + ciscoRouterMarkers.forEach((marker) => marker.addTo(map)); + } else { + ciscoRouterMarkers.forEach((marker) => map.removeLayer(marker)); + } + }; + // Nutzt die Map, um den internen Namen zu bekommen + const internalName = layerNames["Cisco Router"] || "CiscoRouter"; + toggleLayer(mapLayersVisibility[internalName]); + //console.log("internalName Cisco Router: ", internalName); + }, [map, ciscoRouterMarkers, mapLayersVisibility]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der WAGO-Marker basierend auf dem Zustand von mapLayersVisibility.WAGO + + useEffect(() => { + if (!map || !wagoMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + wagoMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + wagoMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.WAGO); + }, [map, wagoMarkers, mapLayersVisibility.WAGO]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der Siemens-Marker basierend auf dem Zustand von mapLayersVisibility.Siemens + + useEffect(() => { + if (!map || !siemensMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + siemensMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + siemensMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.Siemens); + }, [map, siemensMarkers, mapLayersVisibility.Siemens]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der OTDR-Marker basierend auf dem Zustand von mapLayersVisibility.OTDR + + useEffect(() => { + if (!map || !otdrMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + otdrMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + otdrMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.OTDR); + }, [map, otdrMarkers, mapLayersVisibility.OTDR]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der WDM-Marker basierend auf dem Zustand von mapLayersVisibility.WDM + + useEffect(() => { + if (!map || !wdmMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + wdmMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + wdmMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.WDM); + }, [map, wdmMarkers, mapLayersVisibility.WDM]); + + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der GMA-Marker basierend auf dem Zustand von mapLayersVisibility.GMA + + useEffect(() => { + if (!map || !gmaMarkers) return; + + const toggleLayer = (isVisible) => { + if (isVisible) { + gmaMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + gmaMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Apply visibility + toggleLayer(mapLayersVisibility.GMA); + }, [map, gmaMarkers, mapLayersVisibility.GMA]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der Sonstige-Marker basierend auf dem Zustand von mapLayersVisibility.Sonstige + + useEffect(() => { + if (!map || !sonstigeMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + sonstigeMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + sonstigeMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.Sonstige); + }, [map, sonstigeMarkers, mapLayersVisibility.Sonstige]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der TALASICL-Marker basierend auf dem Zustand von mapLayersVisibility.TALASICL + + useEffect(() => { + if (!map || !talasiclMarkers) return; + //console.log("talasiclMarkers", talasiclMarkers); + const toggleLayer = (isVisible) => { + if (isVisible) { + talasiclMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + talasiclMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + + // Verwendung der Map, um den internen Namen zu bekommen, und Fallback auf "TALASICL", falls nicht gefunden + const internalName = + layerNames["TALAS ICL"] || "TALASICL || talasiclMarkers "; + toggleLayer(mapLayersVisibility[internalName]); + //console.log("internalName for TALAS ICL in MapComponent: ", internalName); + }, [map, talasiclMarkers, mapLayersVisibility]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der DAUZ-Marker basierend auf dem Zustand von mapLayersVisibility.DAUZ + + useEffect(() => { + if (!map || !dauzMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + dauzMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + dauzMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.DAUZ); + }, [map, dauzMarkers, mapLayersVisibility.DAUZ]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der SMSFunkmodem-Marker basierend auf dem Zustand von mapLayersVisibility.SMSFunkmodem + + useEffect(() => { + if (!map || !smsfunkmodemMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + smsfunkmodemMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + smsfunkmodemMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.SMSFunkmodem); + }, [map, smsfunkmodemMarkers, mapLayersVisibility.SMSFunkmodem]); + + //------------------------------------------ */ + //------------------------------------------ */ + // Funktion zum Ein- und Ausblenden der Messstellen-Marker basierend auf dem Zustand von mapLayersVisibility.Messstellen + + useEffect(() => { + if (!map || !messstellenMarkers) return; + const toggleLayer = (isVisible) => { + if (isVisible) { + messstellenMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + } else { + messstellenMarkers.forEach((marker) => map.removeLayer(marker)); // Remove markers individually + } + }; + // Apply visibility + toggleLayer(mapLayersVisibility.Messstellen); + }, [map, messstellenMarkers, mapLayersVisibility.Messstellen]); + + //------------------------------------------ */ + const selectedArea = useRecoilValue(selectedAreaState); + + // Combine all markers into a single array + const allMarkers = [ + ...talasMarkers, + ...eciMarkers, + ...gsmModemMarkers, + ...ciscoRouterMarkers, + ...wagoMarkers, + ...siemensMarkers, + ...otdrMarkers, + ...wdmMarkers, + ...gmaMarkers, + ...messstellenMarkers, + ...talasiclMarkers, + ...dauzMarkers, + ...smsfunkmodemMarkers, + ...sonstigeMarkers, + ...ulafMarkers, + ]; + + // Function to find a marker by areaName across all groups + const findMyMarker = (areaName) => { + return allMarkers.find((marker) => marker.options.areaName === areaName); + }; + + // Effect to handle navigation to selected area + useEffect(() => { + if (selectedArea && map) { + const marker = findMyMarker(selectedArea); + if (marker) { + map.flyTo(marker.getLatLng(), 14); // Adjust zoom level as needed + } + } + }, [selectedArea, map, allMarkers]); // Include allMarkers in the dependencies + + /* const findMyMarker = (areaName) => { + // Angenommen, jeder Marker hat eine option `areaName`, die beim Erstellen gesetzt wurde. + return talasMarkers.find((marker) => marker.options.areaName === areaName); + }; */ + + //------------------------------------------ + + const zoomTrigger = useRecoilValue(zoomTriggerState); + + 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"); + } // Ihre bereits existierende Funktion, die Zoom-Out ausführt + } + }, [map, zoomTrigger]); + + //--------------------------------------------------------- + useEffect(() => { + console.log("Aktualisierung in MapComponent.js:", poiReadTrigger); + + // Logik zur Aktualisierung der Map hier hinzufügen + // Beispiel: Daten neu laden oder aktualisieren + }, [poiReadTrigger]); + //--------------------------------------------------------- + // Now update checkOverlappingMarkers to check if oms is initialized + function checkOverlappingMarkers(map, markers, plusIcon) { + // Ensure markers is always an array + if (!Array.isArray(markers)) { + //console.error("The `markers` argument is not an array:", markers); + return; + } + + const overlappingGroups = {}; + + // Group markers by coordinates as strings + markers.forEach((marker) => { + const latlngStr = marker.getLatLng().toString(); + if (overlappingGroups[latlngStr]) { + overlappingGroups[latlngStr].push(marker); + } else { + overlappingGroups[latlngStr] = [marker]; + } + }); + + // Add plus markers at coordinates where overlaps occur + for (const coords in overlappingGroups) { + if (overlappingGroups[coords].length > 1) { + const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number)); + const plusMarker = L.marker(latLng, { icon: plusIcon }); + plusMarker.addTo(map); + + //console.log("Adding plus icon marker at", latLng); + } + } + } + + //--------------------------------------------------------- + useEffect(() => { + if (map) { + // Combine all markers from different layers + const allMarkers = [ + ...talasMarkers, + ...eciMarkers, + ...gsmModemMarkers, + ...ciscoRouterMarkers, + ...wagoMarkers, + ...siemensMarkers, + ...otdrMarkers, + ...wdmMarkers, + ...gmaMarkers, + ...messstellenMarkers, + ...talasiclMarkers, + ...dauzMarkers, + ...smsfunkmodemMarkers, + ...sonstigeMarkers, + ...ulafMarkers, + ]; + + // Call the function to check for overlaps and add plus icons + checkOverlappingMarkers(map, allMarkers, plusRoundIcon); + } + }, [ + map, + talasMarkers, + eciMarkers, + gsmModemMarkers, + ciscoRouterMarkers, + wagoMarkers, + siemensMarkers, + otdrMarkers, + wdmMarkers, + gmaMarkers, + messstellenMarkers, + talasiclMarkers, + dauzMarkers, + smsfunkmodemMarkers, + sonstigeMarkers, + ulafMarkers, + ]); + + //--------------------------------------------------------- + + return ( + <> +
+ {/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */} + {showPopup && ( +
+
e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters + > + {/* Schließen-Button oben rechts */} + + + {/* Formular-Komponente zum Hinzufügen einer Station */} + +
+
+ )} +
+ + + +
+ + ); +}; + +export default MapComponent; diff --git a/components/MapComponent.js b/components/MapComponent.js index 01c0aa1f3..07637c539 100644 --- a/components/MapComponent.js +++ b/components/MapComponent.js @@ -344,6 +344,13 @@ const MapComponent = ({ locations, onLocationUpdate }) => { ? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png` : `img/icons/marker-icon-${station.Icon}.png`; + const priority = determinePriority(iconPath); + const zIndexOffset = 100 * (5 - priority); // Adjusted for simplicity and positive values + + /* console.log( + `Icon Path: ${iconPath}, Priority: ${priority}, zIndexOffset: ${zIndexOffset}` + ); */ + const marker = L.marker([station.X, station.Y], { icon: L.icon({ iconUrl: iconPath, @@ -351,17 +358,37 @@ const MapComponent = ({ locations, onLocationUpdate }) => { iconAnchor: [12, 41], popupAnchor: [1, -34], }), - areaName: station.Area_Name, + areaName: station.Area_Name, // Stelle sicher, dass dieser Bereich gesetzt wird link: station.Link, + zIndexOffset: zIndexOffset, bounceOnAdd: !!statis, }); + if (statis) { + marker.on("add", () => marker.bounce(3)); + } + + const statusInfo = statusResponse.Statis.filter( + (status) => status.IdLD === station.IdLD + ) + .reverse() + .map( + (status) => ` +
+
+ ${status.Me} (${status.Na}) +
+ ` + ) + .join(""); + marker.bindPopup(` -
+

${station.LD_Name}

Gerät: ${station.Device}

Zone: ${station.Area_Short} (${station.Area_Name})

Standort: ${station.Location_Short} (${station.Location_Name})

+
${statusInfo}
`); return marker;