117 lines
4.6 KiB
JavaScript
117 lines
4.6 KiB
JavaScript
// /hooks/layers/useDynamicDeviceLayers.js
|
|
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";
|
|
import { useSelector } from "react-redux";
|
|
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice.js";
|
|
import { selectGisStationsMeasurements } from "@/redux/slices/webservice/gisStationsMeasurementsSlice.js";
|
|
import { selectGisStationsStatusDistrict } from "@/redux/slices/webservice/gisStationsStatusDistrictSlice.js";
|
|
|
|
/**
|
|
* 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, oms) => {
|
|
const measurements = useSelector(selectGisStationsMeasurements);
|
|
const staticDistrictData = useSelector(selectGisStationsStaticDistrict);
|
|
const statusDistrict = useSelector(selectGisStationsStatusDistrict);
|
|
|
|
const [markerStates, setMarkerStates] = useState({});
|
|
const layerRefs = useRef({});
|
|
|
|
// Marker initialisieren (nicht sichtbar machen)
|
|
useEffect(() => {
|
|
if (!map || GisSystemStatic.length === 0) return;
|
|
|
|
GisSystemStatic.forEach(({ Name, IdSystem }) => {
|
|
const key = `system-${IdSystem}`;
|
|
// LayerGroup-Instanzierung und Bereinigung
|
|
if (layerRefs.current[key]) {
|
|
// Entferne alte LayerGroup von der Map, falls vorhanden
|
|
if (map.hasLayer(layerRefs.current[key])) {
|
|
map.removeLayer(layerRefs.current[key]);
|
|
}
|
|
layerRefs.current[key].clearLayers();
|
|
}
|
|
// Neue oder wiederverwendete LayerGroup anlegen und zur Map hinzufügen
|
|
if (!layerRefs.current[key]) {
|
|
layerRefs.current[key] = new L.LayerGroup();
|
|
}
|
|
layerRefs.current[key].addTo(map);
|
|
// Debug-Ausgabe
|
|
/* console.log(
|
|
`[DeviceLayers] LayerGroup für ${key} auf Map hinzugefügt. Aktuelle LayerGroups:`,
|
|
Object.keys(layerRefs.current)
|
|
); */
|
|
|
|
createAndSetDevices(
|
|
IdSystem,
|
|
newMarkers => {
|
|
// Füge neue Marker der LayerGroup hinzu (nur Geräte-Marker)
|
|
if (layerRefs.current[key]) {
|
|
// Entferne alle Marker aus der LayerGroup, bevor neue hinzugefügt werden
|
|
layerRefs.current[key].clearLayers();
|
|
(Array.isArray(newMarkers) ? newMarkers : []).forEach(marker => {
|
|
// Nur LayerGroup verwenden, nicht direkt auf map
|
|
marker.addTo(layerRefs.current[key]);
|
|
});
|
|
// Debug: Anzahl Marker in LayerGroup
|
|
/* console.log(
|
|
`[DeviceLayers] ${
|
|
layerRefs.current[key].getLayers().length
|
|
} Marker in LayerGroup für ${key}`
|
|
); */
|
|
}
|
|
setMarkerStates(prev => ({ ...prev, [key]: newMarkers }));
|
|
},
|
|
GisSystemStatic,
|
|
priorityConfig,
|
|
undefined,
|
|
oms
|
|
);
|
|
});
|
|
}, [map, GisSystemStatic, priorityConfig, staticDistrictData, measurements, statusDistrict]);
|
|
|
|
// Sichtbarkeit nach Redux-Status steuern
|
|
useEffect(() => {
|
|
if (!map) return;
|
|
const editMode = localStorage.getItem("editMode") === "true";
|
|
|
|
Object.entries(markerStates).forEach(([key, markers]) => {
|
|
const isVisible = mapLayersVisibility[key] ?? true; // undefined = true
|
|
|
|
(Array.isArray(markers) ? markers : []).forEach(marker => {
|
|
const hasLayer = map.hasLayer(marker);
|
|
|
|
// Logik korrigiert:
|
|
// - Im editMode: alle Marker verstecken
|
|
// - Nicht im editMode: nur sichtbare Marker anzeigen (isVisible === true)
|
|
if (editMode || isVisible === false) {
|
|
// Marker verstecken
|
|
if (hasLayer) {
|
|
map.removeLayer(marker);
|
|
}
|
|
} else if (isVisible === true) {
|
|
// Marker anzeigen (nur wenn explizit true)
|
|
if (!hasLayer) {
|
|
marker.addTo(map);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
const allMarkers = Object.values(markerStates).filter(Array.isArray).flat();
|
|
checkOverlappingMarkers(map, allMarkers, plusRoundIcon);
|
|
}, [map, markerStates, mapLayersVisibility]);
|
|
|
|
return { markerStates, layerRefs };
|
|
};
|
|
|
|
export default useDynamicDeviceLayers;
|