Files
nodeMap/utils/devices/createAndSetDevices.js
ISA 819fde9605 Safeguard: prevent errors when GisStationsMeasurements is empty or missing
- Ensure createAndSetDevices.js always uses an array for measurements
- Prevents crashes if measurement data is empty
2025-08-20 14:03:38 +02:00

195 lines
6.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// /utils/devices/createAndSetDevices.js
import L from "leaflet";
import "leaflet.smooth_marker_bouncing";
import { store } from "@/redux/store.js";
import { setSelectedDevice } from "@/redux/slices/selectedDeviceSlice.js";
import { selectGisStationsStaticDistrict } from "@/redux/slices/webservice/gisStationsStaticDistrictSlice.js";
import { selectGisStationsStatusDistrict } from "@/redux/slices/webservice/gisStationsStatusDistrictSlice.js";
import { selectGisStationsMeasurements } from "@/redux/slices/webservice/gisStationsMeasurementsSlice.js";
import { addContextMenuToMarker } from "@/utils/contextMenuUtils";
import { cleanupMarkers } from "@/utils/common/cleanupMarkers";
const determinePriority = (iconPath, priorityConfig) => {
for (let priority of priorityConfig) {
if (iconPath.includes(priority.name.toLowerCase())) {
return priority.level;
}
}
return 5;
};
export const createAndSetDevices = async (
systemId,
setMarkersFunction,
GisSystemStatic,
priorityConfig,
measurements,
oms // 🔁 OMS für Spiderfy hinzugefügt
) => {
// Prüfe, ob das System erlaubt ist (Allow === 1)
const systemConfig = Array.isArray(GisSystemStatic)
? GisSystemStatic.find(sys => sys.IdSystem === systemId)
: null;
if (!systemConfig) {
console.warn(`🚫 Kein Marker für System ${systemId}, Allow = ${systemConfig?.Allow}`);
setMarkersFunction([]);
return;
}
let basePath = "";
try {
const res = await fetch("/config.json");
if (res.ok) {
const config = await res.json();
basePath = config.basePath || "";
}
} catch (e) {}
try {
const state = store.getState();
const staticDistrictData = selectGisStationsStaticDistrict(state);
const statusDistrictData = selectGisStationsStatusDistrict(state);
const measurementData = selectGisStationsMeasurements(state);
// Sicherstellen, dass measurementData immer ein Array ist
const safeMeasurementData = Array.isArray(measurementData) ? measurementData : [];
if (!staticDistrictData?.Points?.length) return;
const hasStatus = Array.isArray(statusDistrictData) && statusDistrictData.length > 0;
const statisMap = new Map(statusDistrictData.map(s => [s.IdLD, s]));
const measurementsMap = new Map();
safeMeasurementData.forEach(m => {
if (!measurementsMap.has(m.IdLD)) {
measurementsMap.set(m.IdLD, m);
}
});
const activeStations = staticDistrictData.Points.filter(
station => station.System === systemId && station.Active === 1
);
const markersData = activeStations.map(station => {
const statis = statisMap.get(station.IdLD);
const messung = measurementsMap.get(station.IdLD);
const iconPath = statis
? `img/icons/${statis.Na}-marker-icon-${station.Icon}.png`
: `img/icons/marker-icon-${station.Icon}.png`;
const priority = determinePriority(iconPath, priorityConfig);
const zIndexOffset = 100 * (5 - priority);
const marker = L.marker([station.X, station.Y], {
icon: L.icon({
iconUrl: iconPath,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
}),
areaName: station.Area_Name,
link: station.Link,
zIndexOffset,
deviceName: station.Device,
idDevice: station.IdLD,
});
// ✅ Popup
let popupContent = `
<div class="bg-white rounded-lg">
<span class="text-lg font-semibold text-gray-900">${station.LD_Name}</span>
<span class="text-md font-bold text-gray-800">${station.Device}</span><br>
<span class="text-gray-800"><strong>${station.Area_Short}</strong> (${
station.Area_Name
})</span><br>
<span class="text-gray-800"><strong>${station.Location_Short}</strong> (${
station.Location_Name
})</span>
<div class="mt-2">
${statusDistrictData
.filter(status => status.IdLD === station.IdLD)
.reverse()
.map(
status => `
<div class="flex items-center my-1">
<div class="w-2 h-2 mr-2 inline-block rounded-full" style="background-color: ${status.Co};"></div>
${status.Me}&nbsp;<span style="color: ${status.Co};">(${status.Na})</span>
</div>`
)
.join("")}
</div>
</div>`;
marker.bindPopup(popupContent);
// ✅ Tooltip (nur für System 11)
if (station.System === 11 && messung) {
const gmaMap = new Map();
safeMeasurementData.forEach(m => {
if (!gmaMap.has(m.IdLD)) {
gmaMap.set(m.IdLD, {});
}
const mapEntry = gmaMap.get(m.IdLD);
mapEntry[m.Na] = m.Val; // z.B. mapEntry["FBT"] = 6
});
const gmaValues = gmaMap.get(station.IdLD) ?? {};
const lt = gmaValues["LT"] ?? "-";
const fbt = gmaValues["FBT"] ?? "-";
const gt = gmaValues["GT"] ?? "-";
const rlf = gmaValues["RLF"] ?? "-";
const gmaTooltipHtml = `
<div class="p-0 rounded-lg bg-white bg-opacity-90 tooltip-content">
<div class="font-bold text-sm text-black">${station.Area_Name}</div>
<div class="font-bold text-xxs text-blue-700">LT: ${lt} °C</div>
<div class="font-bold text-xxs text-red-700">FBT: ${fbt} °C</div>
<div class="font-bold text-xxs text-yellow-500">GT: ${gt} °C</div>
<div class="font-bold text-xxs text-green-700">RLF: ${rlf} %</div>
</div>
`;
marker.bindTooltip(gmaTooltipHtml, {
permanent: true,
direction: "right",
offset: [50, -20],
interactive: true,
className: "leaflet-tooltip gma-tooltip",
});
}
marker.on("mouseover", () => {
store.dispatch(
setSelectedDevice({
id: station.IdLD,
name: station.Device,
area: station.Area_Name,
})
);
marker.openPopup();
});
marker.on("contextmenu", () => {
store.dispatch(
setSelectedDevice({
id: station.IdLD,
name: station.Device,
area: station.Area_Name,
})
);
});
addContextMenuToMarker(marker);
// ✅ OverlappingMarkerSpiderfier hinzufügen
if (oms) {
oms.addMarker(marker);
}
return marker;
});
setMarkersFunction(markersData);
} catch (error) {
console.error("❌ Fehler in createAndSetDevices.js:", error.message, error.stack);
}
};