Files
nodeMap/hooks/layers/useGmaMarkersLayer.js
2024-12-16 13:53:30 +01:00

200 lines
6.2 KiB
JavaScript

import { useEffect } from "react";
const useGmaMarkersLayer = (map, markers, GisStationsMeasurements, GMA, oms, isVisible) => {
let currentMenu = null; // Variable für das aktuelle Kontextmenü
const closeContextMenu = () => {
if (currentMenu) {
currentMenu.remove();
currentMenu = null;
}
};
const zoomIn = (map, latlng) => {
if (!map) return;
const currentZoom = map.getZoom();
if (currentZoom < 14) {
map.flyTo(latlng, 14);
}
};
const zoomOut = (map) => {
if (!map) return;
map.flyTo([51.4132, 7.7396], 7);
};
const centerHere = (map, latlng) => {
if (!map) return;
map.panTo(latlng);
};
useEffect(() => {
if (!map || !isVisible) return;
GMA.clearLayers();
markers.forEach((marker) => {
const areaName = marker.options.areaName;
const relevantMeasurements = GisStationsMeasurements.filter((m) => m.Area_Name === areaName);
let measurements = {};
relevantMeasurements.forEach((m) => {
measurements[m.Na] = m.Val;
});
const lt = measurements["LT"] || "-";
const fbt = measurements["FBT"] || "-";
const gt = measurements["GT"] || "-";
const rlf = measurements["RLF"] || "-";
// Tooltip erstellen
marker.bindTooltip(
`
<div class="p-0 rounded-lg bg-white bg-opacity-90 tooltip-content">
<div class="font-bold text-sm text-black"><span>${areaName}</span></div>
<div class="font-bold text-xxs text-blue-700"><span>LT: ${lt} °C</span></div>
<div class="font-bold text-xxs text-red-700"><span>FBT: ${fbt} °C</span></div>
<div class="font-bold text-xxs text-yellow-500"><span>GT: ${gt} °C</span></div>
<div class="font-bold text-xxs text-green-700"><span>RLF: ${rlf} %</span></div>
</div>
`,
{
permanent: true,
// direction: "auto",
offset: [60, 0],
interactive: true,
}
);
let currentMouseLatLng = null;
const mouseMoveHandler = (event) => {
currentMouseLatLng = event.latlng;
};
map.on("mousemove", mouseMoveHandler);
marker.on("tooltipopen", (e) => {
const tooltipElement = e.tooltip._contentNode;
if (tooltipElement) {
tooltipElement.addEventListener("contextmenu", (event) => {
event.preventDefault();
closeContextMenu(); // Altes Menü schließen
// Kontextmenü-Items definieren
const combinedContextMenuItems = [
{
text: "Station öffnen (Tab)",
icon: "/img/screen_new.png",
callback: () => {
const fullUrl = marker.options.link || "http://example.com";
window.open(fullUrl, "_blank");
},
},
{ separator: true },
{
text: "Koordinaten anzeigen",
icon: "/img/not_listed_location.png",
callback: () => {
if (currentMouseLatLng) {
alert(`Breitengrad: ${currentMouseLatLng.lat.toFixed(5)}\nLängengrad: ${currentMouseLatLng.lng.toFixed(5)}`);
}
},
},
{ separator: true },
{
text: "Reinzoomen",
icon: "/img/zoom_in.png",
callback: () => zoomIn(map, marker.getLatLng()),
},
{
text: "Rauszoomen",
icon: "/img/zoom_out.png",
callback: () => zoomOut(map),
},
{
text: "Hier zentrieren",
icon: "/img/center_focus.png",
callback: () => centerHere(map, marker.getLatLng()),
},
];
// Menü erstellen und anzeigen
const menu = document.createElement("div");
menu.className = "custom-context-menu";
menu.style.position = "absolute";
menu.style.left = `${event.clientX}px`;
menu.style.top = `${event.clientY}px`;
menu.style.backgroundColor = "#fff";
menu.style.border = "1px solid #ccc";
menu.style.padding = "4px";
menu.style.zIndex = "1000";
combinedContextMenuItems.forEach((item) => {
if (item.separator) {
const separator = document.createElement("hr");
menu.appendChild(separator);
} else {
const menuItem = document.createElement("div");
menuItem.style.display = "flex";
menuItem.style.alignItems = "center";
menuItem.style.cursor = "pointer";
menuItem.style.padding = "4px";
if (item.icon) {
const icon = document.createElement("img");
icon.src = item.icon;
icon.style.width = "16px";
icon.style.marginRight = "8px";
menuItem.appendChild(icon);
}
const text = document.createElement("span");
text.textContent = item.text;
menuItem.appendChild(text);
menuItem.onclick = () => {
item.callback();
closeContextMenu();
};
menu.appendChild(menuItem);
}
});
document.body.appendChild(menu);
currentMenu = menu;
const handleClickOutside = (e) => {
if (menu && !menu.contains(e.target)) {
closeContextMenu();
document.removeEventListener("click", handleClickOutside);
}
};
document.addEventListener("click", handleClickOutside);
});
}
});
marker.on("tooltipclose", () => {
map.off("mousemove", mouseMoveHandler);
closeContextMenu();
});
GMA.addLayer(marker);
oms.addMarker(marker);
});
map.addLayer(GMA);
return () => {
GMA.clearLayers();
map.removeLayer(GMA);
closeContextMenu();
};
}, [map, markers, GisStationsMeasurements, GMA, oms, isVisible]);
return null;
};
export default useGmaMarkersLayer;