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 { APP_VERSION } from "../../config/appVersion.js";
|
||||||
import * as layers from "../../config/layers.js";
|
import * as layers from "../../config/layers.js";
|
||||||
import addItemsToMapContextMenu from "../contextmenu/useMapContextMenu.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 useAreaMarkersLayer from "../../hooks/layers/useAreaMarkersLayer.js";
|
||||||
import { setupPolylines } from "../../utils/polylines/setupPolylines.js";
|
import { setupPolylines } from "../../utils/polylines/setupPolylines.js";
|
||||||
import { setupPOIs } from "../../utils/setupPOIs.js";
|
import { setupPOIs } from "../../utils/setupPOIs.js";
|
||||||
import useLayerVisibility from "../../hooks/useLayerVisibility.js";
|
|
||||||
import useLineData from "../../hooks/useLineData.js";
|
import useLineData from "../../hooks/useLineData.js";
|
||||||
import { useMapComponentState } from "../../hooks/useMapComponentState.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 { fetchPoiTypThunk } from "../../redux/thunks/database/pois/fetchPoiTypThunk.js";
|
||||||
import { updateAreaThunk } from "../../redux/thunks/database/area/updateAreaThunk";
|
import { updateAreaThunk } from "../../redux/thunks/database/area/updateAreaThunk";
|
||||||
|
|
||||||
|
import useDynamicDeviceLayers from "../../hooks/layers/useDynamicDeviceLayers";
|
||||||
//-----------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------
|
||||||
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
||||||
//-------------------------------
|
//-------------------------------
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const countdown = useSelector((state) => state.polylineContextMenu.countdown);
|
const countdown = useSelector((state) => state.polylineContextMenu.countdown);
|
||||||
const countdownActive = useSelector((state) => state.polylineContextMenu.countdownActive);
|
const countdownActive = useSelector((state) => state.polylineContextMenu.countdownActive);
|
||||||
const isPolylineContextMenuOpen = useSelector((state) => state.polylineContextMenu.isOpen);
|
const isPolylineContextMenuOpen = useSelector((state) => state.polylineContextMenu.isOpen);
|
||||||
@@ -109,7 +110,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
const [isPopupOpen, setIsPopupOpen] = useState(false);
|
||||||
const closePopup = () => setIsPopupOpen(false);
|
const closePopup = () => setIsPopupOpen(false);
|
||||||
const [currentCoordinates, setCurrentCoordinates] = useState("");
|
const [currentCoordinates, setCurrentCoordinates] = useState("");
|
||||||
const [AddPoiModalWindowState, setAddPoiModalWindowState] = useState(false);
|
|
||||||
const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false);
|
const [showPoiUpdateModal, setShowPoiUpdateModal] = useState(false);
|
||||||
const [currentPoiData, setCurrentPoiData] = useState(null);
|
const [currentPoiData, setCurrentPoiData] = useState(null);
|
||||||
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
|
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 mapRef = useRef(null); // Referenz auf das DIV-Element der Karte
|
||||||
const [map, setMap] = useState(null); // Zustand der Karteninstanz
|
const [map, setMap] = useState(null); // Zustand der Karteninstanz
|
||||||
const [oms, setOms] = useState(null); // State für OMS-Instanz
|
const [oms, setOms] = useState(null); // State für OMS-Instanz
|
||||||
const [GisStationsMeasurements, setGisStationsMeasurements] = useState([]); // Zustand für Messdaten
|
|
||||||
//-----userRights----------------
|
//-----userRights----------------
|
||||||
const isRightsLoaded = useSelector((state) => state.gisUserRightsFromWebservice.status === "succeeded");
|
const isRightsLoaded = useSelector((state) => state.gisUserRightsFromWebservice.status === "succeeded");
|
||||||
const userRights = useSelector(selectGisUserRightsFromWebservice);
|
const userRights = useSelector(selectGisUserRightsFromWebservice);
|
||||||
@@ -137,24 +137,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
|
|
||||||
//console.log("priorityConfig in MapComponent1: ", priorityConfig);
|
//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 [linePositions, setLinePositions] = useState([]);
|
||||||
const { lineColors, tooltipContents } = useLineData();
|
const { lineColors, tooltipContents } = useLineData();
|
||||||
const [polylines, setPolylines] = useState([]);
|
const [polylines, setPolylines] = useState([]);
|
||||||
@@ -166,6 +148,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
const [showCoordinatesModal, setShowCoordinatesModal] = useState(false);
|
const [showCoordinatesModal, setShowCoordinatesModal] = useState(false);
|
||||||
const [popupCoordinates, setPopupCoordinates] = useState(null);
|
const [popupCoordinates, setPopupCoordinates] = useState(null);
|
||||||
const [popupVisible, setPopupVisible] = useState(false);
|
const [popupVisible, setPopupVisible] = useState(false);
|
||||||
|
const [poiData, setPoiData] = useState([]);
|
||||||
|
|
||||||
const openVersionInfoModal = () => {
|
const openVersionInfoModal = () => {
|
||||||
setShowVersionInfoModal(true);
|
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) => {
|
const handleCoordinatesSubmit = (coords) => {
|
||||||
@@ -234,7 +180,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
};
|
};
|
||||||
//-----------------------------Map Initialisierung----------------
|
//-----------------------------Map Initialisierung----------------
|
||||||
useInitializeMap(map, mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, (value) => dispatch(setDisabled(value)));
|
useInitializeMap(map, mapRef, setMap, setOms, setMenuItemAdded, addItemsToMapContextMenu, hasRights, (value) => dispatch(setDisabled(value)));
|
||||||
//--------------------------------------------------------------------
|
|
||||||
//-------------------------React Hooks--------------------------------
|
//-------------------------React Hooks--------------------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (linesData && Array.isArray(linesData)) {
|
if (linesData && Array.isArray(linesData)) {
|
||||||
@@ -316,51 +262,6 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
}
|
}
|
||||||
}, [map, zoomTrigger]);
|
}, [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
|
//Tooltip an mouse position anzeigen für die Linien
|
||||||
@@ -534,128 +435,9 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
initializeContextMenu();
|
initializeContextMenu();
|
||||||
}, [map]);
|
}, [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
|
// Initialisiere Leaflet-Karte
|
||||||
// Rufe useAreaMarkersLayer direkt auf
|
// Rufe useAreaMarkersLayer direkt auf
|
||||||
//const [areaUrl, setAreaUrl] = useState(null);
|
|
||||||
const urlParams = new URLSearchParams(window.location.search); // URL-Parameter parsen
|
const urlParams = new URLSearchParams(window.location.search); // URL-Parameter parsen
|
||||||
const mValue = urlParams.get("m"); // Wert von "m" holen
|
const mValue = urlParams.get("m"); // Wert von "m" holen
|
||||||
const hostname = window.location.hostname; // Dynamischer Hostname
|
const hostname = window.location.hostname; // Dynamischer Hostname
|
||||||
@@ -706,18 +488,21 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
}, [areaMarkers, map]);
|
}, [areaMarkers, map]);
|
||||||
|
|
||||||
//----------------------------------
|
//----------------------------------
|
||||||
|
const { markerStates, layerRefs } = useDynamicDeviceLayers(map, GisSystemStatic, mapLayersVisibility, priorityConfig);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleVisibilityChange = () => {
|
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);
|
checkOverlappingMarkers(map, allMarkers, plusRoundIcon);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("visibilityChanged", handleVisibilityChange);
|
window.addEventListener("visibilityChanged", handleVisibilityChange);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("visibilityChanged", handleVisibilityChange);
|
window.removeEventListener("visibilityChanged", handleVisibilityChange);
|
||||||
};
|
};
|
||||||
}, [map, allMarkers]);
|
}, [map, markerStates]);
|
||||||
|
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -881,6 +666,35 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
setPoiData(poiIconsData);
|
setPoiData(poiIconsData);
|
||||||
}
|
}
|
||||||
}, [poiIconsData, poiIconsStatus]);
|
}, [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
|
// /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)
|
- [`env.local.schema.md`](./env.local.schema.md)
|
||||||
- [`redux/slices/`](./redux/slices/)
|
- [`redux/slices/`](./redux/slices/)
|
||||||
- [`services/webservice/`](./services/webservice/)
|
- [`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);
|
setMarkersFunction(markersData);
|
||||||
} catch (error) {
|
} 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 = [];
|
let plusMarkers = [];
|
||||||
|
|
||||||
export const checkOverlappingMarkers = (map, markers, plusIcon) => {
|
export const checkOverlappingMarkers = (map, markers, plusIcon) => {
|
||||||
|
if (!Array.isArray(markers)) {
|
||||||
|
console.warn("⚠️ checkOverlappingMarkers erwartet ein Array, aber erhielt:", markers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const overlappingGroups = {};
|
const overlappingGroups = {};
|
||||||
|
|
||||||
// Gruppiere Marker basierend auf ihrer Position
|
|
||||||
markers.forEach((marker) => {
|
markers.forEach((marker) => {
|
||||||
if (map.hasLayer(marker)) {
|
if (map.hasLayer(marker)) {
|
||||||
// Überprüfen, ob der Marker sichtbar ist
|
|
||||||
const latlngStr = marker.getLatLng().toString();
|
const latlngStr = marker.getLatLng().toString();
|
||||||
if (overlappingGroups[latlngStr]) {
|
if (overlappingGroups[latlngStr]) {
|
||||||
overlappingGroups[latlngStr].push(marker);
|
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.forEach((plusMarker) => map.removeLayer(plusMarker));
|
||||||
plusMarkers = [];
|
plusMarkers = [];
|
||||||
|
|
||||||
// Füge Plus-Icons für überlappende Marker hinzu
|
// neue PlusIcons hinzufügen
|
||||||
for (const coords in overlappingGroups) {
|
for (const coords in overlappingGroups) {
|
||||||
if (overlappingGroups[coords].length > 1) {
|
if (overlappingGroups[coords].length > 1) {
|
||||||
const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number));
|
const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number));
|
||||||
const plusMarker = L.marker(latLng, { icon: plusIcon }).addTo(map);
|
const plusMarker = L.marker(latLng, { icon: plusIcon }).addTo(map);
|
||||||
plusMarkers.push(plusMarker); // Speichere das Plus-Icon
|
plusMarkers.push(plusMarker);
|
||||||
|
|
||||||
plusMarker.on("click", (e) => {
|
plusMarker.on("click", (e) => {
|
||||||
const clickedLatLng = e.latlng;
|
const clickedLatLng = e.latlng;
|
||||||
|
|
||||||
// Finde nahegelegene Marker (50 Pixel als Beispielradius)
|
|
||||||
const nearbyMarkers = markers.filter((marker) => map.distance(marker.getLatLng(), clickedLatLng) < 50);
|
const nearbyMarkers = markers.filter((marker) => map.distance(marker.getLatLng(), clickedLatLng) < 50);
|
||||||
|
|
||||||
console.log("Nearby Markers for Plus Icon:", nearbyMarkers);
|
|
||||||
|
|
||||||
if (nearbyMarkers.length > 0) {
|
if (nearbyMarkers.length > 0) {
|
||||||
// Simuliere einen Klick nur auf den ersten Marker
|
|
||||||
nearbyMarkers[0].fire("click");
|
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) {
|
if (Object.keys(overlappingGroups).length === 0) {
|
||||||
plusMarkers.forEach((plusMarker) => map.removeLayer(plusMarker));
|
plusMarkers.forEach((plusMarker) => map.removeLayer(plusMarker));
|
||||||
plusMarkers = [];
|
plusMarkers = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user