diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..2b7bafa5f --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env", "@babel/preset-react"] +} diff --git a/.gitignore b/.gitignore index be30aedd7..cba64b18b 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ trace # Ignore specific Next.js build files pages-manifest.json +nodeMap für 13 am 16.07.2024.zip diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..3e8762fab --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,32 @@ +pipeline { + agent any + + stages { + stage('Install Dependencies') { + steps { + // Installiere npm Abhängigkeiten + sh 'npm install' + } + } + + stage('Run Tests') { + steps { + // Führt Ihre Tests aus + sh 'npm test' + } + } + } + + post { + always { + // Archivieren Sie die Testberichte, wenn verfügbar + junit '**/test-results.xml' + } + success { + echo 'Die Tests wurden erfolgreich abgeschlossen!' + } + failure { + echo 'Einige Tests sind fehlgeschlagen.' + } + } +} diff --git a/__mocks__/leaflet.js b/__mocks__/leaflet.js new file mode 100644 index 000000000..9a04eb751 --- /dev/null +++ b/__mocks__/leaflet.js @@ -0,0 +1,12 @@ +module.exports = { + map: () => ({ + setView: jest.fn(), + addLayer: jest.fn(), + }), + tileLayer: () => ({ + addTo: jest.fn(), + }), + marker: () => ({ + addTo: jest.fn(), + }), +}; diff --git a/__tests__/MapComponent.test.js b/__tests__/MapComponent.test.js new file mode 100644 index 000000000..ea9be1af6 --- /dev/null +++ b/__tests__/MapComponent.test.js @@ -0,0 +1,89 @@ +// __tests__/MapComponent.test.js + +// Ein einfacher Testfall, der sicherstellt, dass die Addition korrekt ist +test("simple addition", () => { + const a = 1; + const b = 2; + const c = a + b; + expect(c).toBe(3); // Überprüft, ob c gleich 3 ist +}); + +//import L from "leaflet"; +//import { checkOverlappingMarkers } from "../utils/mapUtils"; // Passe den Pfad entsprechend an + +/* describe("checkOverlappingMarkers", () => { + let map; + + beforeEach(() => { + // Erstelle eine neue Leaflet-Karte für jeden Test + map = L.map(document.createElement("div")); + }); + + it("should group markers by coordinates and add plus icons for overlapping markers", () => { + // Erstelle einige Beispielmarker + const markers = [ + L.marker([51.505, -0.09]), + L.marker([51.505, -0.09]), + L.marker([51.51, -0.1]), + ]; + + const plusIcon = L.divIcon({ className: "plus-icon" }); + + // Rufe die Funktion auf + checkOverlappingMarkers(map, markers, plusIcon); + + // Überprüfe, dass die Marker zu Gruppen hinzugefügt wurden + const overlappingGroups = map._layers; + expect(Object.keys(overlappingGroups).length).toBeGreaterThan(0); + + // Überprüfe, dass die Plus-Marker hinzugefügt wurden + const plusMarkers = Object.values(overlappingGroups).filter( + (layer) => + layer.options.icon && + layer.options.icon.options.className === "plus-icon" + ); + expect(plusMarkers.length).toBeGreaterThan(0); + }); + + it("should handle non-array markers argument gracefully", () => { + const plusIcon = L.divIcon({ className: "plus-icon" }); + + // Rufe die Funktion mit einem ungültigen Argument auf + checkOverlappingMarkers(map, null, plusIcon); + + // Stelle sicher, dass keine Marker hinzugefügt wurden + const layers = map._layers; + expect(Object.keys(layers).length).toBe(0); + }); + + it("should not add plus markers if there are no overlaps", () => { + // Erstelle einige Beispielmarker + const markers = [ + L.marker([51.505, -0.09]), + L.marker([51.51, -0.1]), + L.marker([51.52, -0.12]), + ]; + + const plusIcon = L.divIcon({ className: "plus-icon" }); + + // Rufe die Funktion auf + checkOverlappingMarkers(map, markers, plusIcon); + + // Überprüfe, dass keine Plus-Marker hinzugefügt wurden + const plusMarkers = Object.values(map._layers).filter( + (layer) => + layer.options.icon && + layer.options.icon.options.className === "plus-icon" + ); + expect(plusMarkers.length).toBe(0); + }); +}); */ +/* +In diesem Test: + +Wird eine neue Leaflet-Karte vor jedem Test erstellt. +checkOverlappingMarkers wird aufgerufen, um zu überprüfen, ob die Funktion die Marker richtig gruppiert und Plus-Icons für überlappende Marker hinzufügt. +Der Test überprüft auch, ob die Funktion ungültige Argumente (wie null für Marker) korrekt behandelt. +Es wird sichergestellt, dass keine Plus-Marker hinzugefügt werden, wenn keine Überlappungen vorliegen. +Stelle sicher, dass du die Pfade und Importe entsprechend deiner Projektstruktur anpasst. +*/ diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 000000000..e8ca8aa71 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ["@babel/preset-env", "@babel/preset-react"], +}; diff --git a/components/CircleIcon.js b/components/CircleIcon.js new file mode 100644 index 000000000..c9f4843d3 --- /dev/null +++ b/components/CircleIcon.js @@ -0,0 +1,13 @@ +// /components/CircleIcon.js +// Custom circle icon for draggable markers +import L from "leaflet"; +import "leaflet/dist/leaflet.css"; + +const circleIcon = L.divIcon({ + className: "custom-div-icon", + html: "
", + iconSize: [25, 25], + iconAnchor: [5, 5], +}); + +export default circleIcon; diff --git a/components/EndIcon.js b/components/EndIcon.js new file mode 100644 index 000000000..25d272e95 --- /dev/null +++ b/components/EndIcon.js @@ -0,0 +1,10 @@ +// Custom circle icon for draggable markers +import L from "leaflet"; +const endIcon = L.divIcon({ + className: "custom-end-icon", + html: "
", // Graues Viereck + iconSize: [14, 14], + iconAnchor: [7, 7], // Mittelpunkt des Vierecks als Anker +}); + +export default endIcon; diff --git a/components/MapComponent.js b/components/MapComponent.js index 7303ee5d2..f445e7db1 100644 --- a/components/MapComponent.js +++ b/components/MapComponent.js @@ -1,5 +1,5 @@ // components/MapComponent.js - +// test für Jenkins import React, { useEffect, useRef, @@ -15,6 +15,7 @@ import "leaflet/dist/leaflet.css"; import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; import "leaflet-contextmenu"; import * as config from "../config/config.js"; +import * as urls from "../config/urls.js"; import dynamic from "next/dynamic"; import "leaflet.smooth_marker_bouncing"; import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet"; @@ -26,78 +27,93 @@ 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 ShowAddStationPopup from "./ShowAddStationPopup.js"; +import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom.js"; 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 { currentPoiState } from "../store/atoms/currentPoiState.js"; 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 { mapIdState, userIdState } from "../store/atoms/urlParameterState.js"; +import { has, set } from "lodash"; +import { poiLayerVisibleState } from "../store/atoms/poiLayerVisible.js"; import { data } from "autoprefixer"; import plusRoundIcon from "./PlusRoundIcon.js"; - +import {} from //parsePoint, +//handleEditPoi, +//insertNewMarker, +//redrawPolyline, +//saveLineData, +"../utils/utils.js"; +import { parsePoint, findClosestPoints } from "../utils/geometryUtils.js"; +import { + //handleEditPoi, + insertNewMarker, + removeMarker, +} from "../utils/markerUtils.js"; +import { + saveLineData, + redrawPolyline, + restoreMapSettings, + checkOverlappingMarkers, +} from "../utils/mapUtils.js"; +import circleIcon from "./CircleIcon"; +import startIcon from "./StartIcon"; +import endIcon from "./EndIcon"; +import { + fetchGisStatusStations, + fetchPriorityConfig, + fetchPoiData, + updateLocationInDatabase, + checkInternet, + fetchUserRights, + fetchDeviceNameById, +} from "../services/apiService.js"; +import { + addContextMenuToMarker, + openInNewTab, +} from "../utils/contextMenuUtils.js"; +import { MAP_VERSION } from "../config/settings"; +import * as layers from "../config/layers.js"; +import useMapContextMenu from "./useMapContextMenu.js"; +import { openInSameWindow } from "../utils/openInSameWindow"; +import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils.js"; //--------------------------------------------------------------------- //-------------------- MapComponent ----------------------------------- const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { - const [priorityConfig, setPriorityConfig] = useState([]); + const [loading, setLoading] = useState(true); // Ladezustand hinzufügen + const [currentZoom, setCurrentZoom] = useState(() => { + const storedZoom = localStorage.getItem("mapZoom"); + return storedZoom ? parseInt(storedZoom, 10) : 12; + }); - const fetchPriorityConfig = async () => { + const [currentCenter, setCurrentCenter] = useState(() => { + const storedCenter = localStorage.getItem("mapCenter"); 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); + return storedCenter ? JSON.parse(storedCenter) : [53.111111, 8.4625]; + } catch (e) { + console.error("Error parsing stored map center:", e); + return [53.111111, 8.4625]; } - }; + }); + + const [priorityConfig, setPriorityConfig] = useState([]); useEffect(() => { fetchPriorityConfig(); }, []); - useEffect(() => { + /* useEffect(() => { console.log("Aktualisierte Prioritätskonfiguration:", priorityConfig); - }, [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); @@ -127,88 +143,37 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { setMapId(params.get("m")); setUserId(params.get("u")); }, [setMapId, setUserId]); - useEffect(() => { + /* useEffect(() => { fetchUserRights().then(() => { setIsRightsLoaded(true); + console.log("Benutzerrechte in useEffect in MapComponent:", userRights); }); - }, []); // 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); - }; + }, [urls.SERVER_URL]); // Lade die Berechtigungen beim Initialisieren der Komponente */ 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 + const offlineTileLayer = urls.OFFLINE_TILE_LAYER; + const onlineTileLayer = urls.ONLINE_TILE_LAYER; //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 TALAS = layers.MAP_LAYERS.TALAS; + const ECI = layers.MAP_LAYERS.ECI; + const ULAF = layers.MAP_LAYERS.ULAF; + const GSMModem = layers.MAP_LAYERS.GSMModem; + const CiscoRouter = layers.MAP_LAYERS.CiscoRouter; + const WAGO = layers.MAP_LAYERS.WAGO; + const Siemens = layers.MAP_LAYERS.Siemens; + const OTDR = layers.MAP_LAYERS.OTDR; + const WDM = layers.MAP_LAYERS.WDM; + const GMA = layers.MAP_LAYERS.GMA; + const Sonstige = layers.MAP_LAYERS.Sonstige; + const TALASICL = layers.MAP_LAYERS.TALASICL; + const lineLayer = layers.MAP_LAYERS.lineLayer; 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 baseUrl = urls.BASE_URL; // für Station öffnen in neuer tab und gleicher tab, im localhost gab es keine Probleme mit der Frame + const [isPoiTypLoaded, setIsPoiTypLoaded] = useState(false); const [poiTypMap, setPoiTypMap] = useState(new Map()); const [showPopup, setShowPopup] = useState(false); @@ -267,81 +232,24 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { 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"); - } + //---------------------------------------------------- + //---------------------------------------------------- + // Kontextmenü Callback für "Reinzoomen" + const zoomInCallback = (e, map) => { + zoomIn(e, map); }; - //--------------------------------------------- + // Kontextmenü Callback für "Rauszoomen" + const zoomOutCallback = (map) => { + zoomOut(map); + }; + + // Kontextmenü Callback für "Hier zentrieren" + const centerHereCallback = (e, map) => { + centerHere(e, map); + }; //---------------------------------------------------- //-----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( @@ -370,114 +278,108 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }; // 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 + const addStationCallback = useCallback((event, hasRights) => { + console.log( + "Überprüfung der Berechtigung in addStationCallback: ", + 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."); + } + }); //-----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 - { + const addItemsToMapContextMenu = (hasRights) => { + if (!menuItemAdded && map) { + map.contextmenu.addItem({ + text: "Koordinaten anzeigen", + icon: "img/not_listed_location.png", + callback: showCoordinates, + }); + + map.contextmenu.addItem({ separator: true }); // Divider + + map.contextmenu.addItem({ + text: "Reinzoomen", + icon: "img/zoom_in.png", + callback: (e) => zoomInCallback(e, map), + }); + + map.contextmenu.addItem({ + text: "Rauszoomen", + icon: "img/zoom_out.png", + callback: () => zoomOutCallback(map), + }); + + map.contextmenu.addItem({ + text: "Hier zentrieren", + icon: "img/center_focus.png", + callback: (e) => centerHereCallback(e, map), + }); + + map.contextmenu.addItem({ separator: true }); // Another Divider + + map.contextmenu.addItem({ 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... - ]); + setMenuItemAdded(true); // Menüpunkt wurde hinzugefült, Zustand aktualisieren } - }, [isRightsLoaded, hasRights]); - */ - //---------------------------------------------------------------------------------- + }; + + useEffect(() => { + if ( + map && + poiLayerRef.current && + isPoiTypLoaded && + !menuItemAdded && + isRightsLoaded + ) { + console.log( + "Überprüfung der Berechtigung vor addItemsToMapContextMenu: ", + hasRights + ); + addItemsToMapContextMenu(hasRights); + } + }, [ + map, + poiLayerRef, + isPoiTypLoaded, + menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern + hasRights, // Sicherstellen, dass hasRights berücksichtigt wird + isRightsLoaded, // Überprüfung, ob die Rechte geladen sind + ]); + + useEffect(() => { + const fetchAndSetUserRights = async () => { + const rights = await fetchUserRights(); + //console.log("Benutzerrechte in server URL:", rights); + setUserRights(rights); + setIsRightsLoaded(true); + setHasRights(rights && rights.includes(56)); // Prüfen, ob Benutzer die Rechte hat + //console.log("Benutzerrechte in useEffect in MapComponent:", rights); + }; + + fetchAndSetUserRights(); + }, [urls.SERVER_URL]); // Lade die Berechtigungen beim Initialisieren der Komponente + + //---------------------------------------------------- //------------------------------------------ */ const layerNames = { "GSM Modem": "GSMMODEM", @@ -495,37 +397,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } //------------------------------------------ //------------------------------------------ - // 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 //----------------------------------------------------------------- @@ -573,29 +445,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } 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 { @@ -670,6 +520,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
${statusInfo}
`); + return marker; }); @@ -682,18 +533,44 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { //-------------------------------------------------------------------------------- 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 + //---------------------------------------------- + const handleEditPoi = (selectedPoi) => { + // 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 + } - setMapLayersVisibility((prev) => { - return { - ...prev, - [internalName]: checked, - }; + //console.log("Selected Marker ID (idPoi):", marker.options.idPoi); + console.log( + "Selected Marker Description:", + selectedPoi.options.description + ); + console.log("Selected Marker :", selectedPoi.options); + + setCurrentPoiData({ + idPoi: selectedPoi.options.id, + name: selectedPoi.options.name, + description: selectedPoi.options.description, }); - }; */ + //console.log("POI-Daten1:", currentPoiData); + + fetchPoiData(selectedPoi.options.id); + fetchPoiData(selectedPoi.options.name); + //fetchPoiData(selectedPoi.options); + + setShowPoiUpdateModal(true); + }; + //---------------------------------------------- //------------------------------------------ //------------------------------------------ */ @@ -724,95 +601,54 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }; //-------------------------------------------------------------- //--------------------------------------------------------- - // 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) => { + /* 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 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 = urls.SERVER_URL; // 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(() => { + /* useEffect(() => { fetchUserRights(); - }, []); + }, []); */ + /* useEffect(() => { + console.log( + "Server URL ist verfügbar:", + config.url.origin, + "idMap:", + config.idMap, + "idUser:", + config.idUser + ); + fetchUserRights().then((rights) => { + // console.log("Benutzerrechte in server URL:", rights); + setUserRights(rights); + setIsRightsLoaded(true); + setHasRights(rights && rights.includes(56)); // Prüfen, ob Benutzer die Rechte hat + console.log("Benutzerrechte in useEffect in MapComponent:", hasRights); + }); + }, []); */ // Anzeigen von Modals basierend auf Benutzerrechten useEffect(() => { @@ -973,8 +809,10 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { useEffect(() => { if (mapRef.current && !map) { initMap = L.map(mapRef.current, { - center: [53.111111, 8.4625], - zoom: 8, + //center: [53.111111, 8.4625], + center: currentCenter, + //zoom: 8, + zoom: currentZoom, layers: [ TALAS, ECI, @@ -1003,7 +841,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }, }, "-", // Divider - + /* { text: "Koordinaten anzeigen", icon: "img/not_listed_location.png", @@ -1011,13 +849,17 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }, "-", // Divider { text: "Reinzoomen", icon: "img/zoom_in.png", callback: zoomIn }, - { text: "Rauszoomen", icon: "img/zoom_out.png", callback: zoomOut }, + { + text: "Rauszoomen", + icon: "img/zoom_out.png", + callback: () => zoomOutCallback(map), + }, { text: "Hier zentrieren", icon: "img/center_focus.png", - callback: centerHere, + callback: (e) => centerHere(e, map), }, - "-", // Divider + "-", // Divider */ ], }); @@ -1052,6 +894,57 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { //console.log("trigger in MapComponent.js:", poiReadTrigger); }, [mapRef, map, poiReadTrigger, contextMenuItems]); // Prüfe die Abhängigkeiten sorgfältig + /* 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); + }; */ + + /* useEffect(() => { + if (map) { + map.on("contextmenu", (e) => { + const contextMenuItems = [ + { + text: "Reinzoomen", + icon: "img/zoom_in.png", + callback: (e) => zoomIn(e, map), + }, + { + text: "Rauszoomen", + icon: "img/zoom_out.png", + callback: () => zoomOut(map), + }, + { + text: "Hier zentrieren", + icon: "img/center_focus.png", + callback: (e) => centerHere(e, map), + }, + "-", + ]; + L.DomEvent.stopPropagation(e); + const contextMenu = L.popup() + .setLatLng(e.latlng) + .setContent( + '
' + + contextMenuItems + .map( + (item) => + `${item.text}` + ) + .join("
") + + "
" + ) + .openOn(map); + }); + } + }, [map]); */ + // poiTyp Daten hinzufügen //------------------------------------------ // Funktion zum Abrufen der poiTyp Daten @@ -1147,44 +1040,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } //------------------------------------------ - - 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 = () => { + /* const addItemsToMapContextMenu = () => { if (!menuItemAdded) { //console.log("contextMenuItems hasRights:", hasRights); @@ -1197,9 +1055,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { setMenuItemAdded(true); // Menüpunkt wurde hinzugefült, Zustand aktualisieren } - }; + }; */ - useEffect(() => { + /* useEffect(() => { if (map && poiLayerRef.current && isPoiTypLoaded && !menuItemAdded) { addItemsToMapContextMenu(); } @@ -1208,7 +1066,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { poiLayerRef, isPoiTypLoaded, menuItemAdded, // Hinzufügen zu den Abhängigkeiten, um den Effekt korrekt zu steuern - ]); + ]); */ //------------------------------------------ // poiLayerRef(poiDbLayer) POI hinzufügen @@ -1266,6 +1124,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }), draggable: canDrag, id: location.idPoi, + name: location.name, + description: location.description, }).bindContextMenu({ contextmenu: true, contextmenuWidth: 140, @@ -1273,7 +1133,15 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { { text: "POI Bearbeiten", icon: "/img/poi-edit.png", - callback: () => handleEditPoi(marker), + callback: () => + handleEditPoi( + marker, + userRights, + setCurrentPoiData, + setShowPoiUpdateModal, + fetchPoiData, + toast + ), }, ], }); @@ -1569,19 +1437,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { 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); @@ -1763,25 +1618,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { 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 } @@ -2038,14 +1877,14 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { //------------------------------------------ */ // Effect to handle navigation to selected area - useEffect(() => { + /* 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 + }, [selectedArea, map, allMarkers]); // Include allMarkers in the dependencies */ //------------------------------------------ @@ -2063,14 +1902,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } }, [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) { @@ -2129,7 +1960,11 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }) .then((data) => { const newLinePositions = data.map((item) => { + console.log("item.idLD", item.idLD); + console.log("item.idModul", item.idModul); + if (item.points && Array.isArray(item.points)) { + //console.log("item.points in MapComponent", item.points); return { coordinates: item.points.map((point) => [point.x, point.y]), idModul: item.idModul, @@ -2159,6 +1994,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { const response1 = await fetch(webserviceGisLinesStatusUrl); const data1 = await response1.json(); const response2 = await fetch("/api/talas_v5_DB/gisLines/readGisLines"); + /* const response2 = await fetch( + "http://10.10.0.13/talas5/MessagesMap/mapTypC.aspx?m=10&u=484" + ); */ const data2 = await response2.json(); const colorsByModule = {}; @@ -2184,21 +2022,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
`; - - /* newTooltipContents[matchingLine.idModul] = ` -
- ${stat.ModulName || "Unknown"} -
- ${stat.ModulTyp || "N/A"} -
-
- - ${stat.Message || "N/A"} -
- (${stat.PrioName || "N/A"}) -
-
- `; */ } }); @@ -2218,26 +2041,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { }, [lineColors]); //--------------------------------------------------------- - // Custom circle icon for draggable markers - const circleIcon = L.divIcon({ - className: "custom-div-icon", - html: "
", - iconSize: [25, 25], - iconAnchor: [5, 5], - }); - const startIcon = L.divIcon({ - className: "custom-start-icon", - html: "
", // Rot für den Startpunkt - iconSize: [25, 25], - iconAnchor: [5, 5], - }); - - const endIcon = L.divIcon({ - className: "custom-end-icon", - html: "
", // Blau für den Endpunkt - iconSize: [25, 25], - iconAnchor: [5, 5], - }); //----------------------- Update lines---------------------------------- const [lineStatusData, setLineStatusData] = useState([]); const [linesData, setLinesData] = useState([]); @@ -2259,7 +2062,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { ); if (matchingLine) { colorsByModule[matchingLine.idModul] = stat.PrioColor; - console.log("Übereinstimmung gefunden für: ", stat); + //console.log("Übereinstimmung gefunden für: ", stat); setLinesData(matchingLine); } }); @@ -2272,11 +2075,15 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { fetchData(); }, []); //--------------------------------------------------------- - useEffect(() => { + /* useEffect(() => { console.log("lineStatusData", lineStatusData); console.log("lineData:", linesData); - }, [lineStatusData, linesData]); + }, [lineStatusData, linesData]); */ //--------------------------------------------------------- + const [newPoint, setNewPoint] = useState(null); + const [newCoords, setNewCoords] = useState(null); + const [tempMarker, setTempMarker] = useState(null); + useEffect(() => { if (!map) return; @@ -2307,6 +2114,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { marker.on("dragend", () => { const newCoords = marker.getLatLng(); + setNewCoords(newCoords); // Aktualisieren Sie den Zustand const newCoordinates = [...lineData.coordinates]; newCoordinates[index] = [newCoords.lat, newCoords.lng]; @@ -2327,7 +2135,8 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { updatedPolyline.bringToFront(); }); updatedPolyline.on("mouseout", () => { - updatedPolyline.setStyle({ weight: 5 }); + updatedPolyline.setStyle({ weight: 3 }); + console.log("Mouse out"); }); newPolylines[lineIndex].remove(); @@ -2373,13 +2182,13 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { this.bindContextMenu({ contextmenuItems: [ { - text: "Marker entfernen", + text: "Stützpunkt entfernen", callback: () => { const newCoords = marker.getLatLng(); const newCoordinates = [...lineData.coordinates]; newCoordinates[index] = [newCoords.lat, newCoords.lng]; - removeMarker(marker, lineData); + removeMarker(marker, lineData, currentZoom, currentCenter); newPolylines[lineIndex].remove(); lineData.coordinates = newCoordinates; }, @@ -2401,14 +2210,22 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { contextmenu: true, contextmenuItems: [ { - text: "Marker hier hinzufügen", + text: "Stützpunkt hinzufügen", callback: (e) => { + if (tempMarker) { + tempMarker.remove(); // Entfernen des Platzhalter-Icons + } + //------------ const newPoint = e.latlng; + setNewPoint(newPoint); // Aktualisieren Sie den Zustand const closestPoints = findClosestPoints( lineData.coordinates, newPoint ); insertNewMarker(closestPoints, newPoint, lineData, map); + redrawPolyline(lineData); + //Browser aktualisieren + window.location.reload(); }, }, ], @@ -2416,10 +2233,14 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { polyline.on("mouseover", (e) => { // Optional: Visualisiere, dass die Linie interaktiv ist - polyline.setStyle({ color: "blue", weight: 10 }); + //polyline.setStyle({ color: "blue", weight: 10 }); + polyline.setStyle({ weight: 10 }); }); polyline.on("mouseout", (e) => { + //polyline.setStyle({ color: "blue", weight: 3 }); + polyline.setStyle({ weight: 3 }); + // Setze die ursprüngliche Farbe zurück polyline.setStyle({ color: lineColors[lineData.idModul] || "#000000" }); }); @@ -2438,118 +2259,25 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { setMarkers(newMarkers); setPolylines(newPolylines); - }, [map, linePositions, lineColors, tooltipContents]); + }, [ + map, + linePositions, + lineColors, + tooltipContents, + newPoint, + newCoords, + tempMarker, + ]); //--------------------------------------------------------- //-------------------------Funktionen-------------------------------- - function addMarkerAt(e, lineData) { - const newCoord = [e.latlng.lat, e.latlng.lng]; - lineData.coordinates.push(newCoord); // neuen Punkt hinzufügen - drawPolyline(lineData); // Polylinie neu zeichnen - - const marker = L.marker(newCoord, { draggable: true }).addTo(map); - marker.on("drag", (event) => { - updateMarkerPosition(event.target.getLatLng(), lineData, marker); - }); - } - - function drawPolyline(lineData) { - if (lineData.polyline) map.removeLayer(lineData.polyline); - lineData.polyline = L.polyline(lineData.coordinates, { - color: "red", - }).addTo(map); - } - - function removeMarker(marker, lineData) { - const index = lineData.coordinates.findIndex((coord) => - L.latLng(coord[0], coord[1]).equals(marker.getLatLng()) - ); - if (index !== -1) { - lineData.coordinates.splice(index, 1); // Entferne die Koordinaten des Markers - redrawPolyline(lineData); // Neuzeichnen der Polylinie - marker.remove(); // Entferne den Marker von der Karte - saveLineData(lineData); // Speichern der neuen Linienkoordinaten + // Call restoreMapSettings when the map is initialized + useEffect(() => { + if (map) { + restoreMapSettings(map); } - } - - function redrawPolyline(lineData) { - 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(); - }); - polyline.on("mouseout", () => { - polyline.setStyle({ weight: 5 }); - }); - } - - function saveLineData(lineData) { - fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - idModul: lineData.idModul, - idLD: lineData.idLD, - newCoordinates: lineData.coordinates, - }), - }) - .then((response) => { - if (!response.ok) { - throw new Error("Fehler beim Speichern der Linienänderungen"); - } - return response.json(); - }) - .then((data) => { - console.log("Linienänderungen gespeichert:", data); - }) - .catch((error) => { - console.error("Fehler beim Speichern der Linienänderungen:", error); - }); - } - - function insertNewMarker(closestPoints, newPoint, lineData, map) { - const newMarker = L.marker(newPoint, { draggable: true }).addTo(map); - lineData.coordinates.splice(closestPoints[2], 0, [ - newPoint.lat, - newPoint.lng, - ]); - - // Hier direkt speichern nach Einfügen - saveLineData(lineData); - - redrawPolyline(lineData); - - // Event-Listener für das Verschieben des Markers hinzufügen - newMarker.on("dragend", () => { - updateMarkerPosition(newMarker.getLatLng(), lineData, newMarker); - saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben - }); - } - - function updateMarkerPosition(newLatLng, lineData, marker) { - const index = lineData.coordinates.findIndex((coord) => - L.latLng(coord[0], coord[1]).equals(marker.getLatLng()) - ); - if (index !== -1) { - lineData.coordinates[index] = [newLatLng.lat, newLatLng.lng]; - redrawPolyline(lineData); - saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben - } - } + }, [map]); function findClosestPoints(coordinates, newPoint) { let minDist = Infinity; @@ -2567,7 +2295,78 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => { } return closestPair; } + //--------------------------------------------------------- + useEffect(() => { + if (map) { + const handleMapMoveEnd = (event) => { + const newCenter = map.getCenter(); + const newZoom = map.getZoom(); + setCurrentCenter([newCenter.lat, newCenter.lng]); + setCurrentZoom(newZoom); + + // Save to localStorage + localStorage.setItem( + "mapCenter", + JSON.stringify([newCenter.lat, newCenter.lng]) + ); + localStorage.setItem("mapZoom", newZoom); + }; + + map.on("moveend", handleMapMoveEnd); + map.on("zoomend", handleMapMoveEnd); + + return () => { + map.off("moveend", handleMapMoveEnd); + map.off("zoomend", handleMapMoveEnd); + }; + } + }, [map]); + + //------------------------------------------ */hier ist das Bug + + // 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 */ + + //------------------------------------------ + //--------------------------------------------------------- Kein Bug + useEffect(() => { + if (selectedArea && map) { + const station = GisStationsStaticDistrict.find( + (s) => s.Area_Name === selectedArea + ); + if (station) { + map.flyTo([station.X, station.Y], 14); + } + } + }, [selectedArea, map, GisStationsStaticDistrict]); + + useEffect(() => { + if (zoomTrigger && map) { + map.flyTo([51.41321407879154, 7.739617925303934], 7); + } + }, [zoomTrigger, map]); + //--------------------------------------------------------- + //---------------------------------------------------------zoomen in kontextmenü + // Beispiel für die Verwendung von fetchPoiData mit Recoil Zustand + /* useEffect(() => { + if (selectedPoi) { + fetchPoiData(selectedPoi.idPoi) + .then((data) => { + console.log("Fetched POI data:", data); + }) + .catch((error) => { + console.error("Fehler beim Abrufen der POI-Daten:", error); + }); + } + }, [selectedPoi]); */ //--------------------------------------------------------- //--------------------------------------------------------- @@ -2682,7 +2481,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
- Version 1.0.0 + Version {MAP_VERSION}

- TALAS.Map Version 1.0.0 + TALAS.Map Version {MAP_VERSION}