Merge pull request 'feature/start-end-line-marker' (#1) from feature/start-end-line-marker into develop
Reviewed-on: http://10.10.0.12:3000/ISA/nodeMap/pulls/1
This commit is contained in:
3
.babelrc
Normal file
3
.babelrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["@babel/preset-env", "@babel/preset-react"]
|
||||
}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,3 +26,4 @@ trace
|
||||
|
||||
# Ignore specific Next.js build files
|
||||
pages-manifest.json
|
||||
nodeMap für 13 am 16.07.2024.zip
|
||||
|
||||
32
Jenkinsfile
vendored
Normal file
32
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Install Dependencies') {
|
||||
steps {
|
||||
// Installiere npm Abhängigkeiten
|
||||
sh 'npm install'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Run Tests') {
|
||||
steps {
|
||||
// Führt Ihre Tests aus
|
||||
sh 'npm test'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
// Archivieren Sie die Testberichte, wenn verfügbar
|
||||
junit '**/test-results.xml'
|
||||
}
|
||||
success {
|
||||
echo 'Die Tests wurden erfolgreich abgeschlossen!'
|
||||
}
|
||||
failure {
|
||||
echo 'Einige Tests sind fehlgeschlagen.'
|
||||
}
|
||||
}
|
||||
}
|
||||
12
__mocks__/leaflet.js
Normal file
12
__mocks__/leaflet.js
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
map: () => ({
|
||||
setView: jest.fn(),
|
||||
addLayer: jest.fn(),
|
||||
}),
|
||||
tileLayer: () => ({
|
||||
addTo: jest.fn(),
|
||||
}),
|
||||
marker: () => ({
|
||||
addTo: jest.fn(),
|
||||
}),
|
||||
};
|
||||
89
__tests__/MapComponent.test.js
Normal file
89
__tests__/MapComponent.test.js
Normal file
@@ -0,0 +1,89 @@
|
||||
// __tests__/MapComponent.test.js
|
||||
|
||||
// Ein einfacher Testfall, der sicherstellt, dass die Addition korrekt ist
|
||||
test("simple addition", () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = a + b;
|
||||
expect(c).toBe(3); // Überprüft, ob c gleich 3 ist
|
||||
});
|
||||
|
||||
//import L from "leaflet";
|
||||
//import { checkOverlappingMarkers } from "../utils/mapUtils"; // Passe den Pfad entsprechend an
|
||||
|
||||
/* describe("checkOverlappingMarkers", () => {
|
||||
let map;
|
||||
|
||||
beforeEach(() => {
|
||||
// Erstelle eine neue Leaflet-Karte für jeden Test
|
||||
map = L.map(document.createElement("div"));
|
||||
});
|
||||
|
||||
it("should group markers by coordinates and add plus icons for overlapping markers", () => {
|
||||
// Erstelle einige Beispielmarker
|
||||
const markers = [
|
||||
L.marker([51.505, -0.09]),
|
||||
L.marker([51.505, -0.09]),
|
||||
L.marker([51.51, -0.1]),
|
||||
];
|
||||
|
||||
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||
|
||||
// Rufe die Funktion auf
|
||||
checkOverlappingMarkers(map, markers, plusIcon);
|
||||
|
||||
// Überprüfe, dass die Marker zu Gruppen hinzugefügt wurden
|
||||
const overlappingGroups = map._layers;
|
||||
expect(Object.keys(overlappingGroups).length).toBeGreaterThan(0);
|
||||
|
||||
// Überprüfe, dass die Plus-Marker hinzugefügt wurden
|
||||
const plusMarkers = Object.values(overlappingGroups).filter(
|
||||
(layer) =>
|
||||
layer.options.icon &&
|
||||
layer.options.icon.options.className === "plus-icon"
|
||||
);
|
||||
expect(plusMarkers.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should handle non-array markers argument gracefully", () => {
|
||||
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||
|
||||
// Rufe die Funktion mit einem ungültigen Argument auf
|
||||
checkOverlappingMarkers(map, null, plusIcon);
|
||||
|
||||
// Stelle sicher, dass keine Marker hinzugefügt wurden
|
||||
const layers = map._layers;
|
||||
expect(Object.keys(layers).length).toBe(0);
|
||||
});
|
||||
|
||||
it("should not add plus markers if there are no overlaps", () => {
|
||||
// Erstelle einige Beispielmarker
|
||||
const markers = [
|
||||
L.marker([51.505, -0.09]),
|
||||
L.marker([51.51, -0.1]),
|
||||
L.marker([51.52, -0.12]),
|
||||
];
|
||||
|
||||
const plusIcon = L.divIcon({ className: "plus-icon" });
|
||||
|
||||
// Rufe die Funktion auf
|
||||
checkOverlappingMarkers(map, markers, plusIcon);
|
||||
|
||||
// Überprüfe, dass keine Plus-Marker hinzugefügt wurden
|
||||
const plusMarkers = Object.values(map._layers).filter(
|
||||
(layer) =>
|
||||
layer.options.icon &&
|
||||
layer.options.icon.options.className === "plus-icon"
|
||||
);
|
||||
expect(plusMarkers.length).toBe(0);
|
||||
});
|
||||
}); */
|
||||
/*
|
||||
In diesem Test:
|
||||
|
||||
Wird eine neue Leaflet-Karte vor jedem Test erstellt.
|
||||
checkOverlappingMarkers wird aufgerufen, um zu überprüfen, ob die Funktion die Marker richtig gruppiert und Plus-Icons für überlappende Marker hinzufügt.
|
||||
Der Test überprüft auch, ob die Funktion ungültige Argumente (wie null für Marker) korrekt behandelt.
|
||||
Es wird sichergestellt, dass keine Plus-Marker hinzugefügt werden, wenn keine Überlappungen vorliegen.
|
||||
Stelle sicher, dass du die Pfade und Importe entsprechend deiner Projektstruktur anpasst.
|
||||
*/
|
||||
3
babel.config.js
Normal file
3
babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ["@babel/preset-env", "@babel/preset-react"],
|
||||
};
|
||||
13
components/CircleIcon.js
Normal file
13
components/CircleIcon.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// /components/CircleIcon.js
|
||||
// Custom circle icon for draggable markers
|
||||
import L from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
|
||||
const circleIcon = L.divIcon({
|
||||
className: "custom-div-icon",
|
||||
html: "<div style='background-color:gray;border-radius:50%;width:10px;height:10px;border: solid black 1px;'></div>",
|
||||
iconSize: [25, 25],
|
||||
iconAnchor: [5, 5],
|
||||
});
|
||||
|
||||
export default circleIcon;
|
||||
10
components/EndIcon.js
Normal file
10
components/EndIcon.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// Custom circle icon for draggable markers
|
||||
import L from "leaflet";
|
||||
const endIcon = L.divIcon({
|
||||
className: "custom-end-icon",
|
||||
html: "<div style='background-color: gray; width: 14px; height: 14px; border: solid black 2px;'></div>", // Graues Viereck
|
||||
iconSize: [14, 14],
|
||||
iconAnchor: [7, 7], // Mittelpunkt des Vierecks als Anker
|
||||
});
|
||||
|
||||
export default endIcon;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
// pages/api/poiUpdateModal.js
|
||||
//
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { selectedPoiState } from "../store/atoms/poiState";
|
||||
@@ -15,52 +15,24 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||
const [deviceName, setDeviceName] = useState("");
|
||||
const [idLD, setIdLD] = useState(poiData ? poiData.idLD : "");
|
||||
const [idLocationDevice, setIdLocationDevice] = useState("");
|
||||
|
||||
const [description, setDescription] = useState(
|
||||
poiData ? poiData.description : ""
|
||||
);
|
||||
|
||||
// Log the initial POI data
|
||||
useEffect(() => {
|
||||
if (poiData) {
|
||||
console.log("Initial poiData:", poiData);
|
||||
setPoiId(poiData.idPoi);
|
||||
setName(poiData.name);
|
||||
setPoiTypeId(poiData.idPoiTyp);
|
||||
setIdLD(poiData.idLD);
|
||||
|
||||
setDescription(poiData.description);
|
||||
setDeviceName(poiData.idLD);
|
||||
console.log("Loaded POI Data for editing:", poiData);
|
||||
console.log("POI ID:", poiData.idPoi);
|
||||
console.log("POI Name:", poiData.name);
|
||||
console.log("POI Typ ID:", poiData.idPoiTyp);
|
||||
console.log("POI Beschreibung:", poiData.description);
|
||||
console.log("POI Geräte-ID:", poiData.idLD);
|
||||
}
|
||||
}, [poiData]);
|
||||
|
||||
/* const fetchDeviceNameById = async (idLD) => {
|
||||
try {
|
||||
const response = await fetch(`/api/getDeviceNameById?idLD=${idLD}`);
|
||||
const data = await response.json();
|
||||
setDeviceName(data.deviceName);
|
||||
} catch (error) {
|
||||
console.error("Error fetching device name:", error);
|
||||
}
|
||||
}; */
|
||||
|
||||
/* const fetchDeviceNameById = async (idLD) => {
|
||||
try {
|
||||
const response = await fetch(`/api/talas_v5_DB/locationDevice/locationDeviceNameById?idLD=${idLD}`);
|
||||
const data = await response.json();
|
||||
setDeviceName(data.deviceName);
|
||||
} catch (error) {
|
||||
console.error("Error fetching device name:", error);
|
||||
}
|
||||
}; */
|
||||
|
||||
// Beim Öffnen des Modals die Geräte-ID basierend auf dem Gerätenamen abrufen, wenn vorhanden
|
||||
useEffect(() => {
|
||||
const fetchDeviceId = async () => {
|
||||
if (poiData && poiData.idLD) {
|
||||
@@ -82,7 +54,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
fetchDeviceId();
|
||||
}, [poiData]);
|
||||
|
||||
// Function to handle deleting a POI
|
||||
const handleDeletePoi = async () => {
|
||||
if (confirm("Sind Sie sicher, dass Sie diesen POI löschen möchten?")) {
|
||||
try {
|
||||
@@ -94,8 +65,7 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
);
|
||||
if (response.ok) {
|
||||
alert("POI wurde erfolgreich gelöscht.");
|
||||
onClose(); // Close the modal
|
||||
//Browser neu laden, um die aktualisierte Liste anzuzeigen
|
||||
onClose();
|
||||
window.location.reload();
|
||||
} else {
|
||||
throw new Error("Fehler beim Löschen des POI.");
|
||||
@@ -107,7 +77,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Fetch POI types
|
||||
useEffect(() => {
|
||||
const fetchPoiTypData = async () => {
|
||||
try {
|
||||
@@ -127,22 +96,20 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
fetchPoiTypData();
|
||||
}, [selectedPoi]);
|
||||
|
||||
// Fetch device data um den Gerät Namen in den dropdown menu anzuzeigen also erstmal die Liste der Geräte abrufen
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/talas_v5/location_device");
|
||||
// const response = await fetch("/api/talas_v5/location_device"); //"/api/talas_v5_DB/locationDevice/location_device"
|
||||
const response = await fetch(
|
||||
"/api/talas_v5_DB/locationDevice/locationDevices"
|
||||
);
|
||||
const data = await response.json();
|
||||
//console.log("Standort- und Gerätedaten:", data);
|
||||
setLocationDeviceData(data);
|
||||
console.log("Standort- und Gerätedaten poiData:", poiData);
|
||||
if (poiData && poiData.idLD) {
|
||||
const selectedDevice = data.find(
|
||||
(device) => device.id === poiData.idLD
|
||||
);
|
||||
setDeviceName(selectedDevice ? selectedDevice.id : data[0].id); // Hier wird die ID als initialer Zustand gesetzt
|
||||
console.log("Selected Device:", selectedDevice);
|
||||
console.log("Selected devciceName:", deviceName);
|
||||
setDeviceName(selectedDevice ? selectedDevice.id : data[0].id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
@@ -153,18 +120,12 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Fetch device name basierend auf der Geräte-ID
|
||||
|
||||
useEffect(() => {
|
||||
console.log("currentPoi von PoiUpdateModal.js : ", currentPoi.idLD);
|
||||
fetch("/api/talas_v5_DB/locationDevice/locationDevices")
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
setLocationDeviceData(data);
|
||||
console.log("Standort- und Gerätedaten 3:", data);
|
||||
console.log("Standort- und Gerätedaten 3 poiData:", poiData);
|
||||
// Findet das Gerät, das der aktuellen IDLD entspricht
|
||||
const currentDevice = data.find(
|
||||
(device) => device.idLD === currentPoi.idLD
|
||||
);
|
||||
@@ -178,10 +139,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
});
|
||||
}, [poiData?.idLD, currentPoi]);
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Angenommen, deviceName enthält die Geräte-ID
|
||||
//const idLD = deviceName; // Stellen Sie sicher, dass dies eine ID ist und kein Name
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
const idLDResponse = await fetch(
|
||||
@@ -201,7 +158,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
description: description,
|
||||
idPoiTyp: poiTypeId,
|
||||
idLD: idLD,
|
||||
//idLD: parseInt(deviceName, 10), // Konvertieren in eine Ganzzahl
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -220,19 +176,6 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
}
|
||||
};
|
||||
|
||||
//ausgewählte poi Informationen in Console anzeigen
|
||||
console.log("Selected POI:", selectedPoi);
|
||||
console.log("Selected POI Gerät id in poiUpdateModal.js:", selectedPoi.id);
|
||||
console.log("Selected POI Typ name in poiUpdateModal.js:", selectedPoi.typ); //als Typ in dropdown menu
|
||||
console.log(
|
||||
"Selected POI Beschreibung in poiUpdateModal.js:",
|
||||
selectedPoi.description
|
||||
);
|
||||
console.log(
|
||||
"Selected POI Gerät deviceId in poiUpdateModal.js:",
|
||||
selectedPoi.deviceId
|
||||
);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="m-0 p-2 w-full">
|
||||
<div className="flex items-center mb-4">
|
||||
@@ -261,16 +204,11 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
onChange={(e) => setDeviceName(e.target.value)}
|
||||
className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm"
|
||||
>
|
||||
{locationDeviceData.map(
|
||||
(device, index) => (
|
||||
console.log("device.id und name:", device),
|
||||
(
|
||||
<option key={index} value={device.id}>
|
||||
{device.name}
|
||||
</option>
|
||||
)
|
||||
)
|
||||
)}
|
||||
{locationDeviceData.map((device, index) => (
|
||||
<option key={index} value={device.id}>
|
||||
{device.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -294,7 +232,7 @@ const PoiUpdateModal = ({ onClose, poiData }) => {
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button" // Use button type to prevent form submission
|
||||
type="button"
|
||||
onClick={handleDeletePoi}
|
||||
className="bg-red-400 hover:bg-red-600 text-white font-bold py-2 px-4 rounded w-full mb-4"
|
||||
>
|
||||
|
||||
@@ -109,6 +109,9 @@ const ShowAddStationPopup = ({ onClose, map, latlng }) => {
|
||||
onClose();
|
||||
return newTrigger;
|
||||
});
|
||||
|
||||
// Browser aktualisieren
|
||||
window.location.reload();
|
||||
} else {
|
||||
console.error("Fehler beim Hinzufügen des POI");
|
||||
}
|
||||
@@ -117,6 +120,7 @@ const ShowAddStationPopup = ({ onClose, map, latlng }) => {
|
||||
map.closePopup();
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------handleSubmit-------------------
|
||||
|
||||
return (
|
||||
|
||||
16
components/StartIcon.js
Normal file
16
components/StartIcon.js
Normal file
@@ -0,0 +1,16 @@
|
||||
// Custom triangle icon for draggable markers
|
||||
import L from "leaflet";
|
||||
|
||||
const startIcon = L.divIcon({
|
||||
className: "custom-start-icon",
|
||||
html: `
|
||||
<svg width="18" height="18" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<polygon points="10,2 18,18 2,18" fill="black" />
|
||||
<polygon points="10,5 16,16 4,16" fill="gray" />
|
||||
</svg>
|
||||
`, // Schwarzes Dreieck innerhalb eines grauen Dreiecks
|
||||
iconSize: [18, 18],
|
||||
iconAnchor: [9, 18],
|
||||
});
|
||||
|
||||
export default startIcon;
|
||||
22
components/useMapContextMenu.js
Normal file
22
components/useMapContextMenu.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useState, useCallback } from "react";
|
||||
|
||||
const useMapContextMenu = (map, hasRights, addStationCallback) => {
|
||||
const [menuItemAdded, setMenuItemAdded] = useState(false);
|
||||
|
||||
const addItemsToMapContextMenu = useCallback(() => {
|
||||
if (map && !menuItemAdded) {
|
||||
map.contextmenu.addItem({
|
||||
text: "POI hinzufügen",
|
||||
icon: "img/add_station.png",
|
||||
className: "background-red",
|
||||
callback: (event) => addStationCallback(event, hasRights),
|
||||
});
|
||||
|
||||
setMenuItemAdded(true); // Menüpunkt wurde hinzugefült, Zustand aktualisieren
|
||||
}
|
||||
}, [map, menuItemAdded, hasRights, addStationCallback]);
|
||||
|
||||
return { addItemsToMapContextMenu };
|
||||
};
|
||||
|
||||
export default useMapContextMenu;
|
||||
@@ -1,11 +1,14 @@
|
||||
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||
// /config/config.js
|
||||
|
||||
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||
const mapVersion = "0.5.3"; // Die Version der verwendeten Karte
|
||||
const standardSideMenu = true; // Einstellung, ob ein standardmäßiges Seitenmenü verwendet wird
|
||||
const fullSideMenu = false; // Einstellung, ob ein vollständiges Seitenmenü verwendet wird
|
||||
const serverURL = "/api"; // Die Basis-URL des Servers, von dem Daten bezogen werden
|
||||
|
||||
//const serverURL = "/api"; // Die Basis-URL des Servers, von dem Daten bezogen werden
|
||||
const serverURL = "http://10.10.0.13";
|
||||
console.log("serverURL in config:", serverURL);
|
||||
// Initialisieren von Variablen, die später im Browserkontext gesetzt werden
|
||||
let windowHeight, url_string, url, c, user;
|
||||
let windowHeight, url_string, url, idMap, idUser;
|
||||
//Online Daten
|
||||
let mapGisStationsStaticDistrictUrl,
|
||||
mapGisStationsStatusDistrictUrl,
|
||||
@@ -20,28 +23,30 @@ if (typeof window !== "undefined") {
|
||||
windowHeight = window.innerHeight; // Die Höhe des Browserfensters
|
||||
url_string = window.location.href; // Die vollständige URL als String
|
||||
url = new URL(url_string); // Die URL als URL-Objekt, um Teile der URL einfacher zu handhaben
|
||||
c = url.searchParams.get("m"); // Ein Parameter aus der URL, Standardwert ist '10'
|
||||
user = url.searchParams.get("u"); // Ein weiterer Parameter aus der URL, Standardwert ist '484 admin zu testen von Stationen ausblenden und einblenden in der Card'
|
||||
console.log("URL in config:", url);
|
||||
console.log("URL origin in config:", url.origin); //http://localhost:3000
|
||||
idMap = url.searchParams.get("m"); // Ein Parameter aus der URL, Standardwert ist '10'
|
||||
idUser = url.searchParams.get("u"); // Ein weiterer Parameter aus der URL, Standardwert ist '484 admin zu testen von Stationen ausblenden und einblenden in der Card'
|
||||
|
||||
console.log(`Parameter 'idMap' : ${c}`);
|
||||
console.log(`Parameter 'idUser': ${user}`);
|
||||
|
||||
console.log(`Parameter 'idMap' : ${c}`);
|
||||
console.log(`Parameter 'idUser': ${user}`);
|
||||
console.log(`Parameter 'idMap' : ${idMap}`);
|
||||
console.log(`Parameter 'idUser': ${idUser}`);
|
||||
|
||||
// Konstruktion von URLs, die auf spezifische Ressourcen auf dem Server zeigen
|
||||
//http://localhost:3000/?m=10&u=485
|
||||
|
||||
//-----------------Von WebService------------------------------------------------
|
||||
mapGisStationsStaticDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; //idMap: 10, idUser: 484
|
||||
mapGisStationsStatusDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`;
|
||||
mapGisStationsMeasurementsUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${c}`;
|
||||
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}`;
|
||||
mapGisStationsStaticDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`; //idMap: 10, idUser: 484
|
||||
mapGisStationsStatusDistrictUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`;
|
||||
mapGisStationsMeasurementsUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${idMap}`;
|
||||
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
|
||||
mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`;
|
||||
|
||||
//webserviceGisLinesStatusUrl = `http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${c}`;
|
||||
//webserviceGisLinesStatusUrl = `http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`;
|
||||
//webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
||||
//webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
||||
//webserviceGisLinesStatusUrl = `${"serverURL"}:3000/api/linesColorApi`;
|
||||
webserviceGisLinesStatusUrl = `http://localhost:3000/api/linesColorApi`;
|
||||
//webserviceGisLinesStatusUrl = `http://192.168.10.14/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${c}`;
|
||||
//webserviceGisLinesStatusUrl = `http://192.168.10.14/talas5/ClientData/WebServiceMap.asmx/GisLinesStatus?idMap=${idMap}`;
|
||||
|
||||
//http://10.10.0.13/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=12&idUser=484
|
||||
|
||||
@@ -51,11 +56,11 @@ if (typeof window !== "undefined") {
|
||||
mapGisSystemStaticUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic`;
|
||||
mapDataIconUrl = `${serverURL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`; */
|
||||
|
||||
/* mapGisStationsStaticDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`;
|
||||
mapGisStationsStatusDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`;
|
||||
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsMeasurements?idMap=${c}`;
|
||||
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/gisStationsMeasurementsSQL?idMap=${c}`;
|
||||
mapGisSystemStaticUrl = `${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${c}&idUser=${user}`;
|
||||
/* mapGisStationsStaticDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStaticDistrict?idMap=${idMap}&idUser=${idUser}`;
|
||||
mapGisStationsStatusDistrictUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`;
|
||||
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/GisStationsMeasurements?idMap=${idMap}`;
|
||||
mapGisStationsMeasurementsUrl = `${serverURL}/api/talas5/webserviceMap/gisStationsMeasurementsSQL?idMap=${idMap}`;
|
||||
mapGisSystemStaticUrl = `${serverURL}/api/talas5/webserviceMap/GisSystemStatic?idMap=${idMap}&idUser=${idUser}`;
|
||||
mapDataIconUrl = `${serverURL}/api/talas5/webserviceMap/GetIconsStatic`; */
|
||||
}
|
||||
|
||||
@@ -68,8 +73,8 @@ export {
|
||||
windowHeight,
|
||||
url_string,
|
||||
url,
|
||||
c,
|
||||
user,
|
||||
idMap,
|
||||
idUser,
|
||||
mapGisStationsStaticDistrictUrl,
|
||||
mapGisStationsStatusDistrictUrl,
|
||||
mapGisStationsMeasurementsUrl,
|
||||
@@ -77,3 +82,9 @@ export {
|
||||
mapDataIconUrl,
|
||||
webserviceGisLinesStatusUrl,
|
||||
};
|
||||
|
||||
/*
|
||||
Access to fetch at 'http://localhost:3000/api/linesColorApi' from origin 'http://10.10.0.13:3000' has been blocked by CORS policy:
|
||||
No 'Access-Control-Allow-Origin' header is present on the requested resource.
|
||||
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
|
||||
*/
|
||||
|
||||
17
config/layers.js
Normal file
17
config/layers.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import L from "leaflet";
|
||||
|
||||
export const MAP_LAYERS = {
|
||||
TALAS: new L.layerGroup(),
|
||||
ECI: new L.layerGroup(),
|
||||
ULAF: new L.layerGroup(),
|
||||
GSMModem: new L.layerGroup(),
|
||||
CiscoRouter: new L.layerGroup(),
|
||||
WAGO: new L.layerGroup(),
|
||||
Siemens: new L.layerGroup(),
|
||||
OTDR: new L.layerGroup(),
|
||||
WDM: new L.layerGroup(),
|
||||
GMA: new L.layerGroup(),
|
||||
Sonstige: new L.layerGroup(),
|
||||
TALASICL: new L.layerGroup(),
|
||||
lineLayer: new L.LayerGroup(),
|
||||
};
|
||||
5
config/settings.js
Normal file
5
config/settings.js
Normal file
@@ -0,0 +1,5 @@
|
||||
// /config/settings.js
|
||||
// Definieren der grundlegenden Umgebungseinstellungen und Konfigurationen der Karte
|
||||
export const MAP_VERSION = "1.0.0";
|
||||
//export const STANDARD_SIDE_MENU = true;
|
||||
//export const FULL_SIDE_MENU = false;
|
||||
36
config/urls.js
Normal file
36
config/urls.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// /sonstige/urls.js
|
||||
|
||||
// BASE_URL für Station öffnen in neuer tab und gleicher tab, im localhost gab es keine Probleme mit der Frame
|
||||
//export const BASE_URL = "http://10.10.0.13/talas5/devices/";
|
||||
//const baseUrl = "http://localhost:3000/talas5/devices/";
|
||||
//const baseUrl = "http://192.168.10.14/talas5/devices/";
|
||||
//----
|
||||
//Talas_v5 Server
|
||||
//export const OFFLINE_TILE_LAYER = "/mapTiles/{z}/{x}/{y}.png"; // wenn im von localhost also selben Server die Karte angezeigt wird
|
||||
//export const OFFLINE_TILE_LAYER = "/mapTiles/{z}/{x}/{y}.png";
|
||||
export const BASE_URL = "http://10.10.0.13/talas5/devices/";
|
||||
export const OFFLINE_TILE_LAYER = "/mapTiles/{z}/{x}/{y}.png";
|
||||
export const ONLINE_TILE_LAYER =
|
||||
"http://10.10.0.13:3000/mapTiles/{z}/{x}/{y}.png"; //Talas_v5 Server */
|
||||
//-----------------------------------
|
||||
// weil ich keine API habe, ansonsten serverURL ist localhost(IP-Adresse) für GisSystemStatic für die Benutzerrechte
|
||||
//const serverURL = `${protocol}//${hostname}`;
|
||||
//const serverURL = `${protocol}//${hostname}${port ? `:${port}` : ""}`;
|
||||
//const serverURL = "http://localhost:3000";
|
||||
export const SERVER_URL = "http://10.10.0.13";
|
||||
|
||||
// Online Daten URLs
|
||||
/* export const MAP_GIS_STATIONS_STATIC_DISTRICT_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStaticDistrict?idMap=${c}&idUser=${user}`; //idMap: 10, idUser: 484
|
||||
export const MAP_GIS_STATIONS_STATUS_DISTRICT_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsStatusDistrict?idMap=${c}&idUser=${user}`;
|
||||
export const MAP_GIS_STATIONS_MEASUREMENTS_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisStationsMeasurements?idMap=${c}`;
|
||||
export const MAP_GIS_SYSTEM_STATIC_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${c}&idUser=${user}`;
|
||||
export const MAP_DATA_ICON_URL = `${SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GetIconsStatic`;
|
||||
export const WEBSERVICE_GIS_LINES_STATUS_URL =
|
||||
"http://localhost:3000/api/linesColorApi";
|
||||
*/
|
||||
|
||||
/*
|
||||
Access to fetch at 'http://localhost:3000/api/linesColorApi' from origin 'http://10.10.0.13:3000' has been blocked by CORS policy:
|
||||
No 'Access-Control-Allow-Origin' header is present on the requested resource.
|
||||
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
|
||||
*/
|
||||
13
jest.config.js
Normal file
13
jest.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
setupFilesAfterEnv: ["<rootDir>/setupTests.js"],
|
||||
transform: {
|
||||
"^.+\\.(js|jsx)$": "babel-jest",
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
"/node_modules/(?!(@react-leaflet|react-leaflet|leaflet)/)",
|
||||
],
|
||||
testEnvironment: "jsdom",
|
||||
moduleNameMapper: {
|
||||
"\\.(css|less|scss|sass)$": "identity-obj-proxy",
|
||||
},
|
||||
};
|
||||
1
jest.setup.js
Normal file
1
jest.setup.js
Normal file
@@ -0,0 +1 @@
|
||||
import "@testing-library/jest-dom";
|
||||
Binary file not shown.
7834
package-lock.json
generated
7834
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -10,8 +10,9 @@
|
||||
"mysql": "^2.18.1",
|
||||
"mysql2": "^3.10.1",
|
||||
"next": "^14.2.3",
|
||||
"nextjs-cors": "^2.2.0",
|
||||
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
|
||||
"react": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-toastify": "^10.0.5",
|
||||
@@ -21,15 +22,26 @@
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"export": "next export"
|
||||
"export": "next export",
|
||||
"test": "jest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.7",
|
||||
"@babel/preset-env": "^7.24.7",
|
||||
"@babel/preset-react": "^7.24.7",
|
||||
"@testing-library/jest-dom": "^6.4.6",
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@types/leaflet": "^1.9.12",
|
||||
"@types/leaflet-contextmenu": "^1.4.3",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"babel-jest": "^29.7.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-css-modules-transform": "^4.4.2",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"postcss": "^8.4.39",
|
||||
"prettier": "^3.2.5",
|
||||
"tailwindcss": "^3.4.3"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Pfad: pages/_app.js
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import React from "react";
|
||||
import { RecoilRoot } from "recoil";
|
||||
import "../styles/global.css";
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
|
||||
@@ -2,7 +2,18 @@
|
||||
// http://10.10.0.13/talas5/ClientData/WebServiceMap.asmx/GisStationsStatusDistrict
|
||||
//In DB gis_lines idLD und idModul anpassen entsprechend
|
||||
|
||||
export default function handler(req, res) {
|
||||
// /pages/api/linesColorApi.js
|
||||
import NextCors from "nextjs-cors";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
// Run the cors middleware
|
||||
await NextCors(req, res, {
|
||||
// Options
|
||||
methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"],
|
||||
origin: "*", // Erlauben Sie alle Ursprünge, oder geben Sie spezifische Ursprünge an
|
||||
optionsSuccessStatus: 200, // Legacy-Browser-Unterstützung für 204
|
||||
});
|
||||
|
||||
const response = {
|
||||
Name: "Liste aller Statis der Linien",
|
||||
Zeitstempel: new Date().toISOString(), // Aktuellen Zeitstempel hinzufügen
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// pages/index.js
|
||||
import { useEffect, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useRecoilState, useRecoilValue } from "recoil";
|
||||
import { readPoiMarkersStore } from "../store/selectors/readPoiMarkersStore"; // Aktualisiert mit atom
|
||||
import { readPoiMarkersStore } from "../store/selectors/readPoiMarkersStore";
|
||||
import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom";
|
||||
|
||||
const MapComponentWithNoSSR = dynamic(
|
||||
@@ -24,14 +23,12 @@ export default function Home() {
|
||||
}
|
||||
const data = await response.json();
|
||||
setLocations(data);
|
||||
//console.log("Geladene Daten in Home.js:", data);
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// URL-Parameter abfragen
|
||||
function getURLParameter(name) {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return params.get(name);
|
||||
@@ -39,10 +36,7 @@ export default function Home() {
|
||||
setMParam(getURLParameter("m"));
|
||||
setUParam(getURLParameter("u"));
|
||||
|
||||
// Daten beim Laden der Seite holen
|
||||
loadData();
|
||||
|
||||
//console.log("poiReadTrigger in Home.js:", poiReadTrigger);
|
||||
}, [poiReadTrigger]);
|
||||
|
||||
const handleAddLocation = async (name, type, lat, lng) => {
|
||||
@@ -56,8 +50,7 @@ export default function Home() {
|
||||
throw new Error("Fehler beim Hinzufügen des Standorts");
|
||||
}
|
||||
console.log("Standort erfolgreich hinzugefügt");
|
||||
loadData(); // Aktualisiere die Daten nach dem Hinzufügen
|
||||
console.log("poiReadTrigger in Home.js:", poiReadTrigger);
|
||||
loadData();
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
@@ -72,13 +65,11 @@ export default function Home() {
|
||||
)
|
||||
);
|
||||
};
|
||||
//------------------------------------
|
||||
// Daten beim Laden der Seite holen
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
//console.log("poiReadTrigger in Home.js:", poiReadTrigger);
|
||||
}, [poiReadTrigger]);
|
||||
//------------------------------------
|
||||
|
||||
return (
|
||||
<div>
|
||||
<MapComponentWithNoSSR
|
||||
|
||||
142
services/apiService.js
Normal file
142
services/apiService.js
Normal file
@@ -0,0 +1,142 @@
|
||||
// services/apiService.js
|
||||
import * as config from "../config/config";
|
||||
import { setPriorityConfig } from "../utils/utils";
|
||||
import * as urls from "../config/urls";
|
||||
|
||||
export const fetchGisStatusStations = async (idMap, idUser) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error: ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log("GisStatusStations:", data);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Daten:", error);
|
||||
throw error; // Fehler weiter werfen, um ihn in der Komponente behandeln zu können
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------
|
||||
export const fetchPriorityConfig = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/talas_v5_DB/priorityConfig");
|
||||
const data = await response.json();
|
||||
console.log("Prioritätskonfiguration:", data);
|
||||
setPriorityConfig(data);
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Laden der Prioritätskonfiguration:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------
|
||||
export const fetchPoiData = async (idPoi) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/talas_v5_DB/pois/getPoiById?idPoi=${idPoi}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error("Fehler beim Abrufen der POI-Daten");
|
||||
}
|
||||
const data = await response.json();
|
||||
return {
|
||||
idPoi,
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der POI-Daten", error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// ----------------------------------------------
|
||||
// Funktion zum Aktualisieren der Position in der Datenbank
|
||||
export const updateLocationInDatabase = async (
|
||||
id,
|
||||
newLatitude,
|
||||
newLongitude
|
||||
) => {
|
||||
const response = await fetch("/api/talas_v5_DB/pois/updateLocation", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
id,
|
||||
latitude: newLatitude,
|
||||
longitude: newLongitude,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
//schreib die neue Kooridnaten in die Console
|
||||
//akuellisiere die Position in der Datenbank mit den neuen Koordinaten mit updateLocation mit SQL Anweisung UPDATE
|
||||
} else {
|
||||
console.error("Fehler beim Aktualisieren der Position");
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------
|
||||
// Funktionen zur Überwachung der Internetverbindung
|
||||
export const checkInternet = () => {
|
||||
fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" })
|
||||
.then((response) => setOnline(response.ok))
|
||||
.catch(() => setOnline(false));
|
||||
};
|
||||
|
||||
// ----------------------------------------------
|
||||
export const fetchDeviceNameById = async (idLD) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/talas_v5_DB/locationDevice/locationDeviceNameById?idLD=${idLD}`
|
||||
);
|
||||
const data = await response.json();
|
||||
if (response.ok) {
|
||||
return data.name;
|
||||
} else {
|
||||
throw new Error(data.error || "Gerät nicht gefunden");
|
||||
}
|
||||
} catch (error) {
|
||||
/* console.error(
|
||||
"Fehler beim Abrufen des Gerätenamens in MapComponent.js:",
|
||||
error
|
||||
); */
|
||||
return "Unbekannt";
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------
|
||||
// services/apiService.js
|
||||
export const fetchUserRights = async () => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${urls.SERVER_URL}/talas5/ClientData/WebserviceMap.asmx/GisSystemStatic?idMap=${config.idMap}&idUser=${config.idUser}`
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
// console.log("Benutzerrechte in fetchRights:", data);
|
||||
|
||||
// Überprüfen der Struktur der Antwort
|
||||
if (!data || !data.Rights || !Array.isArray(data.Rights)) {
|
||||
throw new Error("Invalid response structure");
|
||||
}
|
||||
|
||||
const rightsArray = data.Rights; // Nehmen an, dass 'Rights' das Array von Rechten ist
|
||||
//console.log("rightsArray in apiService:", rightsArray);
|
||||
|
||||
// Speichert die IDs der Rechte in einem Array
|
||||
const userRightsIds = rightsArray.map((right) => right.IdRight);
|
||||
|
||||
// Wenn alles gut geht, logge die erfolgreichen Abschluss
|
||||
// console.log("Benutzerrechte erfolgreich abgerufen:", userRightsIds);
|
||||
return userRightsIds;
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Benutzerrechte", error);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
2
setupTests.js
Normal file
2
setupTests.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// setupTests.js
|
||||
import "@testing-library/jest-dom";
|
||||
@@ -1,7 +1,9 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
purge: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
|
||||
content: [],
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
zIndex: {
|
||||
|
||||
33
utils/contextMenuUtils.js
Normal file
33
utils/contextMenuUtils.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// contextMenuUtils.js
|
||||
import { BASE_URL } from "../config/urls";
|
||||
export function addContextMenuToMarker(marker) {
|
||||
marker.unbindContextMenu(); // Entferne das Kontextmenü, um Duplikate zu vermeiden
|
||||
|
||||
marker.bindContextMenu({
|
||||
contextmenu: true,
|
||||
contextmenuWidth: 140,
|
||||
contextmenuItems: [
|
||||
/* {
|
||||
text: "Station öffnen (Tab)",
|
||||
icon: "/img/screen_new.png",
|
||||
callback: (e) => openInNewTab(e, marker),
|
||||
},
|
||||
{
|
||||
text: "Station öffnen",
|
||||
icon: "/img/screen_same.png",
|
||||
callback: (e) => openInSameWindow(e, marker),
|
||||
}, */
|
||||
],
|
||||
});
|
||||
}
|
||||
// Funktion zum Öffnen in einem neuen Tab
|
||||
export function openInNewTab(e, marker) {
|
||||
const baseUrl = BASE_URL;
|
||||
console.log("baseUrl:", baseUrl);
|
||||
if (marker && marker.options && marker.options.link) {
|
||||
//console.log("Marker data:", baseUrl + marker.options.link);
|
||||
window.open(baseUrl + marker.options.link, "_blank");
|
||||
} else {
|
||||
console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft");
|
||||
}
|
||||
}
|
||||
21
utils/geometryUtils.js
Normal file
21
utils/geometryUtils.js
Normal file
@@ -0,0 +1,21 @@
|
||||
export const parsePoint = (position) => {
|
||||
const [longitude, latitude] = position.slice(6, -1).split(" ");
|
||||
return { latitude: parseFloat(latitude), longitude: parseFloat(longitude) };
|
||||
};
|
||||
|
||||
export const findClosestPoints = (coordinates, newPoint, map) => {
|
||||
let minDist = Infinity;
|
||||
let closestPair = [];
|
||||
for (let i = 1; i < coordinates.length; i++) {
|
||||
const dist = L.LineUtil.pointToSegmentDistance(
|
||||
map.latLngToLayerPoint(newPoint),
|
||||
map.latLngToLayerPoint(coordinates[i - 1]),
|
||||
map.latLngToLayerPoint(coordinates[i])
|
||||
);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
closestPair = [coordinates[i - 1], coordinates[i], i];
|
||||
}
|
||||
}
|
||||
return closestPair;
|
||||
};
|
||||
111
utils/mapUtils.js
Normal file
111
utils/mapUtils.js
Normal file
@@ -0,0 +1,111 @@
|
||||
// /utils/mapUtils.js
|
||||
import L from "leaflet";
|
||||
|
||||
export const redrawPolyline = (lineData, lineColors, tooltipContents, map) => {
|
||||
if (!lineData || !lineColors || !tooltipContents || !map) {
|
||||
console.error("Invalid parameters for redrawPolyline");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lineData.coordinates || !Array.isArray(lineData.coordinates)) {
|
||||
console.error("Invalid coordinates in lineData");
|
||||
return;
|
||||
}
|
||||
|
||||
const color = lineColors[lineData.idModul] || "#000000";
|
||||
const tooltipContent =
|
||||
tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt";
|
||||
|
||||
if (lineData.polyline) map.removeLayer(lineData.polyline);
|
||||
|
||||
lineData.polyline = L.polyline(lineData.coordinates, {
|
||||
color: color,
|
||||
}).addTo(map);
|
||||
|
||||
lineData.polyline.bindTooltip(tooltipContent, {
|
||||
permanent: false,
|
||||
direction: "auto",
|
||||
});
|
||||
|
||||
lineData.polyline.on("mouseover", () => {
|
||||
lineData.polyline.setStyle({ weight: 10 });
|
||||
lineData.polyline.bringToFront();
|
||||
});
|
||||
|
||||
lineData.polyline.on("mouseout", () => {
|
||||
lineData.polyline.setStyle({ weight: 5 });
|
||||
});
|
||||
};
|
||||
|
||||
export const saveLineData = (lineData) => {
|
||||
fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
idModul: lineData.idModul,
|
||||
idLD: lineData.idLD,
|
||||
newCoordinates: lineData.coordinates,
|
||||
}),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Fehler beim Speichern der Linienänderungen");
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
console.log("Linienänderungen gespeichert:", data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Fehler beim Speichern der Linienänderungen:", error);
|
||||
});
|
||||
};
|
||||
// Call this function on page load to restore zoom and center
|
||||
export const restoreMapSettings = (map) => {
|
||||
const savedZoom = localStorage.getItem("mapZoom");
|
||||
const savedCenter = localStorage.getItem("mapCenter");
|
||||
|
||||
if (savedZoom && savedCenter) {
|
||||
try {
|
||||
const centerCoords = JSON.parse(savedCenter);
|
||||
map.setView(centerCoords, parseInt(savedZoom));
|
||||
} catch (e) {
|
||||
console.error("Error parsing stored map center:", e);
|
||||
map.setView([53.111111, 8.4625], 12); // Standardkoordinaten und -zoom
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Now update checkOverlappingMarkers to check if oms is initialized
|
||||
export const checkOverlappingMarkers = (map, markers, plusIcon) => {
|
||||
// Ensure markers is always an array
|
||||
if (!Array.isArray(markers)) {
|
||||
//console.error("The `markers` argument is not an array:", markers);
|
||||
return;
|
||||
}
|
||||
|
||||
const overlappingGroups = {};
|
||||
|
||||
// Group markers by coordinates as strings
|
||||
markers.forEach((marker) => {
|
||||
const latlngStr = marker.getLatLng().toString();
|
||||
if (overlappingGroups[latlngStr]) {
|
||||
overlappingGroups[latlngStr].push(marker);
|
||||
} else {
|
||||
overlappingGroups[latlngStr] = [marker];
|
||||
}
|
||||
});
|
||||
|
||||
// Add plus markers at coordinates where overlaps occur
|
||||
for (const coords in overlappingGroups) {
|
||||
if (overlappingGroups[coords].length > 1) {
|
||||
const latLng = L.latLng(coords.match(/[-.\d]+/g).map(Number));
|
||||
const plusMarker = L.marker(latLng, { icon: plusIcon });
|
||||
plusMarker.addTo(map);
|
||||
|
||||
//console.log("Adding plus icon marker at", latLng);
|
||||
}
|
||||
}
|
||||
};
|
||||
117
utils/markerUtils.js
Normal file
117
utils/markerUtils.js
Normal file
@@ -0,0 +1,117 @@
|
||||
// /utils/markerUtils.js
|
||||
import circleIcon from "../components/CircleIcon";
|
||||
import { saveLineData, redrawPolyline } from "./mapUtils";
|
||||
import L from "leaflet";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
export const insertNewMarker = (closestPoints, newPoint, lineData, map) => {
|
||||
const newMarker = L.marker(newPoint, {
|
||||
icon: circleIcon,
|
||||
draggable: true,
|
||||
}).addTo(map);
|
||||
lineData.coordinates.splice(closestPoints[2], 0, [
|
||||
newPoint.lat,
|
||||
newPoint.lng,
|
||||
]);
|
||||
|
||||
// Hier direkt speichern nach Einfügen
|
||||
saveLineData(lineData);
|
||||
|
||||
redrawPolyline(lineData);
|
||||
|
||||
// Event-Listener für das Verschieben des Markers hinzufügen
|
||||
newMarker.on("dragend", () => {
|
||||
const newCoords = newMarker.getLatLng();
|
||||
setNewCoords(newCoords);
|
||||
const newCoordinates = [...lineData.coordinates];
|
||||
newCoordinates[closestPoints[2]] = [newCoords.lat, newCoords.lng];
|
||||
lineData.coordinates = newCoordinates;
|
||||
redrawPolyline(lineData);
|
||||
|
||||
updateMarkerPosition(newMarker.getLatLng(), lineData, newMarker);
|
||||
saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben
|
||||
});
|
||||
};
|
||||
|
||||
export const removeMarker = (marker, lineData, currentZoom, currentCenter) => {
|
||||
// Save zoom and center to localStorage
|
||||
//localStorage.setItem("mapZoom", currentZoom);
|
||||
//localStorage.setItem("mapCenter", JSON.stringify(currentCenter));
|
||||
|
||||
// Find the index of the coordinate that matches the marker's position
|
||||
const index = lineData.coordinates.findIndex((coord) =>
|
||||
L.latLng(coord[0], coord[1]).equals(marker.getLatLng())
|
||||
);
|
||||
|
||||
if (index !== -1) {
|
||||
// Remove the coordinate from the line data
|
||||
lineData.coordinates.splice(index, 1);
|
||||
|
||||
// Redraw the polyline with the updated coordinates
|
||||
redrawPolyline(lineData);
|
||||
|
||||
// Remove the marker from the map
|
||||
marker.remove();
|
||||
|
||||
// Save the updated line data
|
||||
saveLineData(lineData);
|
||||
|
||||
// Refresh the browser
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
export const handleEditPoi = (
|
||||
marker,
|
||||
userRights,
|
||||
setCurrentPoiData,
|
||||
setShowPoiUpdateModal,
|
||||
fetchPoiData,
|
||||
toast // Hier toast als Parameter erhalten
|
||||
) => {
|
||||
console.log("Selected Marker ID (idPoi):", marker.options.id);
|
||||
console.log("Selected Marker Description:", marker.options.description);
|
||||
console.log("User Rights:", userRights);
|
||||
|
||||
// Sicherstellen, dass userRights ein Array ist
|
||||
if (!Array.isArray(userRights)) {
|
||||
console.error("User Rights is not an array:", userRights);
|
||||
toast.error("Benutzerrechte sind ungültig.", {
|
||||
position: "top-center",
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("User Rights includes 56:", userRights.includes(56));
|
||||
|
||||
// Prüfung, ob der Benutzer die notwendigen Rechte hat
|
||||
if (!userRights.includes(56)) {
|
||||
toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", {
|
||||
position: "top-center",
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
});
|
||||
console.log("Benutzer hat keine Berechtigung zum Bearbeiten.");
|
||||
return; // Beendet die Funktion frühzeitig, wenn keine Berechtigung vorliegt
|
||||
}
|
||||
|
||||
setCurrentPoiData({
|
||||
idPoi: marker.options.id,
|
||||
name: marker.options.name,
|
||||
description: marker.options.description,
|
||||
});
|
||||
|
||||
fetchPoiData(marker.options.id);
|
||||
|
||||
setShowPoiUpdateModal(true);
|
||||
};
|
||||
10
utils/openInSameWindow.js
Normal file
10
utils/openInSameWindow.js
Normal file
@@ -0,0 +1,10 @@
|
||||
// utils/openInSameWindow.js
|
||||
|
||||
export function openInSameWindow(e, marker, baseUrl) {
|
||||
if (marker && marker.options && marker.options.link) {
|
||||
//console.log("Marker data:", baseUrl + marker.options.link);
|
||||
window.location.href = baseUrl + marker.options.link;
|
||||
} else {
|
||||
console.error("Fehler: Marker hat keine gültige 'link' Eigenschaft");
|
||||
}
|
||||
}
|
||||
265
utils/utils.js
Normal file
265
utils/utils.js
Normal file
@@ -0,0 +1,265 @@
|
||||
// /utils/utils.js
|
||||
import { useState } from "react";
|
||||
import circleIcon from "../components/CircleIcon";
|
||||
|
||||
export const parsePoint = (position) => {
|
||||
const [longitude, latitude] = position.slice(6, -1).split(" ");
|
||||
return { latitude: parseFloat(latitude), longitude: parseFloat(longitude) };
|
||||
};
|
||||
//----------------------------------------------
|
||||
|
||||
export const determinePriority = (iconPath) => {
|
||||
const [priorityConfig, setPriorityConfig] = useState([]);
|
||||
for (let priority of priorityConfig) {
|
||||
if (iconPath.includes(priority.name.toLowerCase())) {
|
||||
return priority.level;
|
||||
}
|
||||
}
|
||||
return 5; // Default priority (lowest)
|
||||
};
|
||||
//----------------------------------------------
|
||||
export const createAndSetMarkers = async (systemId, setMarkersFunction) => {
|
||||
try {
|
||||
const response1 = await fetch(config.mapGisStationsStaticDistrictUrl);
|
||||
const jsonResponse = await response1.json();
|
||||
const response2 = await fetch(config.mapGisStationsStatusDistrictUrl);
|
||||
const statusResponse = await response2.json();
|
||||
|
||||
const getIdSystemAndAllowValueMap = new Map(
|
||||
GisSystemStatic.map((system) => [system.IdSystem, system.Allow])
|
||||
);
|
||||
//console.log("getIdSystemAndAllowValueMap:", getIdSystemAndAllowValueMap);
|
||||
|
||||
if (jsonResponse.Points && statusResponse.Statis) {
|
||||
const statisMap = new Map(statusResponse.Statis.map((s) => [s.IdLD, s]));
|
||||
let markersData = jsonResponse.Points.filter(
|
||||
(station) =>
|
||||
station.System === systemId &&
|
||||
getIdSystemAndAllowValueMap.get(station.System) === 1
|
||||
).map((station) => {
|
||||
const statis = statisMap.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);
|
||||
const zIndexOffset = 100 * (5 - priority); // Adjusted for simplicity and positive values
|
||||
|
||||
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, // Stelle sicher, dass dieser Bereich gesetzt wird
|
||||
link: station.Link,
|
||||
zIndexOffset: zIndexOffset,
|
||||
bounceOnAdd: !!statis,
|
||||
});
|
||||
|
||||
if (statis) {
|
||||
marker.on("add", () => marker.bounce(3));
|
||||
}
|
||||
|
||||
const statusInfo = statusResponse.Statis.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} <span style="color: ${status.Co};">(${status.Na})</span>
|
||||
</div>
|
||||
`
|
||||
)
|
||||
.join("");
|
||||
|
||||
marker.bindPopup(`
|
||||
<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">${statusInfo}</div>
|
||||
</div>
|
||||
`);
|
||||
return marker;
|
||||
});
|
||||
|
||||
setMarkersFunction(markersData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching data: ", error);
|
||||
}
|
||||
};
|
||||
//----------------------------------------------
|
||||
export const fetchPriorityConfig = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/talas_v5_DB/priorityConfig");
|
||||
const data = await response.json();
|
||||
console.log("Prioritätskonfiguration:", data);
|
||||
setPriorityConfig(data);
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Laden der Prioritätskonfiguration:", error);
|
||||
}
|
||||
};
|
||||
//----------------------------------------------
|
||||
export const fetchGisStatusStations = async (idMap, idUser) => {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/talas5/webserviceMap/GisStationsStatusDistrict?idMap=${idMap}&idUser=${idUser}`
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error: ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log("GisStatusStations:", data);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Daten:", error);
|
||||
}
|
||||
};
|
||||
//----------------------------------------------
|
||||
export const handleEditPoi = (marker) => {
|
||||
// Prüfung, ob der Benutzer die notwendigen Rechte hat
|
||||
if (!userRights || !userRights.includes(56)) {
|
||||
toast.error("Benutzer hat keine Berechtigung zum Bearbeiten.", {
|
||||
position: "top-center",
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
});
|
||||
console.log("Benutzer hat keine Berechtigung zum Bearbeiten.");
|
||||
return; // Beendet die Funktion frühzeitig, wenn keine Berechtigung vorliegt
|
||||
}
|
||||
|
||||
//console.log("Selected Marker ID (idPoi):", marker.options.idPoi);
|
||||
//console.log("Selected Marker Description:", marker.options.description);
|
||||
|
||||
setCurrentPoiData({
|
||||
idPoi: marker.options.id,
|
||||
name: marker.options.name,
|
||||
description: marker.options.description,
|
||||
});
|
||||
//console.log("POI-Daten1:", currentPoiData);
|
||||
|
||||
fetchPoiData(marker.options.id);
|
||||
|
||||
setShowPoiUpdateModal(true);
|
||||
};
|
||||
//----------------------------------------------
|
||||
export const insertNewMarker = (closestPoints, newPoint, lineData, map) => {
|
||||
const newMarker = L.marker(newPoint, {
|
||||
icon: circleIcon,
|
||||
draggable: true,
|
||||
}).addTo(map);
|
||||
lineData.coordinates.splice(closestPoints[2], 0, [
|
||||
newPoint.lat,
|
||||
newPoint.lng,
|
||||
]);
|
||||
|
||||
// Hier direkt speichern nach Einfügen
|
||||
saveLineData(lineData);
|
||||
|
||||
redrawPolyline(lineData);
|
||||
|
||||
// Event-Listener für das Verschieben des Markers hinzufügen
|
||||
newMarker.on("dragend", () => {
|
||||
const newCoords = newMarker.getLatLng();
|
||||
setNewCoords(newCoords);
|
||||
const newCoordinates = [...lineData.coordinates];
|
||||
newCoordinates[closestPoints[2]] = [newCoords.lat, newCoords.lng];
|
||||
lineData.coordinates = newCoordinates;
|
||||
redrawPolyline(lineData);
|
||||
|
||||
updateMarkerPosition(newMarker.getLatLng(), lineData, newMarker);
|
||||
saveLineData(lineData); // Speichern der neuen Koordinaten nach dem Verschieben
|
||||
});
|
||||
};
|
||||
//----------------------------------------------
|
||||
/* export const addItemsToMapContextMenu = () => {
|
||||
const [menuItemAdded, setMenuItemAdded] = useState(false);
|
||||
if (!menuItemAdded) {
|
||||
//console.log("contextMenuItems hasRights:", hasRights);
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: "POI hinzufügen",
|
||||
icon: "img/add_station.png",
|
||||
className: "background-red",
|
||||
callback: (event) => addStationCallback(event, hasRights),
|
||||
});
|
||||
|
||||
setMenuItemAdded(true); // Menüpunkt wurde hinzugefült, Zustand aktualisieren
|
||||
}
|
||||
}; */
|
||||
//----------------------------------------------
|
||||
export const saveLineData = (lineData) => {
|
||||
fetch("/api/talas_v5_DB/gisLines/updateLineCoordinates", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
idModul: lineData.idModul,
|
||||
idLD: lineData.idLD,
|
||||
newCoordinates: lineData.coordinates,
|
||||
}),
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Fehler beim Speichern der Linienänderungen");
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
console.log("Linienänderungen gespeichert:", data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Fehler beim Speichern der Linienänderungen:", error);
|
||||
});
|
||||
};
|
||||
//----------------------------------------------
|
||||
/* export const redrawPolyline = (lineData) => {
|
||||
const [lineColors, setLineColors] = useState({}); */
|
||||
import L from "leaflet";
|
||||
|
||||
export const redrawPolyline = (lineData, lineColors, tooltipContents, map) => {
|
||||
if (!lineData || !lineColors || !tooltipContents || !map) {
|
||||
console.error("Invalid parameters for redrawPolyline");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lineData.coordinates || !Array.isArray(lineData.coordinates)) {
|
||||
console.error("Invalid coordinates in lineData");
|
||||
return;
|
||||
}
|
||||
|
||||
const color = lineColors[lineData.idModul] || "#000000";
|
||||
const tooltipContent =
|
||||
tooltipContents[lineData.idModul] || "Standard-Tooltip-Inhalt";
|
||||
|
||||
if (lineData.polyline) map.removeLayer(lineData.polyline);
|
||||
|
||||
lineData.polyline = L.polyline(lineData.coordinates, {
|
||||
color: color,
|
||||
}).addTo(map);
|
||||
|
||||
lineData.polyline.bindTooltip(tooltipContent, {
|
||||
permanent: false,
|
||||
direction: "auto",
|
||||
});
|
||||
|
||||
lineData.polyline.on("mouseover", () => {
|
||||
lineData.polyline.setStyle({ weight: 10 });
|
||||
lineData.polyline.bringToFront();
|
||||
});
|
||||
|
||||
lineData.polyline.on("mouseout", () => {
|
||||
lineData.polyline.setStyle({ weight: 5 });
|
||||
});
|
||||
};
|
||||
45
utils/zoomAndCenterUtils.js
Normal file
45
utils/zoomAndCenterUtils.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// utils/zoomAndCenterUtils.js
|
||||
/* export const zoomIn = (e, map) => {
|
||||
if (!map) {
|
||||
console.error("map is not defined in zoomIn");
|
||||
return;
|
||||
}
|
||||
map.flyTo(e.latlng, map.getZoom() + 1);
|
||||
localStorage.setItem("mapZoom", map.getZoom());
|
||||
localStorage.setItem("mapCenter", JSON.stringify(map.getCenter()));
|
||||
}; */
|
||||
|
||||
export const zoomIn = (e, map) => {
|
||||
if (!map) {
|
||||
console.error("map is not defined in zoomIn");
|
||||
return;
|
||||
}
|
||||
map.flyTo(e.latlng, 12);
|
||||
localStorage.setItem("mapZoom", map.getZoom());
|
||||
localStorage.setItem("mapCenter", JSON.stringify(map.getCenter()));
|
||||
};
|
||||
|
||||
export const zoomOut = (map) => {
|
||||
if (!map) {
|
||||
console.error("map is not defined in zoomOut");
|
||||
return;
|
||||
}
|
||||
const x = 51.41321407879154;
|
||||
const y = 7.739617925303934;
|
||||
const zoom = 7;
|
||||
console.log("map");
|
||||
console.log(map);
|
||||
map.flyTo([x, y], zoom);
|
||||
localStorage.setItem("mapZoom", map.getZoom());
|
||||
localStorage.setItem("mapCenter", JSON.stringify(map.getCenter()));
|
||||
};
|
||||
|
||||
export const centerHere = (e, map) => {
|
||||
if (!map) {
|
||||
console.error("map is not defined in centerHere");
|
||||
return;
|
||||
}
|
||||
map.panTo(e.latlng);
|
||||
localStorage.setItem("mapZoom", map.getZoom());
|
||||
localStorage.setItem("mapCenter", JSON.stringify(map.getCenter()));
|
||||
};
|
||||
Reference in New Issue
Block a user