Files
nodeMap/components/MapComponent.js
ISA 820b908873 feat: Implement dynamic line coloring based on module IDs
Enhanced the map visualization by implementing dynamic line coloring, assigning unique colors to polyline elements based on their corresponding module IDs. This update fetches color settings from the linesColorAPI and applies them to the line drawings on the map. The change aims to improve the visual distinction between different lines, facilitating easier identification and analysis for users.
2024-06-13 14:01:14 +02:00

2346 lines
82 KiB
JavaScript

// components/MapComponent.js
import React, {
useEffect,
useRef,
useState,
useMemo,
useCallback,
} 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 { 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
});
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
/*
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/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
// 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/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 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/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);
}
function getIconPath(status, iconNumber, marker) {
let path = status
? `img/icons/${status}-marker-icon-${iconNumber}.png`
: `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;
}
//------------------------------------------
// 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
//--------------------------------------------------------------------------------
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) => `
<div class="flex items-center my-1">
<div class="w-2 h-2 mr-2 inline-block rounded-full" style="background-color: ${status.Co};"></div>
${status.Me}&nbsp;<span style="color: ${status.Co};">(${status.Na})</span>
</div>
`
)
.join("");
marker.bindPopup(`
<div class=" bg-white rounded-lg ">
<p class="text-lg font-semibold text-gray-900">${station.LD_Name}</p>
<span class="text-md font-bold text-gray-800"> ${station.Device}</span><br>
<span class="text-gray-800"><strong> ${station.Area_Short} </strong>(${station.Area_Name})</span><br>
<span class="text-gray-800"><strong>${station.Location_Short} </strong> (${station.Location_Name})</span>
<div class="mt-2">${statusInfo}</div>
</div>
`);
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";
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/rights?idMap=${c}&idUser=${user}`
);
const data = await response.json();
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);
},
},
{
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: "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:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> 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/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/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/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:", 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 () => {
const response = await fetch("/api/poi-icons");
const data = await response.json();
setPoiData(data);
//console.log("poiData icons:", data);
};
fetchPoiData();
}, []);
useEffect(() => {
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);
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(`
<div>
<b class="text-xl text-black-700">${location.description || "Unbekannt"}</b><br>
${deviceName}<br>
${poiTypName}<br>
</div>
`);
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,
]);
//---------------------------------------------
//-------------------------------------------------------------------------------
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(
`
<div class="p-0 rounded-lg bg-white bg-opacity-90">
<div class="font-bold text-sm text-black">
<span>${area_name}</span>
</div>
<div class="font-bold text-xxs text-blue-700">
<span>LT : ${measurements.LT} °C</span>
</div>
<div class="font-bold text-xxs text-red-700">
<span>FBT : ${measurements.FBT} °C</span>
</div>
<div class="font-bold text-xxs text-yellow-500">
<span>GT : ${measurements.GT === "nicht ermittelbar" ? measurements.GT : `${measurements.GT} °C`}</span>
</div>
<div class="font-bold text-xxs text-green-700">
<span>RLF : ${measurements.RLF} %</span>
</div>
</div>
`,
{
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 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));
/* const polyline = L.polyline(linePositions, { color: lineColor }).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 [lineColors, setLineColors] = useState({});
// API-Aufruf, um Farben der Linien abzurufen
useEffect(() => {
const fetchLinesColor = async () => {
try {
const response = await fetch("/api/linesColorApi");
const data = await response.json();
const colorsByModule = {};
data.linesColor.Statis.forEach((item) => {
colorsByModule[item.IdModul] = item.Co;
});
setLineColors(colorsByModule);
} catch (error) {
console.error("Fehler beim Abrufen der linesColorApi Daten:", error);
}
};
fetchLinesColor();
}, []);
// Überwachen des lineColors Zustandes
useEffect(() => {
console.log("Aktualisierte lineColors", lineColors);
}, [lineColors]);
const [linePositions, setLinePositions] = useState([]);
useEffect(() => {
const endpoint = "/api/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,
};
} else {
throw new Error("Points missing or not an array");
}
});
setLinePositions(newLinePositions);
})
.catch((error) => {
console.error("Error fetching data:", error.message);
});
}, []);
// Karte-Linien Zeichnen
useEffect(() => {
if (!map) return;
linePositions.forEach((lineData) => {
if (lineData.coordinates.length > 0) {
const color = lineColors[lineData.idModul] || "#000000"; // Standardfarbe schwarz, wenn keine Farbe gefunden
const polyline = L.polyline(lineData.coordinates, { color }).addTo(map);
L.circleMarker(lineData.coordinates[0], {
radius: 5,
fillColor: "#0000FF",
color: "#0000FF",
weight: 1,
opacity: 1,
fillOpacity: 0.8,
}).addTo(map);
L.circleMarker(lineData.coordinates[lineData.coordinates.length - 1], {
radius: 5,
fillColor: "#0000FF",
color: "#0000FF",
weight: 1,
opacity: 1,
fillOpacity: 0.8,
}).addTo(map);
for (let i = 1; i < lineData.coordinates.length - 1; i++) {
L.circleMarker(lineData.coordinates[i], {
radius: 3,
fillColor: "#FFFF00",
color: "#FFFF00",
weight: 1,
opacity: 1,
fillOpacity: 0.8,
}).addTo(map);
}
}
});
}, [map, linePositions, lineColors]);
//---------------------------------------------------------
return (
<>
<ToastContainer />
<div>
{/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */}
{showPoiUpdateModal && (
<div
className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]"
onClick={closePoiUpdateModal} // Schließt das Popup bei einem Klick außerhalb
>
<div
className="relative bg-white p-6 rounded-lg shadow-lg"
onClick={(e) => e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters
>
{/* Schließen-Button oben rechts */}
<button
onClick={closePoiUpdateModal}
className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600"
aria-label="Close"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
{/* Formular-Komponente zum Hinzufügen einer Station */}
<PoiUpdateModal
onClose={() => setShowPoiUpdateModal(false)}
poiData={currentPoiData}
onSubmit={handleAddStation}
latlng={popupCoordinates}
/>
</div>
</div>
)}
</div>
{/* Rest of your component */}
<div>
{/* Zeigt das Popup-Fenster nur, wenn `showPopup` wahr ist */}
{showPopup && (
<div
className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]"
onClick={closePopup} // Schließt das Popup bei einem Klick außerhalb
>
<div
className="relative bg-white p-6 rounded-lg shadow-lg"
onClick={(e) => e.stopPropagation()} // Verhindert das Schließen innerhalb des Fensters
>
{/* Schließen-Button oben rechts */}
<button
onClick={closePopup}
className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600"
aria-label="Close"
>
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
{/* Formular-Komponente zum Hinzufügen einer Station */}
<ShowAddStationPopup
onClose={closePopup}
onSubmit={handleAddStation}
latlng={popupCoordinates}
/>
</div>
</div>
)}
</div>
<DataSheet className="z-50" />
<div
id="map"
ref={mapRef}
className="z-0"
style={{ height: "100vh", width: "100vw" }}
></div>
<div className="absolute bottom-3 left-3 w-72 p-4 bg-white rounded-lg shadow-md z-50">
<div className="flex justify-between items-center">
<div>
<span className="text-black text-lg font-semibold">
{" "}
TALAS.Map{" "}
</span>
<br />
<span className="text-black text-lg">Version 1.0.0</span>
</div>
<div>
<button onClick={openVersionInfoModal}>
<InformationCircleIcon
className="text-blue-900 h-8 w-8 pr-1"
title="Weitere Infos"
/>
</button>
</div>
</div>
</div>
{showVersionInfoModal && (
<div className="fixed inset-0 flex items-center justify-center z-50">
<div
className="fixed inset-0 bg-black bg-opacity-50"
onClick={closeVersionInfoModal}
></div>
<div className="bg-white p-6 rounded-lg shadow-lg z-60 max-w-lg mx-auto">
<img
src="img/Logo_TALAS.png"
alt="TALAS V5 Logo"
className="w-1/2 mx-auto my-4"
/>
<div className="bg-white border p-6 rounded-lg shadow-lg z-60 max-w-lg mx-auto">
<h2 className="text-xl font-bold mb-6 text-start leading-tight">
Littwin Systemtechnik GmbH & Co. KG
</h2>
<h4 className="text-lg font-bold mb-2 text-start leading-tight">
Bürgermeister-Brötje Str. 28
</h4>
<h4 className="text-lg font-bold mb-2 text-start leading-tight">
D-26180 Rastede
</h4>
<h5 className="text-md mb-2 text-start leading-snug">
T: +49 4402 9725 77-0
</h5>
<h5 className="text-md mb-2 text-start leading-snug">
E: kontakt@littwin-systemtechnik.de
</h5>
</div>
<p className="text-gray-700 text-center font-bold mt-4 leading-relaxed">
TALAS.Map Version 1.0.0
</p>
<button
onClick={closeVersionInfoModal}
className="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-700 mx-auto block"
>
Schließen
</button>
</div>
</div>
)}
</>
);
};
export default MapComponent;