wip: Dynamische Layers /Geräte Gruppen Erkennung , overlapping funktioniert es noch nicht
This commit is contained in:
@@ -16,12 +16,11 @@ import { restoreMapSettings, checkOverlappingMarkers } from "../../utils/mapUtil
|
||||
import { APP_VERSION } from "../../config/appVersion.js";
|
||||
import * as layers from "../../config/layers.js";
|
||||
import addItemsToMapContextMenu from "../contextmenu/useMapContextMenu.js";
|
||||
import useGmaMarkersLayer from "../../hooks/layers/useGmaMarkersLayer.js";
|
||||
import useSmsfunkmodemMarkersLayer from "../../hooks/layers/useSmsfunkmodemMarkersLayer.js";
|
||||
|
||||
import useAreaMarkersLayer from "../../hooks/layers/useAreaMarkersLayer.js";
|
||||
import { setupPolylines } from "../../utils/polylines/setupPolylines.js";
|
||||
import { setupPOIs } from "../../utils/setupPOIs.js";
|
||||
import useLayerVisibility from "../../hooks/useLayerVisibility.js";
|
||||
|
||||
import useLineData from "../../hooks/useLineData.js";
|
||||
import { useMapComponentState } from "../../hooks/useMapComponentState.js";
|
||||
|
||||
@@ -69,10 +68,12 @@ import { fetchPoiIconsDataThunk } from "../../redux/thunks/database/pois/fetchPo
|
||||
import { fetchPoiTypThunk } from "../../redux/thunks/database/pois/fetchPoiTypThunk.js";
|
||||
import { updateAreaThunk } from "../../redux/thunks/database/area/updateAreaThunk";
|
||||
|
||||
import useDynamicDeviceLayers from "../../hooks/layers/useDynamicDeviceLayers";
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
//-------------------------------
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const countdown = useSelector((state) => state.polylineContextMenu.countdown);
|
||||
const countdownActive = useSelector((state) => state.polylineContextMenu.countdownActive);
|
||||
const isPolylineContextMenuOpen = useSelector((state) => state.polylineContextMenu.isOpen);
|
||||
@@ -109,7 +110,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
||||
const closePopup = () => setIsPopupOpen(false);
|
||||
const [currentCoordinates, setCurrentCoordinates] = useState("");
|
||||
const [AddPoiModalWindowState, setAddPoiModalWindowState] = useState(false);
|
||||
const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false);
|
||||
const [currentPoiData, setCurrentPoiData] = useState(null);
|
||||
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
|
||||
@@ -119,7 +119,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
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 [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten
|
||||
|
||||
//-----userRights----------------
|
||||
const isRightsLoaded = useSelector((state) => state.gisUserRightsFromWebservice.status === "succeeded");
|
||||
const userRights = useSelector(selectGisUserRightsFromWebservice);
|
||||
@@ -137,24 +137,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
|
||||
//console.log("priorityConfig in MapComponent1: ", priorityConfig);
|
||||
//-----------------------------------------
|
||||
const [gmaMarkers, setGmaMarkers] = useState([]); //--------------------station.System === 11 alle sind untetschiedlich Nummern
|
||||
const [talasMarkers, setTalasMarkers] = useState([]);
|
||||
const [eciMarkers, setEciMarkers] = useState([]);
|
||||
const [lteModemMarkers, setlteModemMarkers] = useState([]);
|
||||
const [ciscoRouterMarkers, setCiscoRouterMarkers] = useState([]);
|
||||
const [wagoMarkers, setWagoMarkers] = useState([]);
|
||||
const [siemensMarkers, setSiemensMarkers] = useState([]);
|
||||
const [otdrMarkers, setOtdrMarkers] = useState([]);
|
||||
const [wdmMarkers, setWdmMarkers] = useState([]);
|
||||
const [messstellenMarkers, setMessstellenMarkers] = useState([]);
|
||||
const [talasiclMarkers, setTalasiclMarkers] = useState([]);
|
||||
const [dauzMarkers, setDauzMarkers] = useState([]);
|
||||
const [smsfunkmodemMarkers, setSmsfunkmodemMarkers] = useState([]);
|
||||
const [ulafMarkers, setUlafMarkers] = useState([]);
|
||||
const [sonstigeMarkers, setSonstigeMarkers] = useState([]);
|
||||
const [tkComponentsMarkers, setTkComponentsMarkers] = useState([]);
|
||||
//--------------------------------------------
|
||||
|
||||
const [linePositions, setLinePositions] = useState([]);
|
||||
const { lineColors, tooltipContents } = useLineData();
|
||||
const [polylines, setPolylines] = useState([]);
|
||||
@@ -166,6 +148,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
const [showCoordinatesModal, setShowCoordinatesModal] = useState(false);
|
||||
const [popupCoordinates, setPopupCoordinates] = useState(null);
|
||||
const [popupVisible, setPopupVisible] = useState(false);
|
||||
const [poiData, setPoiData] = useState([]);
|
||||
|
||||
const openVersionInfoModal = () => {
|
||||
setShowVersionInfoModal(true);
|
||||
@@ -187,43 +170,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
}
|
||||
});
|
||||
|
||||
const allMarkers = [
|
||||
...talasMarkers,
|
||||
...eciMarkers,
|
||||
...lteModemMarkers,
|
||||
...ciscoRouterMarkers,
|
||||
...wagoMarkers,
|
||||
...siemensMarkers,
|
||||
...otdrMarkers,
|
||||
...wdmMarkers,
|
||||
...gmaMarkers,
|
||||
...messstellenMarkers,
|
||||
...talasiclMarkers,
|
||||
...dauzMarkers,
|
||||
...smsfunkmodemMarkers,
|
||||
...sonstigeMarkers,
|
||||
...tkComponentsMarkers,
|
||||
...ulafMarkers,
|
||||
];
|
||||
//--------------------------------------------
|
||||
const gmaLayerRef = useRef(null);
|
||||
const talasLayerRef = useRef(null);
|
||||
const eciMarkersLayerRef = useRef(null);
|
||||
const lteModemMarkersLayerRef = useRef(null);
|
||||
const ciscoRouterMarkersLayerRef = useRef(null);
|
||||
const wagoMarkersLayerRef = useRef(null);
|
||||
const siemensMarkersLayerRef = useRef(null);
|
||||
const otdrMarkersLayerRef = useRef(null);
|
||||
const wdmMarkersLayerRef = useRef(null);
|
||||
const messstellenMarkersLayerRef = useRef(null);
|
||||
const talasiclMarkersLayerRef = useRef(null);
|
||||
const dauzMarkersLayerRef = useRef(null);
|
||||
const smsfunkmodemMarkersLayerRef = useRef(null);
|
||||
const ulafMarkersLayerRef = useRef(null);
|
||||
const sonstigeMarkersLayerRef = useRef(null);
|
||||
const tkComponentsMarkersRef = useRef(null);
|
||||
//------------------------------
|
||||
const [poiData, setPoiData] = useState([]);
|
||||
//--------------------------------------------
|
||||
|
||||
const handleCoordinatesSubmit = (coords) => {
|
||||
@@ -234,7 +180,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
};
|
||||
//-----------------------------Map Initialisierung----------------
|
||||
useInitializeMap(map, mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, (value) => dispatch(setDisabled(value)));
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
//-------------------------React Hooks--------------------------------
|
||||
useEffect(() => {
|
||||
if (linesData && Array.isArray(linesData)) {
|
||||
@@ -316,51 +262,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
}
|
||||
}, [map, zoomTrigger]);
|
||||
//--------------------------------------------
|
||||
useEffect(() => {
|
||||
if (map) {
|
||||
// Sammle alle Marker in einer einzigen Liste
|
||||
|
||||
const editMode = localStorage.getItem("editMode") === "true"; // EditMode prüfen
|
||||
const visibility = mapLayersVisibility || {};
|
||||
|
||||
allMarkers.forEach((marker) => {
|
||||
const layerKey = marker.options?.layerKey; // Layer-Key aus den Marker-Optionen
|
||||
const isVisible = visibility[layerKey]; // Sichtbarkeitsstatus prüfen
|
||||
|
||||
if (!layerKey || isVisible === undefined) return;
|
||||
|
||||
if (editMode || !isVisible) {
|
||||
// Entferne Marker, wenn EditMode aktiv ist oder Layer unsichtbar
|
||||
if (map.hasLayer(marker)) map.removeLayer(marker);
|
||||
} else {
|
||||
// Füge Marker hinzu, wenn EditMode deaktiviert ist und Layer sichtbar
|
||||
if (!map.hasLayer(marker)) marker.addTo(map);
|
||||
}
|
||||
});
|
||||
|
||||
// Überprüfe überlappende Marker und füge das "Plus"-Icon hinzu
|
||||
checkOverlappingMarkers(map, allMarkers, plusRoundIcon);
|
||||
}
|
||||
}, [
|
||||
map,
|
||||
talasMarkers,
|
||||
eciMarkers,
|
||||
lteModemMarkers,
|
||||
ciscoRouterMarkers,
|
||||
wagoMarkers,
|
||||
siemensMarkers,
|
||||
otdrMarkers,
|
||||
wdmMarkers,
|
||||
gmaMarkers,
|
||||
messstellenMarkers,
|
||||
talasiclMarkers,
|
||||
dauzMarkers,
|
||||
smsfunkmodemMarkers,
|
||||
sonstigeMarkers,
|
||||
tkComponentsMarkers,
|
||||
ulafMarkers,
|
||||
mapLayersVisibility, // Neu: Abhängigkeit für Sichtbarkeitsstatus
|
||||
]);
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//Tooltip an mouse position anzeigen für die Linien
|
||||
@@ -534,128 +435,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
initializeContextMenu();
|
||||
}, [map]);
|
||||
|
||||
//--------------hooks-------------------------------------------
|
||||
|
||||
useGmaMarkersLayer(
|
||||
map,
|
||||
gmaMarkers,
|
||||
GisStationsMeasurements,
|
||||
layers.MAP_LAYERS.GMA,
|
||||
oms,
|
||||
mapLayersVisibility.GMA // Übergebe die Sichtbarkeitsbedingung als Parameter
|
||||
);
|
||||
//--------------------------------------------
|
||||
//useCreateAndSetDevices(1, talasMarkers, GisSystemStatic, priorityConfig);
|
||||
useLayerVisibility(map, talasMarkers, mapLayersVisibility, "TALAS", oms);
|
||||
useLayerVisibility(map, eciMarkers, mapLayersVisibility, "ECI", oms);
|
||||
useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms);
|
||||
useLayerVisibility(map, ciscoRouterMarkers, mapLayersVisibility, "CiscoRouter", oms);
|
||||
//useLayerVisibility(map, lteModemMarkers, mapLayersVisibility, "LTEModem", oms);
|
||||
useLayerVisibility(map, wagoMarkers, mapLayersVisibility, "WAGO", oms);
|
||||
useLayerVisibility(map, siemensMarkers, mapLayersVisibility, "Siemens", oms);
|
||||
useLayerVisibility(map, otdrMarkers, mapLayersVisibility, "OTDR", oms);
|
||||
useLayerVisibility(map, wdmMarkers, mapLayersVisibility, "WDM", oms);
|
||||
useLayerVisibility(map, gmaMarkers, mapLayersVisibility, "GMA", oms);
|
||||
useLayerVisibility(map, sonstigeMarkers, mapLayersVisibility, "Sonstige", oms);
|
||||
useLayerVisibility(map, tkComponentsMarkers, mapLayersVisibility, "TKKomponenten", oms);
|
||||
useLayerVisibility(map, talasiclMarkers, mapLayersVisibility, "TALASICL", oms);
|
||||
useLayerVisibility(map, dauzMarkers, mapLayersVisibility, "DAUZ", oms);
|
||||
useLayerVisibility(map, smsfunkmodemMarkers, mapLayersVisibility, "SMSModem", oms);
|
||||
useLayerVisibility(map, messstellenMarkers, mapLayersVisibility, "Messstellen", oms);
|
||||
useLayerVisibility(map, ulafMarkers, mapLayersVisibility, "ULAF", oms);
|
||||
//--------------------------------------------
|
||||
useEffect(() => {
|
||||
if (gisSystemStaticStatus !== "succeeded" || !map) return;
|
||||
|
||||
const layerGroups = [
|
||||
{ ref: gmaLayerRef, id: 11, setState: setGmaMarkers },
|
||||
{ ref: talasLayerRef, id: 1, setState: setTalasMarkers },
|
||||
{ ref: eciMarkersLayerRef, id: 2, setState: setEciMarkers },
|
||||
{ ref: lteModemMarkersLayerRef, id: 5, setState: setlteModemMarkers },
|
||||
{ ref: ciscoRouterMarkersLayerRef, id: 6, setState: setCiscoRouterMarkers },
|
||||
{ ref: wagoMarkersLayerRef, id: 7, setState: setWagoMarkers },
|
||||
{ ref: siemensMarkersLayerRef, id: 8, setState: setSiemensMarkers },
|
||||
{ ref: otdrMarkersLayerRef, id: 9, setState: setOtdrMarkers },
|
||||
{ ref: wdmMarkersLayerRef, id: 10, setState: setWdmMarkers },
|
||||
{ ref: messstellenMarkersLayerRef, id: 13, setState: setMessstellenMarkers },
|
||||
{ ref: talasiclMarkersLayerRef, id: 100, setState: setTalasiclMarkers },
|
||||
{ ref: dauzMarkersLayerRef, id: 110, setState: setDauzMarkers },
|
||||
{ ref: smsfunkmodemMarkersLayerRef, id: 111, setState: setSmsfunkmodemMarkers },
|
||||
{ ref: ulafMarkersLayerRef, id: 0, setState: setUlafMarkers },
|
||||
{ ref: sonstigeMarkersLayerRef, id: 200, setState: setSonstigeMarkers },
|
||||
{ ref: tkComponentsMarkersRef, id: 30, setState: setTkComponentsMarkers },
|
||||
];
|
||||
|
||||
// Initialisiere LayerGroups nur einmal
|
||||
layerGroups.forEach(({ ref }) => {
|
||||
if (!ref.current) {
|
||||
ref.current = new L.LayerGroup().addTo(map);
|
||||
}
|
||||
});
|
||||
//--------------------------------------------
|
||||
|
||||
const updateMarkers = ({ ref, id, setState }) => {
|
||||
if (ref.current) {
|
||||
ref.current.clearLayers(); // Entferne alte Marker
|
||||
}
|
||||
|
||||
// Erstelle und füge neue Marker hinzu
|
||||
createAndSetDevices(
|
||||
id,
|
||||
(newMarkers) => {
|
||||
setState(newMarkers); // Zustand aktualisieren
|
||||
newMarkers.forEach((marker) => ref.current.addLayer(marker)); // Marker zur LayerGroup hinzufügen
|
||||
|
||||
// Überprüfe auf überlappende Marker und füge das Plus-Icon hinzu
|
||||
checkOverlappingMarkers(map, newMarkers, plusRoundIcon);
|
||||
},
|
||||
GisSystemStatic,
|
||||
priorityConfig
|
||||
);
|
||||
};
|
||||
|
||||
// Aktualisiere alle Marker-Gruppen
|
||||
const updateAllMarkers = () => {
|
||||
layerGroups.forEach(updateMarkers);
|
||||
};
|
||||
|
||||
// Initiales Update
|
||||
updateAllMarkers();
|
||||
|
||||
// Setze ein Intervall für regelmäßige Updates
|
||||
const intervalId = setInterval(() => {
|
||||
updateAllMarkers();
|
||||
|
||||
if (map) {
|
||||
// console.log("🔥 Automatischer Klick-Event ausgelöst, um Spiderfy zu aktualisieren.");
|
||||
map.fire("click");
|
||||
}
|
||||
if (isPolylineContextMenuOpen) {
|
||||
dispatch(closePolylineContextMenu()); // Schließe das Kontextmenü, bevor das nächste Update passiert
|
||||
}
|
||||
if (map) {
|
||||
// console.log("🔥 nochmal klick.");
|
||||
map.fire("click");
|
||||
}
|
||||
}, 20000);
|
||||
|
||||
// Aufräumen bei Komponentenentladung
|
||||
return () => {
|
||||
clearInterval(intervalId); // Entferne Intervall
|
||||
|
||||
// LayerGroups leeren
|
||||
layerGroups.forEach(({ ref }) => {
|
||||
if (ref.current) {
|
||||
ref.current.clearLayers();
|
||||
}
|
||||
});
|
||||
};
|
||||
}, [map, GisSystemStatic, priorityConfig]);
|
||||
|
||||
//---------------------------------------
|
||||
// Initialisiere Leaflet-Karte
|
||||
// Rufe useAreaMarkersLayer direkt auf
|
||||
//const [areaUrl, setAreaUrl] = useState(null);
|
||||
const urlParams = new URLSearchParams(window.location.search); // URL-Parameter parsen
|
||||
const mValue = urlParams.get("m"); // Wert von "m" holen
|
||||
const hostname = window.location.hostname; // Dynamischer Hostname
|
||||
@@ -706,18 +488,21 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
}, [areaMarkers, map]);
|
||||
|
||||
//----------------------------------
|
||||
const { markerStates, layerRefs } = useDynamicDeviceLayers(map, GisSystemStatic, mapLayersVisibility, priorityConfig);
|
||||
useEffect(() => {
|
||||
const handleVisibilityChange = () => {
|
||||
// Erneut die Marker-Überprüfung auslösen
|
||||
if (!map) return;
|
||||
|
||||
const allMarkers = Object.values(markerStates).filter(Array.isArray).flat();
|
||||
|
||||
checkOverlappingMarkers(map, allMarkers, plusRoundIcon);
|
||||
};
|
||||
|
||||
window.addEventListener("visibilityChanged", handleVisibilityChange);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("visibilityChanged", handleVisibilityChange);
|
||||
};
|
||||
}, [map, allMarkers]);
|
||||
}, [map, markerStates]);
|
||||
|
||||
//---------------------------------------
|
||||
useEffect(() => {
|
||||
@@ -881,6 +666,35 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||
setPoiData(poiIconsData);
|
||||
}
|
||||
}, [poiIconsData, poiIconsStatus]);
|
||||
//-----------------------------------------------------------------
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------
|
||||
|
||||
useEffect(() => {
|
||||
if (!map) return;
|
||||
|
||||
const editMode = localStorage.getItem("editMode") === "true";
|
||||
|
||||
Object.entries(markerStates).forEach(([systemName, markers]) => {
|
||||
const isVisible = mapLayersVisibility[systemName];
|
||||
markers.forEach((marker) => {
|
||||
const hasLayer = map.hasLayer(marker);
|
||||
if (editMode || !isVisible) {
|
||||
if (hasLayer) map.removeLayer(marker);
|
||||
} else {
|
||||
if (!hasLayer) marker.addTo(map);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// optional für alle zusammen
|
||||
const allMarkers = Object.values(markerStates)
|
||||
.filter((entry) => Array.isArray(entry))
|
||||
.flat();
|
||||
|
||||
checkOverlappingMarkers(map, allMarkers, plusRoundIcon);
|
||||
}, [map, markerStates, mapLayersVisibility]);
|
||||
|
||||
//---------------------------------------------
|
||||
//--------------------------------------------
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
// /config/appVersion
|
||||
export const APP_VERSION = "1.1.201";
|
||||
export const APP_VERSION = "1.1.202";
|
||||
|
||||
20
config/devicesGroupLayers.js
Normal file
20
config/devicesGroupLayers.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// /config/devicesGroupLayers.js
|
||||
|
||||
export const devicesGroupLayers = [
|
||||
{ id: 1, name: "TALAS", ref: talasLayerRef, setState: setTalasMarkers },
|
||||
{ id: 2, name: "ECI", ref: eciLayerRef, setState: setEciMarkers },
|
||||
{ id: 3, name: "ULAF", ref: ulafLayerRef, setState: setUlafMarkers },
|
||||
{ id: 5, name: "LTE Modem", ref: lteModemLayerRef, setState: setLteModemMarkers },
|
||||
{ id: 6, name: "Cisco Router", ref: ciscoRouterLayerRef, setState: setCiscoRouterMarkers },
|
||||
{ id: 7, name: "WAGO", ref: wagoLayerRef, setState: setWagoMarkers },
|
||||
{ id: 8, name: "Siemens", ref: siemensLayerRef, setState: setSiemensMarkers },
|
||||
{ id: 9, name: "OTDR", ref: otdrLayerRef, setState: setOtdrMarkers },
|
||||
{ id: 10, name: "WDM", ref: wdmLayerRef, setState: setWdmMarkers },
|
||||
{ id: 11, name: "GMA", ref: gmaLayerRef, setState: setGmaMarkers },
|
||||
{ id: 13, name: "Messstellen", ref: messstellenLayerRef, setState: setMessstellenMarkers },
|
||||
{ id: 30, name: "TK-Komponenten", ref: tkKomponentenLayerRef, setState: setTkKomponentenMarkers },
|
||||
{ id: 100, name: "TALAS ICL", ref: talasiclLayerRef, setState: setTalasiclMarkers },
|
||||
{ id: 110, name: "DAUZ", ref: dauzLayerRef, setState: setDauzMarkers },
|
||||
{ id: 111, name: "SMS Modem", ref: smsModemLayerRef, setState: setSmsModemMarkers },
|
||||
{ id: 200, name: "Sonstige", ref: sonLayerRef, setState: setSonMarkers },
|
||||
];
|
||||
@@ -88,3 +88,53 @@ Dieses Dokument beschreibt die technische Gesamtarchitektur des Projekts **NodeM
|
||||
- [`env.local.schema.md`](./env.local.schema.md)
|
||||
- [`redux/slices/`](./redux/slices/)
|
||||
- [`services/webservice/`](./services/webservice/)
|
||||
|
||||
---
|
||||
|
||||
## Dynamische Layer-Verwaltung mit Redux
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
%% Webservice
|
||||
subgraph Webservice
|
||||
A1[GisSystemStatic API]
|
||||
A2[GisStationsStaticDistrict API]
|
||||
end
|
||||
|
||||
%% Redux
|
||||
subgraph Redux
|
||||
B1[fetchGisSystemStaticThunk]
|
||||
B2[fetchGisStationsStaticDistrictThunk]
|
||||
C1["gisSystemStaticSlice → selectGisSystemStatic"]
|
||||
C2["gisStationsStaticDistrictSlice → selectGisStationsStaticDistrict"]
|
||||
C3["mapLayersSlice → mapLayersVisibility"]
|
||||
end
|
||||
|
||||
%% React
|
||||
subgraph React-Komponente
|
||||
D1[MapComponent.js]
|
||||
D2["useEffect: dynamische Layer"]
|
||||
D3["createAndSetDevices"]
|
||||
D4["layerRefs (useRef)"]
|
||||
D5["markerStates (useState)"]
|
||||
D6["useEffect: Sichtbarkeit prüfen"]
|
||||
D7["Map aktualisieren / add/remove"]
|
||||
D8["checkOverlappingMarkers"]
|
||||
end
|
||||
|
||||
%% Datenfluss
|
||||
A1 --> B1 --> C1 --> D2
|
||||
A2 --> B2 --> C2 --> D3
|
||||
C3 --> D6
|
||||
D2 --> D3
|
||||
D3 --> D4
|
||||
D3 --> D5
|
||||
D5 --> D6
|
||||
D6 --> D7
|
||||
D6 --> D8
|
||||
D7 --> D1
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
68
hooks/layers/useDynamicDeviceLayers.js
Normal file
68
hooks/layers/useDynamicDeviceLayers.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import L from "leaflet";
|
||||
import { createAndSetDevices } from "../../utils/devices/createAndSetDevices";
|
||||
import { checkOverlappingMarkers } from "../../utils/mapUtils";
|
||||
import plusRoundIcon from "../../components/icons/devices/overlapping/PlusRoundIcon";
|
||||
|
||||
/**
|
||||
* Dynamisch GIS-System-Marker erstellen & Sichtbarkeit steuern.
|
||||
* @param {object} map - Leaflet Map-Instanz
|
||||
* @param {Array} GisSystemStatic - Liste der Systeme aus Webservice
|
||||
* @param {object} mapLayersVisibility - Redux-Objekt mit Layer-Sichtbarkeiten
|
||||
* @param {object} priorityConfig - Konfig für Prioritäten
|
||||
* @returns {{ markerStates, layerRefs }} Alle Marker und Referenzen
|
||||
*/
|
||||
const useDynamicDeviceLayers = (map, GisSystemStatic, mapLayersVisibility, priorityConfig) => {
|
||||
const [markerStates, setMarkerStates] = useState({});
|
||||
const layerRefs = useRef({});
|
||||
|
||||
// Marker initialisieren
|
||||
useEffect(() => {
|
||||
if (!map || GisSystemStatic.length === 0) return;
|
||||
|
||||
GisSystemStatic.forEach(({ Name, IdSystem }) => {
|
||||
if (!layerRefs.current[Name]) {
|
||||
layerRefs.current[Name] = new L.LayerGroup().addTo(map);
|
||||
}
|
||||
|
||||
createAndSetDevices(
|
||||
IdSystem,
|
||||
(newMarkers) => {
|
||||
setMarkerStates((prev) => ({ ...prev, [Name]: newMarkers }));
|
||||
newMarkers.forEach((m) => layerRefs.current[Name].addLayer(m));
|
||||
checkOverlappingMarkers(map, newMarkers, plusRoundIcon);
|
||||
},
|
||||
GisSystemStatic,
|
||||
priorityConfig
|
||||
);
|
||||
});
|
||||
}, [map, GisSystemStatic, priorityConfig]);
|
||||
|
||||
// Sichtbarkeit aktualisieren
|
||||
useEffect(() => {
|
||||
if (!map) return;
|
||||
const editMode = localStorage.getItem("editMode") === "true";
|
||||
|
||||
Object.entries(markerStates).forEach(([systemName, markers]) => {
|
||||
const isVisible = mapLayersVisibility[systemName];
|
||||
markers.forEach((marker) => {
|
||||
const hasLayer = map.hasLayer(marker);
|
||||
if (editMode || !isVisible) {
|
||||
if (hasLayer) map.removeLayer(marker);
|
||||
} else {
|
||||
if (!hasLayer) marker.addTo(map);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const allMarkers = Object.values(markerStates)
|
||||
.filter(Array.isArray) // nur Arrays zulassen
|
||||
.flat();
|
||||
|
||||
checkOverlappingMarkers(map, allMarkers, plusRoundIcon);
|
||||
}, [map, markerStates, mapLayersVisibility]);
|
||||
|
||||
return { markerStates, layerRefs };
|
||||
};
|
||||
|
||||
export default useDynamicDeviceLayers;
|
||||
@@ -161,6 +161,6 @@ export const createAndSetDevices = async (systemId, setMarkersFunction, GisSyste
|
||||
|
||||
setMarkersFunction(markersData);
|
||||
} catch (error) {
|
||||
console.error("❌ Fehler in createAndSetDevices.js (Redux-Version):", error);
|
||||
console.error("❌ Fehler in createAndSetDevices.js (Redux-Version):", error.message, error.stack);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,12 +22,15 @@ export const restoreMapSettings = (map) => {
|
||||
let plusMarkers = [];
|
||||
|
||||
export const checkOverlappingMarkers = (map, markers, plusIcon) => {
|
||||
if (!Array.isArray(markers)) {
|
||||
console.warn("⚠️ checkOverlappingMarkers erwartet ein Array, aber erhielt:", markers);
|
||||
return;
|
||||
}
|
||||
|
||||
const overlappingGroups = {};
|
||||
|
||||
// Gruppiere Marker basierend auf ihrer Position
|
||||
markers.forEach((marker) => {
|
||||
if (map.hasLayer(marker)) {
|
||||
// Überprüfen, ob der Marker sichtbar ist
|
||||
const latlngStr = marker.getLatLng().toString();
|
||||
if (overlappingGroups[latlngStr]) {
|
||||
overlappingGroups[latlngStr].push(marker);
|
||||
@@ -37,37 +40,27 @@ export const checkOverlappingMarkers = (map, markers, plusIcon) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Entferne alte Plus-Icons
|
||||
// alte PlusIcons entfernen
|
||||
plusMarkers.forEach((plusMarker) => map.removeLayer(plusMarker));
|
||||
plusMarkers = [];
|
||||
|
||||
// Füge Plus-Icons für überlappende Marker hinzu
|
||||
// neue PlusIcons hinzufügen
|
||||
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 }).addTo(map);
|
||||
plusMarkers.push(plusMarker); // Speichere das Plus-Icon
|
||||
plusMarkers.push(plusMarker);
|
||||
|
||||
plusMarker.on("click", (e) => {
|
||||
const clickedLatLng = e.latlng;
|
||||
|
||||
// Finde nahegelegene Marker (50 Pixel als Beispielradius)
|
||||
const nearbyMarkers = markers.filter((marker) => map.distance(marker.getLatLng(), clickedLatLng) < 50);
|
||||
|
||||
console.log("Nearby Markers for Plus Icon:", nearbyMarkers);
|
||||
|
||||
if (nearbyMarkers.length > 0) {
|
||||
// Simuliere einen Klick nur auf den ersten Marker
|
||||
nearbyMarkers[0].fire("click");
|
||||
console.log("Clicked on nearby Marker[0]:", nearbyMarkers[0]);
|
||||
} else {
|
||||
console.log("Keine Marker gefunden.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Entferne alle Plus-Icons, wenn keine Marker sichtbar sind
|
||||
if (Object.keys(overlappingGroups).length === 0) {
|
||||
plusMarkers.forEach((plusMarker) => map.removeLayer(plusMarker));
|
||||
plusMarkers = [];
|
||||
|
||||
Reference in New Issue
Block a user