Gängige Praxis: *Slice.js Verwendung: Wenn du Redux Toolkit und createSlice nutzt, ist der Postfix Slice gängiger. Begründung: createSlice ist ein Begriff aus Redux Toolkit. Der Name vermittelt, dass die Datei nicht nur den Reducer enthält, sondern auch Aktionen und den initialen Zustand. Häufig in modernen Projekten verwendet.
430 lines
15 KiB
JavaScript
430 lines
15 KiB
JavaScript
// utils/setupPolylines.js
|
|
import { findClosestPoints } from "./geometryUtils";
|
|
import handlePoiSelect from "./handlePoiSelect";
|
|
import { updateLocationInDatabase } from "../services/apiService";
|
|
import { handleEditPoi, insertNewPOI, removePOI } from "./poiUtils";
|
|
import { parsePoint } from "./geometryUtils";
|
|
import circleIcon from "../components/gisPolylines/icons/CircleIcon";
|
|
import startIcon from "../components/gisPolylines/icons/StartIcon";
|
|
import endIcon from "../components/gisPolylines/icons/EndIcon";
|
|
import { redrawPolyline } from "./mapUtils";
|
|
import { openInNewTab } from "./openInNewTab";
|
|
import { toast } from "react-toastify";
|
|
import { polylineLayerVisibleState } from "../redux/slices/polylineLayerVisibleSlice";
|
|
import { useRecoilValue } from "recoil";
|
|
|
|
const protocol = window.location.protocol; // z. B. 'http:' oder 'https:'
|
|
const hostname = window.location.hostname; // z. B. 'example.com'
|
|
const originWithoutPort = `${protocol}//${hostname}`; // z. B. 'https://example.com'
|
|
const BASE_URL = `${originWithoutPort}/talas5/devices/`; // Dynamische Basis-URL
|
|
|
|
// Funktion zum Deaktivieren der Polyline-Ereignisse
|
|
export function disablePolylineEvents(polylines) {
|
|
polylines.forEach((polyline) => {
|
|
polyline.off("mouseover");
|
|
polyline.off("mouseout");
|
|
});
|
|
}
|
|
|
|
// Funktion zum Aktivieren der Polyline-Ereignisse
|
|
export function enablePolylineEvents(polylines, lineColors) {
|
|
// Überprüfe, ob polylines definiert ist und ob es Elemente enthält
|
|
if (!polylines || polylines.length === 0) {
|
|
//console.warn("Keine Polylinien vorhanden oder polylines ist undefined.");
|
|
return;
|
|
}
|
|
|
|
// Falls Polylinien vorhanden sind, wende die Events an
|
|
polylines.forEach((polyline) => {
|
|
polyline.on("mouseover", (e) => {
|
|
//console.log("Mouseover on polyline", polyline.options);
|
|
polyline.setStyle({ weight: 14 });
|
|
const link = `${BASE_URL}cpl.aspx?id=${polyline.options.idLD}`;
|
|
//localStorage.setItem("lastElementType", "polyline");
|
|
//localStorage.setItem("polylineLink", link);
|
|
});
|
|
|
|
polyline.on("mouseout", (e) => {
|
|
//console.log("Mouseout from polyline", polyline.options);
|
|
polyline.setStyle({ weight: 3 });
|
|
});
|
|
});
|
|
}
|
|
// Funktion zum Schließen des Kontextmenüs und Entfernen der Markierung
|
|
function closePolylineSelectionAndContextMenu(map) {
|
|
try {
|
|
// Entferne alle markierten Polylinien
|
|
if (window.selectedPolyline) {
|
|
window.selectedPolyline.setStyle({ weight: 3 }); // Originalstil wiederherstellen
|
|
window.selectedPolyline = null;
|
|
}
|
|
|
|
// Überprüfe, ob map und map.contextmenu definiert sind
|
|
if (map && map.contextmenu) {
|
|
map.contextmenu.hide(); // Kontextmenü schließen
|
|
} else {
|
|
console.warn("Kontextmenü ist nicht verfügbar.");
|
|
}
|
|
} catch (error) {
|
|
console.error("Fehler beim Schließen des Kontextmenüs:", error);
|
|
window.location.reload();
|
|
}
|
|
|
|
// Countdown-Status zurücksetzen
|
|
localStorage.removeItem("contextMenuCountdown");
|
|
localStorage.removeItem("contextMenuExpired");
|
|
}
|
|
|
|
// Überprüft regelmäßig den Status in localStorage
|
|
function monitorContextMenu(map) {
|
|
setInterval(() => {
|
|
const isContextMenuExpired = localStorage.getItem("contextMenuExpired") === "true";
|
|
if (isContextMenuExpired) {
|
|
closePolylineSelectionAndContextMenu(map);
|
|
localStorage.removeItem("contextMenuExpired"); // Flagge entfernen, um wiederverwendbar zu sein
|
|
}
|
|
}, 1000); // Alle 1 Sekunde überprüfen
|
|
}
|
|
|
|
export const setupPolylines = (map, linePositions, lineColors, tooltipContents, setNewCoords, tempMarker, currentZoom, currentCenter, polylineVisible) => {
|
|
if (localStorage.getItem("polylineVisible") === null) {
|
|
localStorage.setItem("polylineVisible", "true"); // Standardwert setzen
|
|
polylineVisible = true; // Wert in der Funktion initialisieren
|
|
} else {
|
|
polylineVisible = localStorage.getItem("polylineVisible") === "true";
|
|
}
|
|
|
|
if (!polylineVisible) {
|
|
// Entferne alle Polylinien, wenn sie ausgeblendet werden sollen
|
|
if (window.polylines) {
|
|
window.polylines.forEach((polyline) => {
|
|
if (map.hasLayer(polyline)) {
|
|
map.removeLayer(polyline);
|
|
}
|
|
});
|
|
}
|
|
return { markers: [], polylines: [] };
|
|
}
|
|
const markers = [];
|
|
const polylines = [];
|
|
const editMode = localStorage.getItem("editMode") === "true"; // Prüfen, ob der Bearbeitungsmodus aktiv ist
|
|
|
|
linePositions.forEach((lineData, lineIndex) => {
|
|
const lineMarkers = [];
|
|
|
|
lineData.coordinates.forEach((coord, index) => {
|
|
let icon = circleIcon;
|
|
if (index === 0) {
|
|
icon = startIcon;
|
|
} else if (index === lineData.coordinates.length - 1) {
|
|
icon = endIcon;
|
|
}
|
|
|
|
// Nur Marker mit circleIcon ausblenden, wenn Bearbeitungsmodus deaktiviert ist
|
|
if (icon !== circleIcon || editMode) {
|
|
const marker = L.marker(coord, {
|
|
icon: icon,
|
|
draggable: editMode, // Nur verschiebbar, wenn Bearbeitungsmodus aktiv ist
|
|
contextmenu: true,
|
|
contextmenuInheritItems: false,
|
|
contextmenuItems: [],
|
|
}).addTo(map);
|
|
|
|
marker.on("dragend", () => {
|
|
console.log("Marker wurde verschoben in setupPolylines.js");
|
|
if (editMode) {
|
|
const newCoords = marker.getLatLng();
|
|
setNewCoords(newCoords);
|
|
const newCoordinates = [...lineData.coordinates];
|
|
newCoordinates[index] = [newCoords.lat, newCoords.lng];
|
|
|
|
const updatedPolyline = L.polyline(newCoordinates, {
|
|
color: lineColors[`${lineData.idLD}-${lineData.idModul}`] || "#000000",
|
|
}).addTo(map);
|
|
|
|
updatedPolyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt", {
|
|
permanent: false,
|
|
direction: "auto",
|
|
});
|
|
|
|
updatedPolyline.on("mouseover", () => {
|
|
updatedPolyline.setStyle({ weight: 20 });
|
|
updatedPolyline.bringToFront();
|
|
});
|
|
|
|
updatedPolyline.on("mouseout", () => {
|
|
updatedPolyline.setStyle({ weight: 3 });
|
|
});
|
|
|
|
polylines[lineIndex].remove();
|
|
polylines[lineIndex] = updatedPolyline;
|
|
lineData.coordinates = newCoordinates;
|
|
|
|
const requestData = {
|
|
idModul: lineData.idModul,
|
|
idLD: lineData.idLD,
|
|
newCoordinates,
|
|
};
|
|
|
|
fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(requestData),
|
|
})
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
return response.json().then((data) => {
|
|
throw new Error(data.error || "Unbekannter Fehler");
|
|
});
|
|
}
|
|
return response.json();
|
|
})
|
|
.then((data) => {
|
|
console.log("Koordinaten erfolgreich aktualisiert:", data);
|
|
})
|
|
.catch((error) => {
|
|
console.error("Fehler beim Aktualisieren der Koordinaten:", error.message);
|
|
});
|
|
} else {
|
|
toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", {
|
|
position: "top-center",
|
|
autoClose: 5000,
|
|
hideProgressBar: false,
|
|
closeOnClick: true,
|
|
pauseOnHover: true,
|
|
draggable: true,
|
|
progress: undefined,
|
|
});
|
|
}
|
|
});
|
|
|
|
marker.on("mouseover", function () {
|
|
this.bindContextMenu({
|
|
contextmenuItems: [
|
|
{
|
|
text: "Stützpunkt entfernen",
|
|
icon: "/img/icons/gisLines/remove-support-point.svg",
|
|
callback: () => {
|
|
if (editMode) {
|
|
const newCoords = marker.getLatLng();
|
|
const newCoordinates = [...lineData.coordinates];
|
|
newCoordinates[index] = [newCoords.lat, newCoords.lng];
|
|
|
|
removePOI(marker, lineData, currentZoom, currentCenter);
|
|
polylines[lineIndex].remove();
|
|
lineData.coordinates = newCoordinates;
|
|
} else {
|
|
toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", {
|
|
position: "top-center",
|
|
autoClose: 5000,
|
|
hideProgressBar: false,
|
|
closeOnClick: true,
|
|
pauseOnHover: true,
|
|
draggable: true,
|
|
progress: undefined,
|
|
});
|
|
}
|
|
},
|
|
},
|
|
],
|
|
});
|
|
});
|
|
|
|
marker.on("mouseout", function () {
|
|
this.unbindContextMenu();
|
|
});
|
|
|
|
lineMarkers.push(marker);
|
|
}
|
|
});
|
|
|
|
const polyline = L.polyline(lineData.coordinates, {
|
|
color: lineColors[`${lineData.idLD}-${lineData.idModul}`] || "#000000",
|
|
weight: 3,
|
|
contextmenu: true,
|
|
contextmenuInheritItems: false, // Standard-Kontextmenü deaktivieren
|
|
contextmenuItems: [],
|
|
}).addTo(map);
|
|
|
|
// Füge "Stützpunkt hinzufügen" nur hinzu, wenn editMode aktiv ist
|
|
if (editMode) {
|
|
polyline.options.contextmenuItems.push(
|
|
{
|
|
text: "Station öffnen (Tab)",
|
|
icon: "/img/screen_new.png",
|
|
callback: (e) => {
|
|
const link = `${BASE_URL}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
|
|
window.open(link, "_blank");
|
|
},
|
|
},
|
|
{ separator: true },
|
|
|
|
{
|
|
text: "Koordinaten anzeigen",
|
|
icon: "/img/not_listed_location.png",
|
|
callback: (e) => {
|
|
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5));
|
|
},
|
|
},
|
|
{ separator: true },
|
|
{
|
|
text: "Reinzoomen",
|
|
icon: "/img/zoom_in.png",
|
|
callback: (e) => map.zoomIn(),
|
|
},
|
|
{
|
|
text: "Rauszoomen",
|
|
icon: "/img/zoom_out.png",
|
|
callback: (e) => map.zoomOut(),
|
|
},
|
|
{
|
|
text: "Hier zentrieren",
|
|
icon: "/img/center_focus.png",
|
|
callback: (e) => map.panTo(e.latlng),
|
|
},
|
|
{ separator: true },
|
|
{
|
|
text: "POI hinzufügen",
|
|
icon: "/img/add_station.png",
|
|
callback: (e) => {
|
|
// Hier kannst du die Logik für das Hinzufügen eines POIs implementieren
|
|
alert("POI hinzufügen an: " + e.latlng);
|
|
},
|
|
},
|
|
{
|
|
text: "Stützpunkt hinzufügen",
|
|
icon: "/img/icons/gisLines/add-support-point.svg",
|
|
callback: (e) => {
|
|
if (tempMarker) {
|
|
tempMarker.remove();
|
|
}
|
|
const newPoint = e.latlng;
|
|
const closestPoints = findClosestPoints(lineData.coordinates, newPoint, map);
|
|
insertNewPOI(closestPoints, newPoint, lineData, map);
|
|
redrawPolyline(lineData, lineColors, tooltipContents, map);
|
|
window.location.reload();
|
|
},
|
|
}
|
|
);
|
|
} else {
|
|
polyline.options.contextmenuItems.push(
|
|
{
|
|
text: "Station öffnen (Tab)",
|
|
icon: "/img/screen_new.png",
|
|
callback: (e) => {
|
|
const link = `${BASE_URL}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
|
|
window.open(link, "_blank");
|
|
},
|
|
},
|
|
{ separator: true },
|
|
|
|
{
|
|
text: "Koordinaten anzeigen",
|
|
icon: "/img/not_listed_location.png",
|
|
callback: (e) => {
|
|
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5));
|
|
},
|
|
},
|
|
{ separator: true },
|
|
{
|
|
text: "Reinzoomen",
|
|
icon: "/img/zoom_in.png",
|
|
callback: (e) => map.zoomIn(),
|
|
},
|
|
{
|
|
text: "Rauszoomen",
|
|
icon: "/img/zoom_out.png",
|
|
callback: (e) => map.zoomOut(),
|
|
},
|
|
|
|
{
|
|
text: "Hier zentrieren",
|
|
icon: "/img/center_focus.png",
|
|
callback: (e) => map.panTo(e.latlng),
|
|
},
|
|
{ separator: true },
|
|
{
|
|
text: "POI hinzufügen",
|
|
icon: "/img/add_station.png",
|
|
callback: (e) => {
|
|
// Hier kannst du die Logik für das Hinzufügen eines POIs implementieren
|
|
alert("POI hinzufügen an: " + e.latlng);
|
|
},
|
|
}
|
|
);
|
|
}
|
|
|
|
// Hier wird der Tooltip hinzugefügt
|
|
polyline.bindTooltip(tooltipContents[`${lineData.idLD}-${lineData.idModul}`] || "Standard-Tooltip-Inhalt", {
|
|
permanent: false,
|
|
direction: "auto",
|
|
});
|
|
|
|
polyline.on("mouseover", (e) => {
|
|
const startTime = Date.now(); // Startzeit erfassen
|
|
localStorage.setItem("contextMenuStartTime", startTime); // Speichern in localStorage
|
|
|
|
// Starte einen Intervall-Timer, um die Differenz zu berechnen
|
|
/* const countdownInterval = setInterval(() => {
|
|
const currentTime = Date.now();
|
|
const elapsedTime = (currentTime - startTime) / 1000; // Differenz in Sekunden
|
|
|
|
// Speichern der abgelaufenen Zeit in localStorage
|
|
localStorage.setItem("contextMenuCountdown", elapsedTime);
|
|
|
|
// Wenn die Zeit 17 Sekunden erreicht, schließe das Menü
|
|
if (elapsedTime >= 17) {
|
|
clearInterval(countdownInterval);
|
|
const contextMenu = map.contextmenu; // Zugriff auf das Kontextmenü
|
|
contextMenu.hide(); // Kontextmenü schließen
|
|
}
|
|
}, 1000); */
|
|
// Jede Sekunde
|
|
//console.log("Mouseover on polyline", lineData);
|
|
polyline.setStyle({ weight: 14 });
|
|
const link = `${BASE_URL}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
|
|
//console.log("Link der Linie:", link);
|
|
|
|
//localStorage.setItem("lastElementType", "polyline");
|
|
localStorage.setItem("Link_der_Linie:", link);
|
|
});
|
|
|
|
polyline.on("mouseout", (e) => {
|
|
// console.log("Mouseout from polyline", lineData);
|
|
polyline.setStyle({ weight: 3 });
|
|
// Setze den Countdown auf 0, wenn mouseout ausgelöst wird
|
|
localStorage.setItem("contextMenuCountdown", 0);
|
|
});
|
|
// Speichere den Link bei einem Rechtsklick (Kontextmenü)
|
|
/*
|
|
polyline.on("contextmenu", (e) => {
|
|
const link = `${process.env.NEXT_PUBLIC_BASE_URL}cpl.aspx?ver=35&kue=24&id=${lineData.idLD}`;
|
|
console.log("Link der Linie (via Rechtsklick):", link);
|
|
localStorage.setItem("lastElementType", "polyline");
|
|
localStorage.setItem("polylineLink", link);
|
|
});
|
|
*/
|
|
// Starte den Timer zum Schließen des Kontextmenüs nach 15 Sekunden
|
|
polyline.on("contextmenu", function (e) {
|
|
const contextMenu = this._map.contextmenu; // Zugriff auf das Kontextmenü
|
|
const closeMenu = () => contextMenu.hide(); // Funktion zum Schließen des Menüs
|
|
|
|
const countdown = parseInt(localStorage.getItem("contextMenuCountdown"), 30);
|
|
if (countdown >= 28) {
|
|
closeMenu();
|
|
}
|
|
});
|
|
|
|
polylines.push(polyline);
|
|
markers.push(...lineMarkers);
|
|
});
|
|
|
|
// Speichere Polylines und LineColors global für den Zugriff in anderen Funktionen
|
|
window.polylines = polylines;
|
|
window.lineColors = lineColors;
|
|
monitorContextMenu(map);
|
|
return { markers, polylines };
|
|
};
|