From ff6620f98c47844b07081d6de46b781a634b3486 Mon Sep 17 00:00:00 2001 From: ISA Date: Wed, 26 Jun 2024 10:35:19 +0200 Subject: [PATCH] add MapComponent and lineColorsAPI after cherry pick. update lines and tooltip ok --- components/MapComponent.js | 2553 ++++++++++++++++++++++++++++++++++++ pages/api/linesColorApi.js | 53 + 2 files changed, 2606 insertions(+) create mode 100644 components/MapComponent.js create mode 100644 pages/api/linesColorApi.js diff --git a/components/MapComponent.js b/components/MapComponent.js new file mode 100644 index 000000000..a964d0a4e --- /dev/null +++ b/components/MapComponent.js @@ -0,0 +1,2553 @@ +// components/MapComponent.js + +import React, { + useEffect, + useRef, + useState, + useMemo, + useCallback, + use, +} from "react"; +import { MapContainer, TileLayer, Polyline, LayerGroup } from "react-leaflet"; + +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, useSetRecoilState } 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 { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline' +import PoiUpdateModal from "./PoiUpdateModal.js"; +import { selectedPoiState } from "../store/atoms/poiState.js"; +import { currentPoiState } from "../store/atoms/currentPoiState"; +import { ToastContainer, toast } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; +import { mapIdState, userIdState } from "../store/atoms/urlParameterState"; +import { set } from "lodash"; +import { poiLayerVisibleState } from "../store/atoms/poiLayerVisible"; +import { data } from "autoprefixer"; + +//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: [22, 22], + iconAnchor: [25, 55], + className: "absolute top-0 left-0 z-10", // Adjust with Tailwind CSS classes +}); +//--------------------------------------------------------------------- +//-------------------- MapComponent ----------------------------------- +const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { + const [priorityConfig, setPriorityConfig] = useState([]); + + const fetchPriorityConfig = async () => { + try { + const response = await fetch("/api/talas_v5_DB/priorityConfig"); + const data = await response.json(); + console.log("Prioritätskonfiguration:", data); + setPriorityConfig(data); + } catch (error) { + console.error("Fehler beim Laden der Prioritätskonfiguration:", error); + } + }; + + useEffect(() => { + fetchPriorityConfig(); + }, []); + + useEffect(() => { + console.log("Aktualisierte Prioritätskonfiguration:", priorityConfig); + }, [priorityConfig]); + //--------------------------------------------------------------------- + const fetchGisStatusStations = async (idMap, idUser) => { + try { + const response = await fetch( + `/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}` + ); + if (!response.ok) { + throw new Error(`Error: ${response.statusText}`); + } + const data = await response.json(); + console.log("GisStatusStations:", data); + return data; + } catch (error) { + console.error("Fehler beim Abrufen der Daten:", error); + } + }; + + useEffect(() => { + fetchGisStatusStations(12, 484); // Beispielaufruf mit idMap = 10 und idUser = 484 + }, []); + + //--------------------------------------------------------------------- + /* + path.includes("critical") || // Priorität 1 + path.includes("major") || // Priorität 2 + path.includes("minor") || // Priorität 3 + path.includes("system") // Priorität 4 + */ + /* const priorityColors = { + 1: "#ba0000", // High priority, red, critical + 2: "#ed7b00", // Medium priority orange major + 3: "#d1ca00", // priority minor senfgelb + 4: "#8602ab", // priority system Violett + // 5: "#298a00", // normal priority green + }; */ + const [menuItemAdded, setMenuItemAdded] = useState(false); + + const poiLayerVisible = useRecoilValue(poiLayerVisibleState); + + const [contextMenuItems, setContextMenuItems] = useState([]); + const [isRightsLoaded, setIsRightsLoaded] = useState(false); + const [hasRights, setHasRights] = useState(false); + const [mapId, setMapId] = useRecoilState(mapIdState); + const [userId, setUserId] = useRecoilState(userIdState); + + const [showAddStationPopup, setShowAddStationPopup] = useState(false); + const [userRights, setUserRights] = useState(null); + const setSelectedPoi = useSetRecoilState(selectedPoiState); + const openPoiUpdateModal = () => setShowPoiUpdateModal(true); + const closePoiUpdateModal = () => setShowPoiUpdateModal(false); + const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false); + const [currentPoiData, setCurrentPoiData] = useState(null); + const setCurrentPoi = useSetRecoilState(currentPoiState); + const currentPoi = useRecoilValue(currentPoiState); + const handlePoiSelect = (poiData) => { + setSelectedPoi(poiData); // poiData should be the data of the selected POI + // Open the modal or any other logic + }; + + useEffect(() => { + const params = new URL(window.location.href).searchParams; + setMapId(params.get("m")); + setUserId(params.get("u")); + }, [setMapId, setUserId]); + useEffect(() => { + fetchUserRights().then(() => { + setIsRightsLoaded(true); + }); + }, []); // Lade die Berechtigungen beim Initialisieren der Komponente + + const handleEditPoi = (marker) => { + // Prüfung, ob der Benutzer die notwendigen Rechte hat + if (!userRights || !userRights.includes(56)) { + toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", { + position: "top-center", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + console.log("Benutzer hat keine Berechtigung zum Bearbeiten."); + return; // Beendet die Funktion frühzeitig, wenn keine Berechtigung vorliegt + } + + //console.log("Selected Marker ID (idPoi):", marker.options.idPoi); + //console.log("Selected Marker Description:", marker.options.description); + + setCurrentPoiData({ + idPoi: marker.options.id, + name: marker.options.name, + description: marker.options.description, + }); + //console.log("POI-Daten1:", currentPoiData); + + fetchPoiData(marker.options.id); + + setShowPoiUpdateModal(true); + }; + + const fetchPoiData = async (idPoi) => { + const response = await fetch( + `/api/talas_v5_DB/pois/getPoiById?idPoi=${idPoi}` + ); + if (!response.ok) { + console.error("Fehler beim Abrufen der POI-Daten"); + return; + } + const data = await response.json(); + setCurrentPoiData({ + idPoi, + name: data.name, + description: data.description, + }); + //console.log("POI-Daten2:", currentPoiData); + setShowPoiUpdateModal(true); + }; + + const [showVersionInfoModal, setShowVersionInfoModal] = useState(false); + const zoomTrigger = useRecoilValue(zoomTriggerState); + const offlineTileLayer = "/mapTiles/{z}/{x}/{y}.png"; + //const onlineTileLayer = "/mapTiles/{z}/{x}/{y}.png"; + //const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; + const onlineTileLayer = "http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png"; //Talas_v5 Server + //const onlineTileLayer = "http://192.168.10.14:3000/mapTiles/{z}/{x}/{y}.png"; //Talas_v5 Server + // 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(); + const lineLayer = new L.LayerGroup(); + + const [gisSystemStaticLoaded, setGisSystemStaticLoaded] = useState(false); + + const baseUrl = "http://10.10.0.13/talas5/devices/"; // für Station öffnen in neuer tab und gleicher tab, im localhost gab es keine Probleme mit der Frame + //const baseUrl = "http://localhost:3000/talas5/devices/"; + //const baseUrl = "http://192.168.10.14/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:", userRights.includes(56)); + + //console.log("Neue Station:", stationData); + setShowAddStationPopup(false); + 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; + const webserviceGisLinesStatusUrl = config.webserviceGisLinesStatusUrl; + + const openVersionInfoModal = () => { + setShowVersionInfoModal(true); + }; + + const closeVersionInfoModal = () => { + setShowVersionInfoModal(false); + }; + // Funktion zum Aktualisieren der Position in der Datenbank + const updateLocationInDatabase = async (id, newLatitude, newLongitude) => { + const response = await fetch("/api/talas_v5_DB/pois/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"); + } + }; + //--------------------------------------------- + + //---------------------------------------------------- + //-----Kontextmenu---------------- + function addContextMenuToMarker(marker) { + marker.unbindContextMenu(); // Entferne das Kontextmenü, um Duplikate zu vermeiden + + 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) { + if (marker && marker.options && marker.options.link) { + //console.log("Marker data:", baseUrl + marker.options.link); + window.open(baseUrl + marker.options.link, "_blank"); + } else { + console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); + } + } + + // Funktion zum Öffnen im gleichen Fenster + function openInSameWindow(e, marker) { + if (marker && marker.options && marker.options.link) { + //console.log("Marker data:", baseUrl + marker.options.link); + window.location.href = baseUrl + marker.options.link; + } else { + console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft"); + } + } + + 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 "POI hinzufügen" + /* const addStationCallback = useCallback( + (event, hasRights) => { + console.log("Kontextmenü-Callback für 'POI hinzufügen' aufgerufen"); + console.log(event); + console.log("Benutzerrechte zum Zeitpunkt des Aufrufs:", hasRights); + + if (hasRights) { + setPopupCoordinates(event.latlng); + setShowPopup(true); + } else { + toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", { + position: "top-center", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + console.log("Benutzer hat keine Berechtigung zum Hinzufügen."); + } + }, + [hasRights, isRightsLoaded] + ); // Keine Abhängigkeiten, da `hasRights` als Parameter übergeben wird */ + const addStationCallback = useCallback( + (event) => { + //console.log("Benutzerrechte zum Zeitpunkt des Aufrufs:", hasRights); + if (hasRights) { + setPopupCoordinates(event.latlng); + setShowPopup(true); + } else { + toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", { + position: "top-center", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + console.error("Benutzer hat keine Berechtigung zum Hinzufügen."); + } + }, + [hasRights] + ); // Abhängigkeit zu hasRights hinzufügen + + //-----Kontextmenu----ende------------ + //-------------------------------------------------------------------------------- + + // Verwende useMemo, um die Kontextmenü-Items nur zu initialisieren, wenn notwendig + /* const contextMenuItems = useMemo( + () => [ + { + text: "Station öffnen (Tab)", + icon: "/img/screen_new.png", + callback: (e) => { + const clickedMarker = e.relatedTarget; // Zugriff auf den Marker, der das Event ausgelöst hat + openInNewTab(e, clickedMarker); + }, + }, + { + text: "Station öffnen", + icon: "/img/screen_same.png", + //callback: (e) => openInSameWindow(e, marker), + callback: (e) => { + const clickedMarker = e.relatedTarget; // Zugriff auf den Marker, der das Event ausgelöst hat + openInSameWindow(e, clickedMarker); + }, + }, + "-", // Divider + { + text: "POI hinzufügen", + icon: "img/add_station.png", + className: "background-red", + callback: (event) => addStationCallback(event, hasRights), + }, + + { + text: "Koordinaten anzeigen", + 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, + }, + ], + [hasRights] + ); */ + /* useEffect(() => { + if (hasRights) { + setContextMenuItems([ + { + text: "POI hinzufügen test", + icon: "img/add_station.png", + className: "background-red", + callback: (event) => addStationCallback(event), + }, + // Weitere Menüpunkte... + ]); + } + }, [isRightsLoaded, hasRights]); + */ + //---------------------------------------------------------------------------------- + //------------------------------------------ */ + const layerNames = { + "GSM Modem": "GSMMODEM", + "Cisco Router": "CiscoRouter", + "TALAS ICL": "TALASICL", + "SMS-Funkmodem": "GSMModem", + }; + //------------------------------------------ */ + function fly(stationValue) { + var x = 51.41321407879154; + var y = 7.739617925303934; + var zoom = 7; + + initMap.flyTo([x, y], zoom); + } + //------------------------------------------ + //------------------------------------------ + // 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 = []; + //------------------------------------------ + //------------------------------------------ + 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 + } + } + //---------------------------------- + //------------------------------------------ + + 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 + //-------------------------------------------------------------------------------- + const determinePriority = (iconPath) => { + for (let priority of priorityConfig) { + if (iconPath.includes(priority.name.toLowerCase())) { + return priority.level; + } + } + return 5; // Default priority (lowest) + }; + /* function determinePriority(iconPath) { + if (iconPath.includes("critical")) return 1; // Highest priority + if (iconPath.includes("critical")) { + console.log( + "iconPath.includes('critical'):", + iconPath.includes("critical") + ); + } + + if (iconPath.includes("major")) return 2; + if (iconPath.includes("minor")) { + console.log("iconPath.includes('minor'):", iconPath.includes("minor")); + } + if (iconPath.includes("minor")) return 3; + if (iconPath.includes("system")) { + console.log("iconPath.includes('system'):", iconPath.includes("system")); + } + if (iconPath.includes("system")) return 4; + if (iconPath.includes("system")) { + console.log("iconPath.includes('system'):", iconPath.includes("system")); + } + 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 getIdSystemAndAllowValueMap = new Map( + GisSystemStatic.map((system) => [system.IdSystem, system.Allow]) + ); + //console.log("getIdSystemAndAllowValueMap:", getIdSystemAndAllowValueMap); + + 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 && + getIdSystemAndAllowValueMap.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 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} + ${station.Device}
+ ${station.Area_Short} (${station.Area_Name})
+ ${station.Location_Short} (${station.Location_Name}) +
${statusInfo}
+
+ `); + return marker; + }); + + setMarkersFunction(markersData); + } + } catch (error) { + console.error("Error fetching data: ", error); + } + }; + //-------------------------------------------------------------------------------- + + const mapLayersVisibility = useRecoilValue(mapLayersState); + /* + 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, + }; + }); + }; */ + + //------------------------------------------ + //------------------------------------------ */ + 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); + }; + //-------------------------------------------------------------- + //--------------------------------------------------------- + // 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); + } + } + } + //--------------------------------------------------------- + const handleMarkerClick = (markerData) => { + // Setze die aktuellen Daten im State, um sie im Formular vorzubelegen + setCurrentMarkerData(markerData); + setShowEditModal(true); + }; + // In der Marker-Erstellungsfunktion + //--------------------------------------------------------- + //----------------------------------------------------------- + // Funktion um die Benutzerrechte zu überprüfen + // serverIP 10.10.0.13 idMap=10 idUser=485 + //const serverURL = "http://10.10.0.13"; + + const url = new URL(window.location.href); + const hostname = url.hostname; // Gibt den Hostnamen (IP oder Domain) zurück + const port = url.port; // Gibt den Port zurück, leer wenn Standardport verwendet wird + const protocol = url.protocol; // "http:" oder "https:" + //const serverURL = `${protocol}//${hostname}`; + const serverURL = "http://10.10.0.13"; // weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte + //const serverURL = "http://localhost:3000"; // weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte + + const params = new URL(window.location.href).searchParams; + //const serverURL = `${protocol}//${hostname}${port ? `:${port}` : ""}`; + + const c = params.get("m"); // Beispielwert für idMap + const user = params.get("u"); // Beispielwert für idUser + //console.log("serverURL:", serverURL); + const fetchUserRights = async () => { + try { + const response = await fetch( + `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}` + //`${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${c}&idUser=${user}` //Berechtigung zum hinzufügen von POIs in der Karte + //`${serverURL}/api/rights?idMap=${c}&idUser=${user}` + ); + const data = await response.json(); + //console.log("Benutzerrechte:", data); + const rightsArray = data.Rights; // Nehmen an, dass 'Rights' das Array von Rechten ist + + // Speichert die IDs der Rechte in einem Array + const userRightsIds = rightsArray.map((right) => right.IdRight); + setUserRights(userRightsIds); // Speichert die Rechte in den Zustand + + //console.log("Benutzerrechte:", rightsArray); + //console.log("Benutzerrechte IDs:", userRightsIds); + //console.log("Benutzerrechte in if :", userRightsIds.includes(56)); + setHasRights(userRightsIds.includes(56)); + } catch (error) { + console.error("Fehler beim Abrufen der Benutzerrechte", error); + } + }; + useEffect(() => { + //console.log("Aktualisierter Status von hasRights: ", hasRights); + }, [hasRights]); // Dieser Effekt läuft jedes Mal, wenn sich `hasRights` ändert. + + // Überprüfen der Benutzerrechte beim Initialisieren der Komponente + useEffect(() => { + fetchUserRights(); + }, []); + + // Anzeigen von Modals basierend auf Benutzerrechten + useEffect(() => { + if (userRights !== 56) { + setShowPoiUpdateModal(false); + setShowAddStationPopup(false); + } + }, [userRights]); + //----------------------------------------------------------- + //--------------------------------------------------------- + useEffect(() => { + //console.log("useEffect current Data:", currentPoiData); + }, [currentPoiData]); + //--------------------------------------------------------- + //------------------------------------------ + // 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(); + + if (jsonResponse && jsonResponse.Systems) { + setGisSystemStatic(jsonResponse.Systems); + setGisSystemStaticLoaded(true); // Setze den Zustand auf geladen + } 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(); + }, []); + //------------------------------------------ + + useEffect(() => { + if (typeof window !== "undefined") { + //console.log("Window height from config:", config.windowHeight); + } + }, []); + + // 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 öffnen (Tab)", + icon: "/img/screen_new.png", + callback: (e) => { + const clickedMarker = e.relatedTarget; // Zugriff auf den Marker, der das Event ausgelöst hat + openInNewTab(e, clickedMarker); + }, + }, + "-", // Divider + + { + text: "Koordinaten anzeigen", + 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, + }, + "-", // Divider + ], + }); + + 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, contextMenuItems]); // Prüfe die Abhängigkeiten sorgfältig + + // poiTyp Daten hinzufügen + //------------------------------------------ + // Funktion zum Abrufen der poiTyp Daten + + useEffect(() => { + const fetchPoiTypData = async () => { + try { + const response = await fetch("/api/talas_v5_DB/poiTyp/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]); + + //--------------------------------------- + + // 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/talas_v5_DB/poiTyp/readPoiTyp"); + const data = await response.json(); + const map = new Map(); + data.forEach((item) => map.set(item.idPoiTyp, item.name)); + setPoiTypMap(map); + 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 + //------------------------------------------ + function editPoi(marker) { + // Zugriff auf die Markerdaten + const markerId = marker.options.id; + //console.log("Bearbeiten des POI mit ID:", markerId); + + // Hier könnte ein Modal mit Formular geöffnet werden + // Beispiel: openEditModal(markerId); + } + + //------------------------------------------ + + const fetchDeviceNameById = async (idLD) => { + try { + const response = await fetch( + `/api/talas_v5_DB/locationDevice/locationDeviceNameById?idLD=${idLD}` + ); + const data = await response.json(); + if (response.ok) { + return data.name; + } else { + throw new Error(data.error || "Gerät nicht gefunden"); + } + } catch (error) { + console.error( + "Fehler beim Abrufen des Gerätenamens in MapComponent.js:", + error + ); + return "Unbekannt"; + } + }; + //-------------------------------------------------- + /* useEffect(() => { + fetchUserRights().then(() => { + setIsRightsLoaded(true); // Stellen Sie sicher, dass Sie diesen Status verwenden, um die Initialisierung zu kontrollieren. + }); +}, []); */ + + /* useEffect(() => { + if (map && !map.contextmenu) { + map.contextmenu = new L.Control.ContextMenu({ + contextmenu: true, + contextmenuWidth: 140, + contextmenuItems: [], // Starten mit einem leeren Array oder initialen Einträgen + }).addTo(map); + } + }, [map]); */ + + const addItemsToMapContextMenu = () => { + if (!menuItemAdded) { + //console.log("contextMenuItems hasRights:", hasRights); + + map.contextmenu.addItem({ + text: "POI hinzufügen", + icon: "img/add_station.png", + className: "background-red", + callback: (event) => addStationCallback(event, hasRights), + }); + + setMenuItemAdded(true); // Menüpunkt wurde hinzugefült, Zustand aktualisieren + } + }; + + useEffect(() => { + if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded) { + addItemsToMapContextMenu(); + } + }, [ + map, + poiLayerRef, + isPoiTypLoaded, + menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern + ]); + //------------------------------------------ + + // poiLayerRef(poiDbLayer) POI hinzufügen + //-------------------------------------------- + const [poiData, setPoiData] = useState([]); + + useEffect(() => { + const fetchPoiData = async () => { + try { + const response = await fetch("/api/talas_v5_DB/pois/poi-icons"); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + setPoiData(data); + //console.log("poiData data:", data); + //console.log("poiData icons:", poiData); + } catch (error) { + console.error("Fehler beim Abrufen der poiData:", error); + } + }; + + fetchPoiData(); + }, []); + //-------------------------------------------- + useEffect(() => { + if (poiData.length === 0) return; + + try { + if (map && poiLayerRef.current && isPoiTypLoaded) { + map.removeLayer(poiLayerRef.current); + poiLayerRef.current = new L.LayerGroup().addTo(map); + + locations.forEach(async (location) => { + try { + const { latitude, longitude } = parsePoint(location.position); + const poiTypName = poiTypMap.get(location.idPoiTyp) || "Unbekannt"; + const deviceName = await fetchDeviceNameById(location.idLD); + //console.log("deviceName:", deviceName); // Das ist in Modal POI hinzufügen + + const canDrag = userRights ? userRights.includes(56) : false; + const matchingIcon = poiData.find( + (poi) => poi.idPoi === location.idPoi + ); + const iconUrl = matchingIcon + ? `/img/icons/pois/${matchingIcon.path}` + : "/img/icons/pois/default-icon.png"; + + const marker = L.marker([latitude, longitude], { + icon: L.icon({ + iconUrl: iconUrl, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + }), + draggable: canDrag, + id: location.idPoi, + }).bindContextMenu({ + contextmenu: true, + contextmenuWidth: 140, + contextmenuItems: [ + { + text: "POI Bearbeiten", + icon: "/img/poi-edit.png", + callback: () => handleEditPoi(marker), + }, + ], + }); + + marker.bindPopup(` +
+ ${location.description || "Unbekannt"}
+ ${deviceName}
+ ${poiTypName}
+
+ `); + + marker.on("mouseover", function () { + this.openPopup(); + handlePoiSelect({ + id: location.idPoi, + deviceId: location.idLD, + typ: poiTypName, + description: location.description, + }); + setCurrentPoi(location); + }); + + marker.on("mouseout", function () { + this.closePopup(); + }); + + marker.on("dragend", (e) => { + if (canDrag) { + 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); + }); + } else { + console.error("Drag operation not allowed"); + } + }); + + if (poiLayerVisible) { + marker.addTo(poiLayerRef.current); + } + } catch (innerError) { + console.error("Error processing a location:", innerError); + } + }); + } + } catch (error) { + console.error("Error in useEffect:", error); + } + }, [ + map, + locations, + onLocationUpdate, + poiReadTrigger, + isPoiTypLoaded, + userRights, + poiLayerVisible, + poiData, // Add poiData as a dependency + ]); + + //--------------------------------------------- + + //------------------------------------------------------------------------------- + useEffect(() => { + if (gisSystemStaticLoaded && map) { + 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 + } + }, [gisSystemStaticLoaded, map]); + //-------------------------------------------------------------------------------- + useEffect(() => { + if (map && talasMarkers.length) { + talasMarkers.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(TALAS); + //console.log("map", map); + //console.log("oms", oms); + //disable map contextmenu + map.options.contextmenu = false; + map.options.contextmenuItems = []; + + oms.map.options.contextmenu = false; + oms.map.options.contextmenuItems = []; + + // Call the function here + checkOverlappingMarkers(oms, map, plusRoundIcon); + } + }, [map, talasMarkers]); // Abhängigkeiten auf `map` und `talasMarkers` beschränken + + //------------------------------------------- + //-------------------------------------------------------------------------------- + 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); + //------------------------------------------- + + // Funktion zum Ein- und Ausblenden der TALAS-Marker basierend auf dem Zustand von mapLayersVisibility.TALAS + + useEffect(() => { + if (!map || !talasMarkers) return; + /* const someLineCoordinatesforTalas = [ + [53.111111, 8.4625], + [53.111111, 8.4625], + [53.111111, 8.4625], + [53.111111, 8.4625], + ]; */ + const toggleLayer = (isVisible) => { + if (isVisible) { + talasMarkers.forEach((marker) => marker.addTo(map)); // Ensure markers are added + //console.log("talasMarkers", talasMarkers); + //console.log("talasMarkers.color", talasMarkers.color); + //talasMarkers.forEach((marker) => map.removeLayer(marker)); + /* console.log("talasMarkers linePositions ", linePositions); + const polyline = L.polyline(someLineCoordinatesforTalas, { + color: "green", + }).addTo( + //Linien-Farbe /Farbe für die Strecke zwischen den Markern + TALAS + ); */ + } 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]); + + //------------------------------------------ */ + + // 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]); + + //------------------------------------------ */ + + // 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 + + //------------------------------------------ + + 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]); */ + //--------------------------------------------------------- + + //--------------------------------------------------------- + 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, + ]); + //--------------------------------------------------------- + //LINESTRING (53.151257 8.190471,53.161601 8.129359,53.19802 8.092366,53.244065 8.014003,53.252539 7.954265) + const [linePositions, setLinePositions] = useState([]); + // ------------Linien zeichnen---------------- + useEffect(() => { + const endpoint = "/api/talas_v5_DB/gisLines/readGisLines"; + fetch(endpoint) + .then((response) => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + const newLinePositions = data.map((item) => { + if (item.points && Array.isArray(item.points)) { + return { + coordinates: item.points.map((point) => [point.x, point.y]), + idModul: item.idModul, + idLD: item.idLD, + }; + } else { + throw new Error("Points missing or not an array"); + } + }); + setLinePositions(newLinePositions); + }) + .catch((error) => { + console.error("Error fetching data:", error.message); + }); + }, []); + //--------------------------- Linien färben ------------------------------ + const [lineColors, setLineColors] = useState({}); + const [tooltipContents, setTooltipContents] = useState({}); + const [polylines, setPolylines] = useState([]); + const [markers, setMarkers] = useState([]); + + // API-Aufruf, um Farben der Linien abzurufen + + useEffect(() => { + const fetchData = async () => { + try { + const response1 = await fetch(webserviceGisLinesStatusUrl); + const data1 = await response1.json(); + const response2 = await fetch("/api/talas_v5_DB/gisLines/readGisLines"); + const data2 = await response2.json(); + + const colorsByModule = {}; + const newTooltipContents = {}; + + data1.Statis.forEach((stat) => { + const matchingLine = data2.find( + (item) => item.idLD === stat.IdLD && item.idModul === stat.Modul + ); + if (matchingLine) { + colorsByModule[matchingLine.idModul] = stat.PrioColor; + newTooltipContents[matchingLine.idModul] = ` +
+ ${stat.ModulName || "Unknown"}
+ + ModulName : ${stat.ModulTyp || "N/A"} +
+ + + + ${stat.Message || "N/A"} + + + + (${stat.PrioName || "N/A"}) +
+
+ + `; + } + }); + + setLineColors(colorsByModule); + setTooltipContents(newTooltipContents); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + fetchData(); + }, []); + + // Überwachen des lineColors Zustandes + useEffect(() => { + //console.log("Aktualisierte lineColors", lineColors); + }, [lineColors]); + + //--------------------------------------------------------- + // Custom circle icon for draggable markers + const circleIcon = L.divIcon({ + className: "custom-div-icon", + html: "
", + iconSize: [25, 25], + iconAnchor: [5, 5], + }); + //----------------------- Update lines---------------------------------- + const [lineStatusData, setLineStatusData] = useState([]); + const [linesData, setLinesData] = useState([]); + + useEffect(() => { + const fetchData = async () => { + try { + const response1 = await fetch(webserviceGisLinesStatusUrl); + const data1 = await response1.json(); + setLineStatusData(data1.Statis); + + const response2 = await fetch("/api/talas_v5_DB/gisLines/readGisLines"); + const data2 = await response2.json(); + + const colorsByModule = {}; + data1.Statis.forEach((stat) => { + const matchingLine = data2.find( + (item) => item.idLD === stat.IdLD && item.idModul === stat.Modul + ); + if (matchingLine) { + colorsByModule[matchingLine.idModul] = stat.PrioColor; + console.log("Übereinstimmung gefunden für: ", stat); + setLinesData(matchingLine); + } + }); + + setLineColors(colorsByModule); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + fetchData(); + }, []); + //--------------------------------------------------------- + useEffect(() => { + console.log("lineStatusData", lineStatusData); + console.log("lineData:", linesData); + }, [lineStatusData, linesData]); + //--------------------------------------------------------- + // Function to initialize markers and polylines + // Initialisieren eines Zustands für die Speicherung der Polyline-Objekte + useEffect(() => { + if (!map) return; + + // Entfernen alter Marker und Polylines + markers.forEach((marker) => marker.remove()); + polylines.forEach((polyline) => polyline.remove()); + + const newMarkers = []; + const newPolylines = []; + + linePositions.forEach((lineData, lineIndex) => { + const lineMarkers = []; + lineData.coordinates.forEach((coord, index) => { + const marker = L.marker(coord, { + icon: circleIcon, + draggable: true, + }).addTo(map); + + marker.on("dragend", () => { + const newCoords = marker.getLatLng(); + const newCoordinates = [...lineData.coordinates]; + newCoordinates[index] = [newCoords.lat, newCoords.lng]; + const updatedPolyline = L.polyline(newCoordinates, { + color: lineColors[lineData.idModul] || "#000000", + }).addTo(map); + + updatedPolyline.bindTooltip( + tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", + { + permanent: false, + direction: "auto", + } + ); + + updatedPolyline.on("mouseover", () => { + updatedPolyline.setStyle({ weight: 10 }); + updatedPolyline.bringToFront(); + }); + updatedPolyline.on("mouseout", () => { + updatedPolyline.setStyle({ weight: 5 }); + }); + + newPolylines[lineIndex].remove(); + newPolylines[lineIndex] = updatedPolyline; + lineData.coordinates = newCoordinates; + + const requestData = { + idModul: lineData.idModul, + idLD: lineData.idLD, + newCoordinates, + }; + + console.log("Sending to API:", requestData); + // API-Aufruf, um die neuen Koordinaten zu speichern + fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(requestData), + }) + .then((response) => { + if (!response.ok) { + return response.json().then((data) => { + throw new Error(data.error || "Unbekannter Fehler"); + }); + } + return response.json(); + }) + .then((data) => { + console.log("Koordinaten erfolgreich aktualisiert:", data); + }) + .catch((error) => { + console.error( + "Fehler beim Aktualisieren der Koordinaten:", + error.message + ); + }); + }); + + lineMarkers.push(marker); + }); + + const polyline = L.polyline(lineData.coordinates, { + color: lineColors[lineData.idModul] || "#000000", + }).addTo(map); + + polyline.bindTooltip( + tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt", + { + permanent: false, + direction: "auto", + } + ); + + polyline.on("mouseover", () => { + polyline.setStyle({ weight: 10 }); + polyline.bringToFront(); + console.log( + `polyline with idLD : ${lineData.idLD}, idModul: ${lineData.idModul}`, + "lineData : ", + lineData + ); + }); + polyline.on("mouseout", () => { + polyline.setStyle({ weight: 5 }); + }); + + newPolylines.push(polyline); + newMarkers.push(...lineMarkers); + }); + + setMarkers(newMarkers); + setPolylines(newPolylines); + }, [map, linePositions, lineColors, tooltipContents]); + + //--------------------------------------------------------- + //--------------------------------------------------------- + + return ( + <> + +
+ {/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */} + {showPoiUpdateModal && ( +
+
e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters + > + {/* Schließen-Button oben rechts */} + + + {/* Formular-Komponente zum Hinzufügen einer Station */} + setShowPoiUpdateModal(false)} + poiData={currentPoiData} + onSubmit={handleAddStation} + latlng={popupCoordinates} + /> +
+
+ )} +
+ + {/* Rest of your component */} +
+ {/* 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 */} + +
+
+ )} +
+ + + +
+ +
+
+
+ + {" "} + TALAS.Map{" "} + + +
+ Version 1.0.0 +
+
+ +
+
+
+ {showVersionInfoModal && ( +
+
+
+ TALAS V5 Logo +
+

+ Littwin Systemtechnik GmbH & Co. KG +

+

+ Bürgermeister-Brötje Str. 28 +

+

+ D-26180 Rastede +

+
+ T: +49 4402 9725 77-0 +
+
+ E: kontakt@littwin-systemtechnik.de +
+
+

+ TALAS.Map Version 1.0.0 +

+ +
+
+ )} + + ); +}; + +export default MapComponent; diff --git a/pages/api/linesColorApi.js b/pages/api/linesColorApi.js new file mode 100644 index 000000000..353c8527a --- /dev/null +++ b/pages/api/linesColorApi.js @@ -0,0 +1,53 @@ +// /pages/api/linesColorApi.js +// http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStatusDistrict +//In DB gis_lines idLD und idModul anpassen entsprechend + +export default function handler(req, res) { + const response = { + Name: "Liste aller Statis der Linien", + Zeitstempel: new Date().toISOString(), // Aktuellen Zeitstempel hinzufügen + IdMap: "10", + Statis: [ + { + IdLD: 50922, + Modul: 1, + DpName: "KUE01_Ausfall", + ModulName: "42 Wippershain Sender", + // ModulTyp: "nicht vorhanden", + ModulTyp: "KÜ705-FO", + Message: "KUEG 01: 42 Wippershain Sender Messwerkausfall kommend", + Level: 4, + PrioColor: "#FFFF00", + PrioName: "system", + Value: "?", + }, + { + IdLD: 25440, + Modul: 3, + DpName: "KUE03_Ausfall", + ModulName: "42 Solz Sender", + //ModulTyp: "nicht vorhanden", + ModulTyp: "KÜSS V2", + Message: "KUEG 03: 42 Solz Sender Messwerkausfall kommend", + Level: 4, + PrioColor: "#FF0000", + PrioName: "system", + Value: "?", + }, + { + IdLD: 25440, + Modul: 4, + DpName: "KUE04_Ausfall", + ModulName: "42/13 Bad Hersfeld Gaswerk", + ModulTyp: "Kue705-FO", + Message: "KUEG 04: 42/13 Bad Hersfeld Gaswerk Messwerkausfall kommend", + Level: 4, + PrioColor: "#FF00FF", + PrioName: "system", + Value: "?", + }, + ], + }; + + res.status(200).json(response); +}