polylines tooltip content
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// components/DataSheet.js
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState";
|
||||
@@ -5,18 +6,15 @@ import { gisSystemStaticState } from "../store/atoms/gisSystemState";
|
||||
import { mapLayersState } from "../store/atoms/mapLayersState";
|
||||
import { selectedAreaState } from "../store/atoms/selectedAreaState";
|
||||
import { zoomTriggerState } from "../store/atoms/zoomTriggerState";
|
||||
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisible";
|
||||
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState";
|
||||
|
||||
function DataSheet() {
|
||||
const [poiVisible, setPoiVisible] = useRecoilState(poiLayerVisibleState);
|
||||
const setSelectedArea = useSetRecoilState(selectedAreaState);
|
||||
const [mapLayersVisibility, setMapLayersVisibility] =
|
||||
useRecoilState(mapLayersState);
|
||||
const [mapLayersVisibility, setMapLayersVisibility] = useRecoilState(mapLayersState);
|
||||
const [stationListing, setStationListing] = useState([]);
|
||||
const [systemListing, setSystemListing] = useState([]);
|
||||
const GisStationsStaticDistrict = useRecoilValue(
|
||||
gisStationsStaticDistrictState
|
||||
);
|
||||
const GisStationsStaticDistrict = useRecoilValue(gisStationsStaticDistrictState);
|
||||
const GisSystemStatic = useRecoilValue(gisSystemStaticState);
|
||||
const setZoomTrigger = useSetRecoilState(zoomTriggerState);
|
||||
|
||||
@@ -24,30 +22,31 @@ function DataSheet() {
|
||||
const selectedIndex = event.target.options.selectedIndex;
|
||||
const areaName = event.target.options[selectedIndex].text;
|
||||
setSelectedArea(areaName);
|
||||
console.log("Area selected oder areaName in DataSheet.js:", areaName);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const allowedSystems = new Set(
|
||||
GisSystemStatic.filter((system) => system.Allow === 1).map(
|
||||
(system) => system.IdSystem
|
||||
)
|
||||
);
|
||||
console.log("GisStationsStaticDistrict:", GisStationsStaticDistrict);
|
||||
console.log("GisSystemStatic:", GisSystemStatic);
|
||||
const allowedSystems = new Set(GisSystemStatic.filter((system) => system.Allow === 1).map((system) => system.IdSystem));
|
||||
console.log("allowedSystems:", allowedSystems);
|
||||
|
||||
const seenNames = new Set();
|
||||
const filteredAreas = GisStationsStaticDistrict.filter((item) => {
|
||||
const isUnique =
|
||||
!seenNames.has(item.Area_Name) && allowedSystems.has(item.System);
|
||||
const isUnique = !seenNames.has(item.Area_Name) && allowedSystems.has(item.System);
|
||||
if (isUnique) {
|
||||
seenNames.add(item.Area_Name);
|
||||
}
|
||||
return isUnique;
|
||||
});
|
||||
|
||||
setStationListing(
|
||||
filteredAreas.map((area, index) => ({
|
||||
id: index + 1,
|
||||
name: area.Area_Name,
|
||||
}))
|
||||
);
|
||||
//console.log("filteredAreas:", filteredAreas);
|
||||
|
||||
const seenSystemNames = new Set();
|
||||
const filteredSystems = GisSystemStatic.filter((item) => {
|
||||
const formattedName = item.Name.replace(/[\s\-]+/g, "");
|
||||
@@ -57,6 +56,7 @@ function DataSheet() {
|
||||
}
|
||||
return isUnique;
|
||||
});
|
||||
|
||||
setSystemListing(
|
||||
filteredSystems.map((system, index) => ({
|
||||
id: index + 1,
|
||||
@@ -64,19 +64,21 @@ function DataSheet() {
|
||||
}))
|
||||
);
|
||||
}, [GisStationsStaticDistrict, GisSystemStatic]);
|
||||
//}, []);
|
||||
//-----------------------------------------
|
||||
//-----------------------------------------
|
||||
|
||||
const handleCheckboxChange = (name, event) => {
|
||||
const { checked } = event.target;
|
||||
console.log(`Checkbox ${name} checked state:`, checked);
|
||||
|
||||
setMapLayersVisibility((prev) => {
|
||||
const newState = {
|
||||
...prev,
|
||||
[name]: checked,
|
||||
};
|
||||
console.log(`New mapLayersVisibility state:`, newState);
|
||||
return newState;
|
||||
});
|
||||
console.log("mapLayersVisibility:", mapLayersVisibility);
|
||||
};
|
||||
|
||||
const handleIconClick = () => {
|
||||
@@ -85,16 +87,14 @@ function DataSheet() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
id="mainDataSheet"
|
||||
className="absolute top-3 right-3 w-1/6 min-w-[300px] z-10 bg-white p-2 rounded-lg shadow-lg"
|
||||
>
|
||||
<div id="mainDataSheet" className="absolute top-3 right-3 w-1/6 min-w-[300px] z-10 bg-white p-2 rounded-lg shadow-lg">
|
||||
<div className="flex flex-col gap-4 p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<select
|
||||
onChange={handleAreaChange}
|
||||
id="stationListing"
|
||||
className="border-solid-1 p-2 rounded ml-1 font-semibold"
|
||||
role="combobox" // Ensure the correct role is set
|
||||
>
|
||||
<option value="Station wählen">Station wählen</option>
|
||||
{stationListing.map((station) => (
|
||||
@@ -103,22 +103,15 @@ function DataSheet() {
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<img
|
||||
src="/img/expand-icon.svg"
|
||||
alt="Expand"
|
||||
className="h-6 w-6 ml-2 cursor-pointer"
|
||||
onClick={handleIconClick}
|
||||
/>
|
||||
<img src="/img/expand-icon.svg" alt="Expand" className="h-6 w-6 ml-2 cursor-pointer" onClick={handleIconClick} />
|
||||
</div>
|
||||
<div>
|
||||
{systemListing.map((system) => (
|
||||
<React.Fragment key={system.id}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={mapLayersVisibility[system.name] || false}
|
||||
onChange={(e) => handleCheckboxChange(system.name, e)}
|
||||
/>
|
||||
<label className="text-sm ml-2">{system.name}</label>
|
||||
<input type="checkbox" checked={mapLayersVisibility[system.name] || false} onChange={(e) => handleCheckboxChange(system.name, e)} id={`system-${system.id}`} />
|
||||
<label htmlFor={`system-${system.id}`} className="text-sm ml-2">
|
||||
{system.name}
|
||||
</label>
|
||||
<br />
|
||||
</React.Fragment>
|
||||
))}
|
||||
@@ -128,12 +121,12 @@ function DataSheet() {
|
||||
onChange={(e) => {
|
||||
const checked = e.target.checked;
|
||||
setPoiVisible(checked);
|
||||
console.log(
|
||||
`POIs sind jetzt ${checked ? "sichtbar" : "nicht sichtbar"}.`
|
||||
);
|
||||
}}
|
||||
id="poi-checkbox"
|
||||
/>
|
||||
<label className="text-sm ml-2">POIs</label>
|
||||
<label htmlFor="poi-checkbox" className="text-sm ml-2">
|
||||
POIs
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
30
components/VersionInfoModal.js
Normal file
30
components/VersionInfoModal.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// components/VersionInfoModal.js
|
||||
import React from "react";
|
||||
|
||||
const VersionInfoModal = ({ showVersionInfoModal, closeVersionInfoModal, MAP_VERSION }) => {
|
||||
return (
|
||||
<>
|
||||
{showVersionInfoModal && (
|
||||
<div className="fixed inset-0 flex items-center justify-center z-50">
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50" onClick={closeVersionInfoModal}></div>
|
||||
<div className="bg-white p-6 rounded-lg shadow-lg z-60 max-w-lg mx-auto">
|
||||
<img src="img/Logo_TALAS.png" alt="TALAS V5 Logo" className="w-1/2 mx-auto my-4" />
|
||||
<div className="bg-white border p-6 rounded-lg shadow-lg z-60 max-w-lg mx-auto">
|
||||
<h2 className="text-xl font-bold mb-6 text-start leading-tight">Littwin Systemtechnik GmbH & Co. KG</h2>
|
||||
<h4 className="text-lg font-bold mb-2 text-start leading-tight">Bürgermeister-Brötje Str. 28</h4>
|
||||
<h4 className="text-lg font-bold mb-2 text-start leading-tight">D-26180 Rastede</h4>
|
||||
<h5 className="text-md mb-2 text-start leading-snug">T: +49 4402 9725 77-0</h5>
|
||||
<h5 className="text-md mb-2 text-start leading-snug">E: kontakt@littwin-systemtechnik.de</h5>
|
||||
</div>
|
||||
<p className="text-gray-700 text-center font-bold mt-4 leading-relaxed">TALAS.Map Version {MAP_VERSION}</p>
|
||||
<button onClick={closeVersionInfoModal} className="mt-4 bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-700 mx-auto block">
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default VersionInfoModal;
|
||||
12
components/gisPolylines/icons/CircleIcon.js
Normal file
12
components/gisPolylines/icons/CircleIcon.js
Normal file
@@ -0,0 +1,12 @@
|
||||
// /components/gisPolylines/icons/CircleIcon.js
|
||||
import L from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
|
||||
const CircleIcon = new L.DivIcon({
|
||||
className: "custom-circle-icon leaflet-marker-icon",
|
||||
html: '<div style="background-color:gray; width:10px; height:10px; border-radius:50%; border: solid black 1px;"></div>',
|
||||
iconSize: [25, 25],
|
||||
iconAnchor: [5, 5],
|
||||
});
|
||||
|
||||
export default CircleIcon;
|
||||
11
components/gisPolylines/icons/EndIcon.js
Normal file
11
components/gisPolylines/icons/EndIcon.js
Normal file
@@ -0,0 +1,11 @@
|
||||
// /components/gisPolylines/icons/EndIcon.js
|
||||
// Viereck als End-Icon für die Route
|
||||
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;
|
||||
17
components/gisPolylines/icons/StartIcon.js
Normal file
17
components/gisPolylines/icons/StartIcon.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// /components/gisPolylines/icons/StartIcon.js
|
||||
//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, 10],
|
||||
});
|
||||
|
||||
export default StartIcon;
|
||||
27
components/gisPolylines/icons/SupportPointIcons.js
Normal file
27
components/gisPolylines/icons/SupportPointIcons.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// komponents/gisPolylines/icons/SupportPointIcons
|
||||
import L from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
|
||||
// Icon für Stützpunkt hinzufügen
|
||||
export const AddSupportPointIcon = L.divIcon({
|
||||
className: "custom-add-support-point-icon",
|
||||
html: `
|
||||
<div style='background-color:green;border-radius:50%;width:12px;height:12px;border: solid white 2px;'>
|
||||
<div style='color: white; font-size: 10px; text-align: center; line-height: 12px;'>+</div>
|
||||
</div>
|
||||
`,
|
||||
iconSize: [24, 24],
|
||||
iconAnchor: [12, 12],
|
||||
});
|
||||
|
||||
// Icon für Stützpunkt entfernen
|
||||
export const RemoveSupportPointIcon = L.divIcon({
|
||||
className: "custom-remove-support-point-icon",
|
||||
html: `
|
||||
<div style='background-color:red;border-radius:50%;width:12px;height:12px;border: solid white 2px;'>
|
||||
<div style='color: white; font-size: 10px; text-align: center; line-height: 12px;'>-</div>
|
||||
</div>
|
||||
`,
|
||||
iconSize: [24, 24],
|
||||
iconAnchor: [12, 12],
|
||||
});
|
||||
160
components/imports.js
Normal file
160
components/imports.js
Normal file
@@ -0,0 +1,160 @@
|
||||
// imports.js
|
||||
import React, { useEffect, useRef, useState, useCallback } from "react";
|
||||
import L, { marker } from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
|
||||
import "leaflet-contextmenu";
|
||||
import * as config from "../config/config.js";
|
||||
import * as urls from "../config/urls.js";
|
||||
import "leaflet.smooth_marker_bouncing";
|
||||
import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet";
|
||||
import DataSheet from "./DataSheet.js";
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import { gisStationsStaticDistrictState } from "../store/atoms/gisStationState.js";
|
||||
import { gisSystemStaticState } from "../store/atoms/gisSystemState.js";
|
||||
import { mapLayersState } from "../store/atoms/mapLayersState.js";
|
||||
import { selectedAreaState } from "../store/atoms/selectedAreaState.js";
|
||||
import { zoomTriggerState } from "../store/atoms/zoomTriggerState.js";
|
||||
import { poiTypState } from "../store/atoms/poiTypState.js";
|
||||
import AddPoiModalWindow from "./pois/AddPoiModalWindow.js";
|
||||
import { poiReadFromDbTriggerAtom } from "../store/atoms/poiReadFromDbTriggerAtom.js";
|
||||
import { InformationCircleIcon } from "@heroicons/react/20/solid"; // oder 'outline'
|
||||
import PoiUpdateModal from "./pois/PoiUpdateModal.js";
|
||||
import { selectedPoiState } from "../store/atoms/poiState.js";
|
||||
import { currentPoiState } from "../store/atoms/currentPoiState.js";
|
||||
import { ToastContainer, toast } from "react-toastify";
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { mapIdState, userIdState } from "../store/atoms/urlParameterState.js";
|
||||
import { poiLayerVisibleState } from "../store/atoms/poiLayerVisibleState.js";
|
||||
import plusRoundIcon from "./PlusRoundIcon.js";
|
||||
import { parsePoint, findClosestPoints } from "../utils/geometryUtils.js";
|
||||
import { insertNewMarker, removeMarker, createAndSetMarkers, handleEditPoi } from "../utils/markerUtils.js";
|
||||
import { redrawPolyline, restoreMapSettings, checkOverlappingMarkers } from "../utils/mapUtils.js";
|
||||
import circleIcon from "./gisPolylines/icons/CircleIcon.js";
|
||||
import startIcon from "./gisPolylines/icons/StartIcon.js";
|
||||
import endIcon from "./gisPolylines/icons/EndIcon.js";
|
||||
import { fetchGisStatusStations, fetchPriorityConfig, fetchPoiData, updateLocationInDatabase, fetchUserRights, fetchDeviceNameById } from "../services/apiService.js";
|
||||
import { addContextMenuToMarker } from "../utils/contextMenuUtils.js";
|
||||
import { MAP_VERSION } from "../config/settings.js";
|
||||
import * as layers from "../config/layers.js";
|
||||
import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils.js";
|
||||
import { initializeMap } from "../utils/mapInitialization.js";
|
||||
import { addItemsToMapContextMenu } from "./useMapContextMenu.js";
|
||||
import useGmaMarkersLayer from "../hooks/useGmaMarkersLayer.js"; // Import the custom hook
|
||||
import useTalasMarkersLayer from "../hooks/talasMarkersLayer.js"; // Import the custom hook
|
||||
import useEciMarkersLayer from "../hooks/useEciMarkersLayer.js";
|
||||
import useGsmModemMarkersLayer from "../hooks/useGsmModemMarkersLayer.js";
|
||||
import useCiscoRouterMarkersLayer from "../hooks/useCiscoRouterMarkersLayer.js";
|
||||
import useWagoMarkersLayer from "../hooks/useWagoMarkersLayer.js";
|
||||
import useSiemensMarkersLayer from "../hooks/useSiemensMarkersLayer.js";
|
||||
import useOtdrMarkersLayer from "../hooks/useOtdrMarkersLayer.js";
|
||||
import useWdmMarkersLayer from "../hooks/useWdmMarkersLayer.js";
|
||||
import useMessstellenMarkersLayer from "../hooks/useMessstellenMarkersLayer.js";
|
||||
import useTalasiclMarkersLayer from "../hooks/useTalasiclMarkersLayer.js";
|
||||
import useDauzMarkersLayer from "../hooks/useDauzMarkersLayer.js";
|
||||
import useSmsfunkmodemMarkersLayer from "../hooks/useSmsfunkmodemMarkersLayer.js";
|
||||
import useUlafMarkersLayer from "../hooks/useUlafMarkersLayer.js";
|
||||
import useSonstigeMarkersLayer from "../hooks/useSonstigeMarkersLayer.js";
|
||||
import handlePoiSelect from "../utils/handlePoiSelect.js";
|
||||
import { fetchGisStationsStaticDistrict, fetchGisStationsStatusDistrict, fetchGisStationsMeasurements, fetchGisSystemStatic } from "../services/fetchData.js";
|
||||
import { setupPolylines, setupMarkers } from "../utils/mapFeatures.js"; // Import the functions
|
||||
import VersionInfoModal from "./VersionInfoModal.js";
|
||||
//--------------------------------------------
|
||||
import PoiUpdateModalWrapper from "./pois/PoiUpdateModalWrapper";
|
||||
import AddPoiModalWindowWrapper from "./pois/AddPoiModalWindowWrapper";
|
||||
import useFetchPoiData from "../hooks/useFetchPoiData";
|
||||
import usePoiTypData from "../hooks/usePoiTypData";
|
||||
import useMarkerLayers from "../hooks/useMarkerLayers";
|
||||
import useLayerVisibility from "../hooks/useLayerVisibility";
|
||||
import useLineData from "../hooks/useLineData.js";
|
||||
|
||||
export {
|
||||
React,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
useCallback,
|
||||
L,
|
||||
marker,
|
||||
config,
|
||||
urls,
|
||||
OverlappingMarkerSpiderfier,
|
||||
DataSheet,
|
||||
useRecoilState,
|
||||
useRecoilValue,
|
||||
useSetRecoilState,
|
||||
gisStationsStaticDistrictState,
|
||||
gisSystemStaticState,
|
||||
mapLayersState,
|
||||
selectedAreaState,
|
||||
zoomTriggerState,
|
||||
poiTypState,
|
||||
AddPoiModalWindow,
|
||||
poiReadFromDbTriggerAtom,
|
||||
InformationCircleIcon,
|
||||
PoiUpdateModal,
|
||||
selectedPoiState,
|
||||
currentPoiState,
|
||||
ToastContainer,
|
||||
toast,
|
||||
mapIdState,
|
||||
userIdState,
|
||||
poiLayerVisibleState,
|
||||
plusRoundIcon,
|
||||
parsePoint,
|
||||
findClosestPoints,
|
||||
insertNewMarker,
|
||||
removeMarker,
|
||||
createAndSetMarkers,
|
||||
handleEditPoi,
|
||||
redrawPolyline,
|
||||
restoreMapSettings,
|
||||
checkOverlappingMarkers,
|
||||
circleIcon,
|
||||
startIcon,
|
||||
endIcon,
|
||||
fetchGisStatusStations,
|
||||
fetchPriorityConfig,
|
||||
fetchPoiData,
|
||||
updateLocationInDatabase,
|
||||
fetchUserRights,
|
||||
fetchDeviceNameById,
|
||||
addContextMenuToMarker,
|
||||
MAP_VERSION,
|
||||
layers,
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
centerHere,
|
||||
initializeMap,
|
||||
addItemsToMapContextMenu,
|
||||
useGmaMarkersLayer,
|
||||
useTalasMarkersLayer,
|
||||
useEciMarkersLayer,
|
||||
useGsmModemMarkersLayer,
|
||||
useCiscoRouterMarkersLayer,
|
||||
useWagoMarkersLayer,
|
||||
useSiemensMarkersLayer,
|
||||
useOtdrMarkersLayer,
|
||||
useWdmMarkersLayer,
|
||||
useMessstellenMarkersLayer,
|
||||
useTalasiclMarkersLayer,
|
||||
useDauzMarkersLayer,
|
||||
useSmsfunkmodemMarkersLayer,
|
||||
useUlafMarkersLayer,
|
||||
useSonstigeMarkersLayer,
|
||||
handlePoiSelect,
|
||||
fetchGisStationsStaticDistrict,
|
||||
fetchGisStationsStatusDistrict,
|
||||
fetchGisStationsMeasurements,
|
||||
fetchGisSystemStatic,
|
||||
setupPolylines,
|
||||
setupMarkers,
|
||||
VersionInfoModal,
|
||||
PoiUpdateModalWrapper,
|
||||
AddPoiModalWindowWrapper,
|
||||
useFetchPoiData,
|
||||
usePoiTypData,
|
||||
useMarkerLayers,
|
||||
useLayerVisibility,
|
||||
useLineData,
|
||||
};
|
||||
145
components/pois/AddPoiModalWindow.js
Normal file
145
components/pois/AddPoiModalWindow.js
Normal file
@@ -0,0 +1,145 @@
|
||||
// components/pois/AddPoiModalWindow.js
|
||||
import React, { useState, useEffect, use } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { useRecoilValue, useRecoilState, useSetRecoilState } from "recoil";
|
||||
import { readPoiMarkersStore } from "../../store/selectors/readPoiMarkersStore";
|
||||
import { poiReadFromDbTriggerAtom } from "../../store/atoms/poiReadFromDbTriggerAtom";
|
||||
|
||||
const AddPoiModalWindow = ({ onClose, map, latlng }) => {
|
||||
const [poiTypData, setpoiTypData] = useState(); // Recoil State verwenden
|
||||
const [name, setName] = useState("");
|
||||
const [poiTypeId, setPoiTypeId] = useState(""); // Initialize as string
|
||||
const [poiTypeName, setPoiTypeName] = useState(""); // Initialize as string
|
||||
const [latitude] = useState(latlng.lat.toFixed(5));
|
||||
const [longitude] = useState(latlng.lng.toFixed(5));
|
||||
const setLoadData = useSetRecoilState(readPoiMarkersStore);
|
||||
const setTrigger = useSetRecoilState(poiReadFromDbTriggerAtom);
|
||||
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||
const [deviceName, setDeviceName] = useState("");
|
||||
//------------------------------------------------------------------------------------------
|
||||
useEffect(() => {
|
||||
const fetchInitialData = async () => {
|
||||
try {
|
||||
const [poiTypResponse, locationDeviceResponse] = await Promise.all([fetch("/api/talas_v5_DB/poiTyp/readPoiTyp"), fetch("/api/talas5/location_device")]);
|
||||
|
||||
const poiTypData = await poiTypResponse.json();
|
||||
setpoiTypData(poiTypData);
|
||||
|
||||
if (poiTypData.length > 0) {
|
||||
setPoiTypeId(poiTypData[0].idPoiTyp); // Set initial poiTypeId to the id of the first poiType
|
||||
if (poiTypData[1]) {
|
||||
setPoiTypeName(poiTypData[1].name);
|
||||
}
|
||||
}
|
||||
|
||||
const locationDeviceData = await locationDeviceResponse.json();
|
||||
setLocationDeviceData(locationDeviceData);
|
||||
|
||||
if (locationDeviceData.length > 0) {
|
||||
setDeviceName(locationDeviceData[0].name); // Set initial device name
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Daten:", error);
|
||||
}
|
||||
};
|
||||
|
||||
fetchInitialData();
|
||||
}, []);
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//-----------------handleSubmit-------------------
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
const formData = {
|
||||
name,
|
||||
poiTypeId,
|
||||
latitude,
|
||||
longitude,
|
||||
idLD: locationDeviceData.find((device) => device.name === deviceName).idLD,
|
||||
};
|
||||
|
||||
const response = await fetch("/api/talas_v5_DB/pois/addLocation", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
setTrigger((trigger) => {
|
||||
//console.log("Aktueller Trigger-Wert:", trigger); // Vorheriger Wert
|
||||
const newTrigger = trigger + 1;
|
||||
//console.log("Neuer Trigger-Wert:", newTrigger); // Aktualisierter Wert
|
||||
onClose();
|
||||
return newTrigger;
|
||||
});
|
||||
|
||||
// Browser aktualisieren
|
||||
window.location.reload();
|
||||
} else {
|
||||
console.error("Fehler beim Hinzufügen des POI");
|
||||
}
|
||||
|
||||
if (map && typeof map.closePopup === "function") {
|
||||
map.closePopup();
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------handleSubmit-------------------
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="m-0 p-2 w-full ">
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="name" className="block mr-2 flex-none">
|
||||
Name :
|
||||
</label>
|
||||
<input type="text" id="name" name="name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Name der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" />
|
||||
</div>
|
||||
|
||||
{/* {locationDeviceData.----------------------------------------------*/}
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="deviceName" className="block mr-2 flex-none">
|
||||
Gerät :
|
||||
</label>
|
||||
<select id="deviceName" name="deviceName" value={deviceName} 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) => (
|
||||
<option key={index} value={device.name}>
|
||||
{device.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{/* {locationDeviceData.----------------------------------------------*/}
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="idPoiTyp2" className="block mr-2 flex-none">
|
||||
Typ:
|
||||
</label>
|
||||
<select id="idPoiTyp2" name="idPoiTyp2" value={poiTypeId} onChange={(e) => setPoiTypeId(e.target.value)} className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm">
|
||||
{poiTypData &&
|
||||
poiTypData.map((poiTyp, index) => (
|
||||
<option key={poiTyp.idPoiTyp || index} value={poiTyp.idPoiTyp}>
|
||||
{poiTyp.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="flex flex-row items-center justify-center">
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="lat" className="block mr-2 flex-none text-xs">
|
||||
Lat : {latitude}
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="lng" className="block mr-2 flex-none text-xs">
|
||||
Lng : {longitude}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full">
|
||||
POI hinzufügen
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddPoiModalWindow;
|
||||
24
components/pois/AddPoiModalWindowPopup.js
Normal file
24
components/pois/AddPoiModalWindowPopup.js
Normal file
@@ -0,0 +1,24 @@
|
||||
// components/pois/AddPoiModalWindowPopup.js
|
||||
import React from "react";
|
||||
import AddPoiModalWindow from "./AddPoiModalWindow.js";
|
||||
|
||||
const AddPoiModalWindowPopup = ({ showPopup, closePopup, handleAddStation, popupCoordinates }) => {
|
||||
return (
|
||||
<>
|
||||
{showPopup && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]" onClick={closePopup}>
|
||||
<div className="relative bg-white p-6 rounded-lg shadow-lg" onClick={(e) => e.stopPropagation()}>
|
||||
<button onClick={closePopup} className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
<AddPoiModalWindow onClose={closePopup} onSubmit={handleAddStation} latlng={popupCoordinates} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddPoiModalWindowPopup;
|
||||
30
components/pois/AddPoiModalWindowWrapper.js
Normal file
30
components/pois/AddPoiModalWindowWrapper.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// components/pois/AddPoiModalWindowWrapper.js
|
||||
import React from "react";
|
||||
import AddPoiModalWindow from "./AddPoiModalWindow";
|
||||
|
||||
const AddPoiModalWindowWrapper = ({ show, onClose, latlng, handleAddStation }) => {
|
||||
return (
|
||||
show && (
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]"
|
||||
onClick={onClose}
|
||||
data-testid="modal-overlay" // Hinzugefügt, um den Hintergrund zu identifizieren
|
||||
>
|
||||
<div
|
||||
className="relative bg-white p-6 rounded-lg shadow-lg"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
role="dialog" // Hinzugefügt, um das Dialog-Element zu identifizieren
|
||||
>
|
||||
<button onClick={onClose} className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
<AddPoiModalWindow onClose={onClose} onSubmit={handleAddStation} latlng={latlng} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default AddPoiModalWindowWrapper;
|
||||
213
components/pois/PoiUpdateModal.js
Normal file
213
components/pois/PoiUpdateModal.js
Normal file
@@ -0,0 +1,213 @@
|
||||
// components/pois/poiUpdateModal.js
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { selectedPoiState } from "../../store/atoms/poiState";
|
||||
import { currentPoiState } from "../../store/atoms/currentPoiState";
|
||||
|
||||
const PoiUpdateModal = ({ onClose, poiData, onSubmit }) => {
|
||||
const currentPoi = useRecoilValue(currentPoiState);
|
||||
const selectedPoi = useRecoilValue(selectedPoiState);
|
||||
const [poiId, setPoiId] = useState(poiData ? poiData.idPoi : "");
|
||||
const [name, setName] = useState(poiData ? poiData.name : "");
|
||||
const [poiTypData, setPoiTypData] = useState([]);
|
||||
const [poiTypeId, setPoiTypeId] = useState("");
|
||||
const [locationDeviceData, setLocationDeviceData] = useState([]);
|
||||
const [deviceName, setDeviceName] = useState("");
|
||||
const [idLD, setIdLD] = useState(poiData ? poiData.idLD : "");
|
||||
|
||||
const [description, setDescription] = useState(poiData ? poiData.description : "");
|
||||
|
||||
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);
|
||||
}
|
||||
}, [poiData]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchDeviceId = async () => {
|
||||
if (poiData && poiData.idLD) {
|
||||
try {
|
||||
const response = await fetch(`/api/talas_v5_DB/locationDevice/getDeviceIdById?idLD=${poiData.idLD}`);
|
||||
const data = await response.json();
|
||||
if (data) setDeviceName(data.name);
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Geräteinformation in PoiUpdateModel.js: ", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fetchDeviceId();
|
||||
}, [poiData]);
|
||||
|
||||
const handleDeletePoi = async () => {
|
||||
if (confirm("Sind Sie sicher, dass Sie diesen POI löschen möchten?")) {
|
||||
try {
|
||||
const response = await fetch(`/api/talas_v5_DB/pois/deletePoi?id=${poiId}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
if (response.ok) {
|
||||
alert("POI wurde erfolgreich gelöscht.");
|
||||
onClose();
|
||||
window.location.reload();
|
||||
} else {
|
||||
throw new Error("Fehler beim Löschen des POI.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Löschen des POI:", error);
|
||||
alert("Fehler beim Löschen des POI.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchPoiTypData = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/talas_v5_DB/poiTyp/readPoiTyp");
|
||||
const data = await response.json();
|
||||
setPoiTypData(data);
|
||||
if (selectedPoi && data) {
|
||||
const matchingType = data.find((pt) => pt.name === selectedPoi.typ);
|
||||
if (matchingType) {
|
||||
setPoiTypeId(matchingType.idPoiTyp);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der poiTyp Daten:", error);
|
||||
}
|
||||
};
|
||||
fetchPoiTypData();
|
||||
}, [selectedPoi]);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// 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();
|
||||
setLocationDeviceData(data);
|
||||
if (poiData && poiData.idLD) {
|
||||
const selectedDevice = data.find((device) => device.id === poiData.idLD);
|
||||
setDeviceName(selectedDevice ? selectedDevice.id : data[0].id);
|
||||
//console.log("Selected Device in poiUpdate:", selectedDevice);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der Standort- und Gerätedaten:", error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetch("/api/talas_v5_DB/locationDevice/locationDevices")
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
setLocationDeviceData(data);
|
||||
const currentDevice = data.find((device) => device.idLD === currentPoi.idLD);
|
||||
if (currentDevice) {
|
||||
setDeviceName(currentDevice.name);
|
||||
//console.log("Current Device name in poiUpdate:", currentDevice.name);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Fehler beim Abrufen der Gerätedaten:", error);
|
||||
setLocationDeviceData([]);
|
||||
});
|
||||
}, [poiData?.idLD, currentPoi]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
const idLDResponse = await fetch(`/api/talas_v5_DB/locationDevice/getDeviceId?deviceName=${encodeURIComponent(deviceName)}`);
|
||||
const idLDData = await idLDResponse.json();
|
||||
const idLD = idLDData.idLD;
|
||||
try {
|
||||
const response = await fetch("/api/talas_v5_DB/pois/updatePoi", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
idPoi: poiId,
|
||||
name: name,
|
||||
description: description,
|
||||
idPoiTyp: poiTypeId,
|
||||
idLD: idLD,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
onClose();
|
||||
window.location.reload();
|
||||
} else {
|
||||
const errorResponse = await response.json();
|
||||
throw new Error(errorResponse.error || "Fehler beim Aktualisieren des POI.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Aktualisieren des POI:", error);
|
||||
alert("Fehler beim Aktualisieren des POI.");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-10 flex justify-center items-center z-[1000]" onClick={onClose}>
|
||||
<div className="relative bg-white p-6 rounded-lg shadow-lg" onClick={(e) => e.stopPropagation()}>
|
||||
<button onClick={onClose} className="absolute top-0 right-0 mt-2 mr-2 p-1 text-gray-700 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600" aria-label="Close">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
<form onSubmit={handleSubmit} className="m-0 p-2 w-full">
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="description" className="block mr-2 flex-none">
|
||||
Beschreibung:
|
||||
</label>
|
||||
<input type="text" id="description" name="description" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Beschreibung der Station" className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm" />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="deviceName" className="block mr-2 flex-none">
|
||||
Gerät:
|
||||
</label>
|
||||
<select id="deviceName" name="deviceName" value={deviceName} 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) => (
|
||||
<option key={index} value={device.id}>
|
||||
{device.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center mb-4">
|
||||
<label htmlFor="idPoiTyp2" className="block mr-2 flex-none">
|
||||
Typ:
|
||||
</label>
|
||||
<select id="idPoiTyp2" name="idPoiTyp2" value={poiTypeId} onChange={(e) => setPoiTypeId(e.target.value)} className="block p-2 w-full border-2 border-gray-200 rounded-md text-sm">
|
||||
{poiTypData.map((poiTyp, index) => (
|
||||
<option key={index} value={poiTyp.idPoiTyp}>
|
||||
{poiTyp.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button 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">
|
||||
POI löschen
|
||||
</button>
|
||||
|
||||
<button type="submit" className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full">
|
||||
POI aktualisieren
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PoiUpdateModal;
|
||||
9
components/pois/PoiUpdateModalWindow.js
Normal file
9
components/pois/PoiUpdateModalWindow.js
Normal file
@@ -0,0 +1,9 @@
|
||||
// components/pois/PoiUpdateModalWindow.js
|
||||
import React from "react";
|
||||
import PoiUpdateModal from "./PoiUpdateModal.js";
|
||||
|
||||
const PoiUpdateModalWindow = ({ showPoiUpdateModal, closePoiUpdateModal, currentPoiData, popupCoordinates }) => {
|
||||
return <>{showPoiUpdateModal && <PoiUpdateModal onClose={closePoiUpdateModal} poiData={currentPoiData} onSubmit={() => {}} latlng={popupCoordinates} />}</>;
|
||||
};
|
||||
|
||||
export default PoiUpdateModalWindow;
|
||||
26
components/pois/PoiUpdateModalWrapper.js
Normal file
26
components/pois/PoiUpdateModalWrapper.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// components/pois/PoiUpdateModalWrapper.js
|
||||
import React, { useState } from "react";
|
||||
import PoiUpdateModal from "./PoiUpdateModal";
|
||||
import { useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import { currentPoiState, selectedPoiState } from "../../store/atoms/poiState";
|
||||
import { poiReadFromDbTriggerAtom } from "../../store/atoms/poiReadFromDbTriggerAtom";
|
||||
|
||||
const PoiUpdateModalWrapper = ({ show, onClose, latlng }) => {
|
||||
const setSelectedPoi = useSetRecoilState(selectedPoiState);
|
||||
const setCurrentPoi = useSetRecoilState(currentPoiState);
|
||||
const currentPoi = useRecoilValue(currentPoiState);
|
||||
const poiReadTrigger = useRecoilValue(poiReadFromDbTriggerAtom);
|
||||
|
||||
return (
|
||||
show && (
|
||||
<PoiUpdateModal
|
||||
onClose={onClose}
|
||||
poiData={currentPoi}
|
||||
onSubmit={() => {}} // Add your submit logic here
|
||||
latlng={latlng}
|
||||
/>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default PoiUpdateModalWrapper;
|
||||
52
components/pois/PoiUtils.js
Normal file
52
components/pois/PoiUtils.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// components/pois/PoiUtils.js
|
||||
import L from "leaflet";
|
||||
|
||||
// Funktion, um POI Markers zu erstellen
|
||||
export const createPoiMarkers = (poiData, iconPath) => {
|
||||
return poiData.map((location) => {
|
||||
return L.marker([location.latitude, location.longitude], {
|
||||
icon: L.icon({
|
||||
iconUrl: iconPath,
|
||||
iconSize: [25, 41],
|
||||
iconAnchor: [12, 41],
|
||||
popupAnchor: [1, -34],
|
||||
draggable: true,
|
||||
}),
|
||||
id: location.idPoi,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Funktion zum Hinzufügen von Markern zur Karte und zum Umgang mit Events
|
||||
export const addMarkersToMap = (markers, map, layerGroup) => {
|
||||
markers.forEach((marker) => {
|
||||
marker.addTo(layerGroup);
|
||||
marker.on("mouseover", () => marker.openPopup());
|
||||
marker.on("mouseout", () => marker.closePopup());
|
||||
marker.on("dragend", (e) => {
|
||||
const newLat = e.target.getLatLng().lat;
|
||||
const newLng = e.target.getLatLng().lng;
|
||||
const markerId = e.target.options.id;
|
||||
updateLocationInDatabase(markerId, newLat, newLng);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Funktion zum Aktualisieren der Standorte 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) {
|
||||
console.error("Fehler beim Aktualisieren der Position");
|
||||
}
|
||||
};
|
||||
|
||||
// Weitere Funktionen können hier hinzugefügt werden
|
||||
77
components/useMapContextMenu.js
Normal file
77
components/useMapContextMenu.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// /components/useMapContextMenu.js
|
||||
import { toast } from "react-toastify";
|
||||
import { zoomIn, zoomOut, centerHere } from "../utils/zoomAndCenterUtils"; // Assuming these are imported correctly
|
||||
|
||||
const zoomInCallback = (e, map) => {
|
||||
zoomIn(e, map);
|
||||
};
|
||||
|
||||
const zoomOutCallback = (map) => {
|
||||
zoomOut(map);
|
||||
};
|
||||
|
||||
const centerHereCallback = (e, map) => {
|
||||
centerHere(e, map);
|
||||
};
|
||||
// Funktion zum Anzeigen der Koordinaten
|
||||
const showCoordinates = (e) => {
|
||||
alert("Breitengrad: " + e.latlng.lat.toFixed(5) + "\nLängengrad: " + e.latlng.lng.toFixed(5));
|
||||
};
|
||||
// Kontextmenü Callback für "POI hinzufügen"
|
||||
const addStationCallback = (event, hasRights, setShowPopup, setPopupCoordinates) => {
|
||||
if (hasRights) {
|
||||
setPopupCoordinates(event.latlng);
|
||||
setShowPopup(true);
|
||||
} else {
|
||||
toast.error("Benutzer hat keine Berechtigung zum Hinzufügen.", {
|
||||
position: "top-center",
|
||||
autoClose: 5000,
|
||||
hideProgressBar: false,
|
||||
closeOnClick: true,
|
||||
pauseOnHover: true,
|
||||
draggable: true,
|
||||
progress: undefined,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const addItemsToMapContextMenu = (map, menuItemAdded, setMenuItemAdded, hasRights, setShowPopup, setPopupCoordinates) => {
|
||||
if (!menuItemAdded && map && map.contextmenu) {
|
||||
map.contextmenu.addItem({
|
||||
text: "Koordinaten anzeigen",
|
||||
icon: "img/not_listed_location.png",
|
||||
callback: showCoordinates,
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({ separator: true });
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: "Reinzoomen",
|
||||
icon: "img/zoom_in.png",
|
||||
callback: (e) => zoomInCallback(e, map),
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: "Rauszoomen",
|
||||
icon: "img/zoom_out.png",
|
||||
callback: () => zoomOutCallback(map),
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: "Hier zentrieren",
|
||||
icon: "img/center_focus.png",
|
||||
callback: (e) => centerHereCallback(e, map),
|
||||
});
|
||||
|
||||
map.contextmenu.addItem({ separator: true });
|
||||
|
||||
map.contextmenu.addItem({
|
||||
text: "POI hinzufügen",
|
||||
icon: "img/add_station.png",
|
||||
className: "background-red",
|
||||
callback: (event) => addStationCallback(event, hasRights, setShowPopup, setPopupCoordinates),
|
||||
});
|
||||
|
||||
setMenuItemAdded(true);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user