Card in z-index=50 (Dropdown menu) und map z-index=0 mit Tailwind

This commit is contained in:
ISA
2024-04-19 11:36:29 +02:00
parent 8a1cc0aa66
commit 9b32c77e89
7 changed files with 170 additions and 1271 deletions

95
components/DataSheet.js Normal file
View File

@@ -0,0 +1,95 @@
import React, { useState } from "react";
function DataSheet() {
const stationListing = [
{ id: 1, name: "Ammersricht BZR (FGN)" },
{ id: 2, name: "Bad-Bentheim" },
{ id: 3, name: "Gevelsberg" },
{ id: 4, name: "Köln" },
{ id: 5, name: "Olfen-Selm" },
{ id: 6, name: "Plettenberg" },
{ id: 7, name: "Renzenhof (RG)" },
{ id: 8, name: "Schlüchtern II" },
{ id: 9, name: "Wuppertal" },
// Füge hier weitere Stationen hinzu, falls nötig
];
// Initialisiere den Zustand mit allen Stationen als nicht gecheckt (false)
const [checkedStations, setCheckedStations] = useState(
stationListing.reduce((acc, station) => {
acc[station.id] = false;
return acc;
}, {})
);
const handleCheckboxChange = (id) => {
setCheckedStations((prev) => ({
...prev,
[id]: !prev[id],
}));
};
const handleStationChange = (event) => {
console.log("Station selected:", event.target.value);
};
const resetView = () => {
console.log("View has been reset");
};
return (
<div
id="mainDataSheet"
className="absolute top-12 right-3 w-1/6 min-w-[300px] z-10 bg-gray-100 border border-gray-300"
>
<div className="bg-white shadow rounded-lg overflow-hidden">
<div className="bg-gray-200 border-b border-gray-300 p-3">
<form>
<select
onChange={handleStationChange}
id="stationListing"
className="w-full border-none p-2 rounded"
>
<option>Station wählen</option>
{stationListing.map((station) => (
<option key={station.id} value={station.id}>
{station.name}
</option>
))}
</select>
</form>
<div className="text-right">
<button onClick={resetView} className="p-1 focus:outline-none">
<i
className="fi-arrows-out text-gray-800 text-lg"
title="Ansicht zurücksetzen"
></i>
</button>
</div>
</div>
<div className="flex flex-col p-4 gap-2">
{stationListing.map((station) => (
<div key={station.id} className="flex items-center">
<input
type="checkbox"
id={`box-${station.id}`}
className="accent-blue-500 checked:bg-blue-500"
checked={checkedStations[station.id]}
onChange={() => handleCheckboxChange(station.id)}
// Wenn du möchtest, dass die Checkboxen nicht veränderbar sind, entferne den onChange-Handler und setze `readOnly`
/>
<label
htmlFor={`box-${station.id}`}
className="text-sm font-bold ml-2"
>
{station.name}
</label>
</div>
))}
</div>
</div>
</div>
);
}
export default DataSheet;

View File

@@ -1,95 +0,0 @@
//components/Kartenkomponente.js
import React, { useState, useEffect } from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import dynamic from 'next/dynamic';
// Dynamischer Import mit SSR deaktiviert
const KartenKomponenteOhneSSR = dynamic(
() => import('../components/KartenKomponente'),
{ ssr: false }
);
const KartenKomponente = ({ locations, onAddLocation, onLocationUpdate }) => {
const [isOnline, setIsOnline] = useState(true); // Standardwert als fallback
const [aktuelleSchicht, setAktuelleSchicht] = useState({
url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png", // Standardwert
options: {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
minZoom: 7,
maxZoom: 19,
crossOrigin: true,
},
});
useEffect(() => {
// Setzt den Zustand, basierend darauf, ob das Fensterobjekt existiert (Client-Seite)
if (typeof window !== "undefined") {
setIsOnline(navigator.onLine);
setAktuelleSchicht({
url: navigator.onLine ? "https://tile.openstreetmap.org/{z}/{x}/{y}.png" : "/mapTiles/{z}/{x}/{y}.png",
options: {
minZoom: 7,
maxZoom: navigator.onLine ? 19 : 14,
crossOrigin: true,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
},
});
const handleOnlineStatus = () => setIsOnline(navigator.onLine);
window.addEventListener("online", handleOnlineStatus);
window.addEventListener("offline", handleOnlineStatus);
return () => {
window.removeEventListener("online", handleOnlineStatus);
window.removeEventListener("offline", handleOnlineStatus);
};
}
}, []);
useEffect(() => {
setAktuelleSchicht({
url: isOnline ? "https://tile.openstreetmap.org/{z}/{x}/{y}.png" : "/mapTiles/{z}/{x}/{y}.png",
options: {
minZoom: 7,
maxZoom: isOnline ? 19 : 14,
crossOrigin: true,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
},
});
}, [isOnline]);
// Funktion, um auf Klick ein Popup für das Hinzufügen neuer Standorte zu zeigen
const addMarker = (e) => {
// Hier könnte eine Logik stehen, um ein Formular-Modal oder Popup zu öffnen, um die Daten für den neuen Standort zu sammeln
const newLocation = { lat: e.latlng.lat, lng: e.latlng.lng }; // Beispiel für neue Standortdaten
onAddLocation(newLocation); // Rufe die übergebene onAddLocation-Funktion mit den neuen Standortdaten auf
};
return (
<MapContainer center={[51.505, -0.09]} zoom={13} style={{ height: "100vh", width: "100%" }} whenCreated={map => map.on('click', addMarker)}>
<TileLayer url={aktuelleSchicht.url} {...aktuelleSchicht.options} />
{locations.map((location, index) => (
<Marker
key={index}
position={[location.lat, location.lng]}
draggable={true}
eventHandlers={{
dragend: (e) => {
const newLat = e.target.getLatLng().lat;
const newLng = e.target.getLatLng().lng;
onLocationUpdate(location.id, newLat, newLng); // Aktualisiere die Position des Standorts, nachdem der Marker verschoben wurde
},
}}
>
<Popup>{location.name}</Popup>
</Marker>
))}
</MapContainer>
);
};
export default KartenKomponente;

View File

@@ -1,350 +0,0 @@
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
import "leaflet-contextmenu";
const MapComponent = ({
locations,
onAddLocation,
onLocationUpdate,
dataStatic,
mapData,
}) => {
const [map, setMap] = useState(null);
const mapRef = useRef(null);
const [online, setOnline] = useState(navigator.onLine);
const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png";
const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
// Funktionen zur Überwachung der Internetverbindung
const checkInternet = () => {
console.log("Checking internet connectivity...");
fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" })
.then((response) => setOnline(response.ok))
.catch(() => setOnline(false));
};
// Initialize map
useEffect(() => {
if (mapRef.current && !map) {
console.log("Initializing map...");
const osm = L.map(mapRef.current, {
center: [53.111111, 8.4625],
zoom: 10,
contextmenu: true,
contextmenuWidth: 140,
contextmenuItems: [
{ text: "Station hinzufügen", callback: showAddStationPopup },
{
text: "Station öffnen (Tab)",
icon: "img/screen_new.png",
callback: newLink,
},
{
text: "Station öffnen",
icon: "img/screen_same.png",
callback: sameLink,
},
"-", // Divider
{ text: "Reinzoomen", callback: (e) => zoomIn(e) },
{ text: "Rauszoomen", callback: (e) => zoomOut(e) },
{
text: "Hier zentrieren",
callback: (e) => centerMap(e, osm),
},
"-", // Divider
{
text: "Koordinaten",
icon: "img/not_listed_location.png",
callback: showCoordinates,
},
{
text: "Get Data to Console",
icon: "img/not_listed_location.png",
callback: showData,
},
],
});
// Adding initial tile layer
const tileLayer = L.tileLayer(
online
? "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
: "../TileMap/mapTiles/{z}/{x}/{y}.png",
{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
minZoom: 7,
maxZoom: 19,
}
);
tileLayer.addTo(osm);
setMap(osm);
// Cleanup function
return () => {
osm.remove();
};
}
}, [mapRef, online]); // React only on online changes for initialization
// Handle online/offline status
useEffect(() => {
window.addEventListener("online", checkInternet);
window.addEventListener("offline", checkInternet);
return () => {
window.removeEventListener("online", checkInternet);
window.removeEventListener("offline", checkInternet);
};
}, []);
// Update map layers based on online status
useEffect(() => {
if (map) {
const newLayer = L.tileLayer(
online
? "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
: "../TileMap/mapTiles/{z}/{x}/{y}.png",
{
minZoom: 7,
maxZoom: online ? 19 : 14,
attribution:
'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}
);
map.eachLayer((layer) => {
if (layer instanceof L.TileLayer) {
map.removeLayer(layer);
}
});
newLayer.addTo(map);
}
}, [online, map]);
// Marker handling
useEffect(() => {
// Remove old markers
if (map) {
map.eachLayer((layer) => {
if (layer instanceof L.Marker) {
map.removeLayer(layer);
}
});
// Add new markers
locations.forEach((location) => {
const { latitude, longitude } = parsePoint(location.position);
const marker = L.marker([latitude, longitude], {
icon: L.icon({
iconUrl: "/location.svg",
iconSize: [34, 34],
iconAnchor: [17, 34],
popupAnchor: [0, -34],
}),
draggable: true,
id: location.idPoi,
});
marker.bindPopup(
`<b>${location.description || "Unbekannt"}</b><br>Type: ${
location.idPoiTyp || "N/A"
}<br>Lat: ${latitude.toFixed(5)}, Lng: ${longitude.toFixed(5)}`
);
marker.on("dragend", function (e) {
const newLat = e.target.getLatLng().lat;
const newLng = e.target.getLatLng().lng;
const markerId = e.target.options.id;
updateLocationInDatabase(markerId, newLat, newLng).then(() => {
onLocationUpdate(markerId, newLat, newLng);
});
});
marker.addTo(map);
});
}
}, [map, locations, onLocationUpdate]);
//------------------------------------------
function parsePoint(pointString) {
const match = pointString.match(
/POINT\s*\((\d+(\.\d+)?)\s+(\d+(\.\d+)?)\)/
);
if (match) {
return {
longitude: parseFloat(match[1]),
latitude: parseFloat(match[3]), // Achtung: Index 3 für die zweite Koordinate, wegen der Gruppe (\.\d+)?
};
} else {
// Handle the error or return a default/fallback value
console.error("Invalid POINT format:", pointString);
return null; // Oder eine sinnvolle Standardantwort
}
}
//----------------------------------
const centerMap = (e) => {
if (!map) {
console.error("Die Karte wurde noch nicht initialisiert.");
return;
}
if (!e || !e.latlng) {
console.error("Fehlerhafte Event-Daten: ", e);
return;
}
console.log("Zentrierung auf: ", e.latlng);
map.panTo(e.latlng);
};
//-----Kontextmenu----------------
const newLink = (e) => {
try {
if (!e.relatedTarget || !e.relatedTarget.options) {
throw new Error("relatedTarget or options not defined");
}
alert("Neues Fenster: " + e.relatedTarget.options.test);
window
.open(`../devices/${e.relatedTarget.options.test}`, "_blank")
.focus();
} catch (error) {
console.error("Failed in newLink function:", error);
}
};
const sameLink = (e) => {
alert(e.relatedTarget.options.test);
window
.open("../devices/" + e.relatedTarget.options.test, "_parent")
.focus();
};
const zoomIn = (e) => {
if (!map) {
console.error("Karte ist noch nicht initialisiert in zoomIn.");
return;
}
map.flyTo(e.latlng, 12);
};
const zoomOut = (e) => {
if (!map) {
console.error("Karte ist noch nicht initialisiert in zoomOut.");
return;
}
// Annahme: Du willst beim Rauszoomen die aktuelle Position halten
// und nur den Zoom-Level ändern. Hier reduzieren wir den Zoom-Level um 1.
const currentZoom = map.getZoom();
map.flyTo(e.latlng, map.getZoom() - 1);
};
const showCoordinates = (e) => {
alert("Breitengrad: " + e.latlng.lat + "\nLängengrad: " + e.latlng.lng);
};
const showData = (e) => {
console.log(e);
};
const showTalas = (e) => {
map.addLayer(TALAS);
loadData();
};
const hideTalas = (e) => {
map.removeLayer(TALAS);
loadData();
};
const showGSM = (e) => {
map.addLayer(GMA);
loadData();
};
const hideGSM = (e) => {
map.removeLayer(GMA);
loadData();
};
//-----Kontextmenu----ende------------
const showAddStationPopup = (e, map) => {
//popupContent Station hinzufügen
const popupContent = `
<form id="addStationForm" class="m-0 p-2 w-full">
<div class="flex items-center mb-4">
<label for="name" class="block mr-2 flex-none">Name:</label>
<input
type="text"
id="name"
name="name"
placeholder="Name der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="type" class="block mr-3 flex-none">Type:</label>
<input
type="text"
id="type"
name="type"
placeholder="Typ der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lat" class="block mr-2 flex-none">Breitengrad:</label>
<input
type="text"
id="lat"
name="lat"
value="${e.latlng.lat.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lng" class="block mr-2 flex-none">Längengrad:</label>
<input
type="text"
id="lng"
name="lng"
value="${e.latlng.lng.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full"
>
Station hinzufügen
</button>
</form>
`;
L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(map);
// Verzögerung hinzufügen, um sicherzustellen, dass das Formular im DOM verfügbar ist
setTimeout(() => {
const form = document.getElementById("addStationForm");
if (form) {
form.addEventListener("submit", async (event) => {
event.preventDefault();
const name = event.target.name.value;
const type = event.target.type.value;
const lat = event.target.lat.value;
const lng = event.target.lng.value;
// Hier wird `onAddLocation` mit den Werten aufgerufen, die aus dem Formular gesammelt wurden
await onAddLocation(name, type, lat, lng);
map.closePopup();
});
}
}, 10);
};
return <div id="map" ref={mapRef} className="h-screen"></div>;
};
export default MapComponent;

View File

@@ -1,511 +0,0 @@
// ./components/MapComponent.js
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
import "leaflet-contextmenu";
const MapComponent = ({
locations,
onAddLocation,
onLocationUpdate,
dataStatic,
mapData,
}) => {
const [map, setMap] = useState(null);
const [markers, setMarkers] = useState([]);
const mapRef = useRef(null);
const [mapLayers, setMapLayers] = useState({});
const [online, setOnline] = useState(navigator.onLine);
// Define tile layers
const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png";
const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
// Ensure all usage of `map` checks that it is initialized
useEffect(() => {
if (map) {
const layerUrl = online ? onlineTileLayer : offlineTileLayer;
const newLayer = L.tileLayer(layerUrl, {
minZoom: 7,
maxZoom: online ? 19 : 14,
attribution:
'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
});
map.eachLayer((layer) => {
if (layer instanceof L.TileLayer) {
map.removeLayer(layer);
}
});
newLayer.addTo(map);
}
}, [online, map]);
// Funktion zum Wechseln der Kartenlayer
const switchLayer = () => {
console.log("Attempting to switch layers...");
if (!map) {
console.log("Map is not initialized yet.");
return;
}
const layerUrl = online ? onlineTileLayer : offlineTileLayer;
console.log(`Switching layers: ${online ? "Online" : "Offline"}`);
const newLayer = L.tileLayer(layerUrl, {
minZoom: 7,
maxZoom: online ? 19 : 14,
attribution:
'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
});
map.eachLayer((layer) => {
if (layer instanceof L.TileLayer) {
console.log("Removing layer:", layer);
map.removeLayer(layer);
}
});
newLayer.addTo(map);
console.log("Layer added to map.");
};
// Online-/Offline-Status überwachen
useEffect(() => {
// Funktion zur Überprüfung der Internetverbindung
const checkInternet = () => {
console.log("Checking internet connectivity...");
fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" })
.then((response) => {
const newOnlineStatus = response.ok;
console.log(
`Internet status checked: ${newOnlineStatus ? "Online" : "Offline"}`
);
setOnline(newOnlineStatus);
})
.catch((error) => {
console.log("Error checking internet status:", error.message);
setOnline(false);
});
};
window.addEventListener("online", checkInternet);
window.addEventListener("offline", checkInternet);
return () => {
window.removeEventListener("online", checkInternet);
window.removeEventListener("offline", checkInternet);
};
}, []);
const centerMap = (e) => {
if (!map) {
console.error("Die Karte wurde noch nicht initialisiert.");
return;
}
if (!e || !e.latlng) {
console.error("Fehlerhafte Event-Daten: ", e);
return;
}
console.log("Zentrierung auf: ", e.latlng);
map.panTo(e.latlng);
};
// Karte nur einmal initialisieren
useEffect(() => {
if (mapRef.current && !map) {
console.log("Initializing map...");
const initializedMap = L.map(mapRef.current, {
center: [53.111111, 8.4625],
zoom: 10,
contextmenu: true,
contextmenuWidth: 140,
contextmenuItems: [
{
text: "Station hinzufügen",
callback: (e) => showAddStationPopup(e, initializedMap),
},
{
text: "Station öffnen (Tab)",
icon: "img/screen_new.png",
callback: newLink,
},
{
text: "Station öffnen",
icon: "img/screen_same.png",
callback: sameLink,
},
"-",
{
text: "Reinzoomen",
icon: "img/zoom_in.png",
callback: zoomIn,
},
{
text: "Rauszoomen",
icon: "img/zoom_out.png",
callback: zoomOut,
},
{
text: "Hier zentrieren",
icon: "img/center_focus.png",
callback: centerMap,
},
"-",
{
text: "Koordinaten",
icon: "img/not_listed_location.png",
callback: showCoordinates,
},
{
text: "Get Data to Console",
icon: "img/not_listed_location.png",
callback: showData,
},
{
text: "Show Talas",
icon: "img/not_listed_location.png",
callback: showTalas,
},
{
text: "Hide Talas",
icon: "img/not_listed_location.png",
callback: hideTalas,
},
{
text: "Show GMA",
icon: "img/not_listed_location.png",
callback: showGSM,
},
{
text: "Hide GMA",
icon: "img/not_listed_location.png",
callback: hideGSM,
},
],
});
const tileLayer = L.tileLayer(
online ? onlineTileLayer : offlineTileLayer,
{
attribution:
'&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
minZoom: 7,
maxZoom: 19,
}
);
tileLayer.addTo(initializedMap);
setMap(initializedMap);
return () => initializedMap.remove(); // Cleanup
}
}, [mapRef, online]); // Abhängigkeit von online hinzugefügt
// Layer wechseln, wenn Online-Status sich ändert
useEffect(() => {
switchLayer(online);
}, [online, map]);
// Erstellen von Refs für jede LayerGroup
const TALAS = useRef(null);
const ECI = useRef(null);
const ULAF = useRef(null);
const GSMModem = useRef(null);
const CiscoRouter = useRef(null);
const WAGO = useRef(null);
const Siemens = useRef(null);
const OTDR = useRef(null);
const WDM = useRef(null);
const GMA = useRef(null);
const Sonstige = useRef(null);
const TALASICL = useRef(null);
const flyToStation = (stationValue) => {
let x = 51.41321407879154;
let y = 7.739617925303934;
let zoom = 14;
const stationData = dataStatic.find(
(station) => station.Area_Name === stationValue
);
if (stationData) {
x = stationData.X;
y = stationData.Y;
} else {
zoom = 8; // default zoom if not found
}
map.flyTo([x, y], zoom);
mapData.forEach((datum) => {
const loc = new L.LatLng(datum.lat, datum.lon);
const marker = new L.Marker(loc, { title: datum.d });
marker.bindPopup(datum.d);
map.addLayer(marker);
});
};
//-----Kontextmenu----------------
const newLink = (e) => {
try {
if (!e.relatedTarget || !e.relatedTarget.options) {
throw new Error("relatedTarget or options not defined");
}
alert("Neues Fenster: " + e.relatedTarget.options.test);
window
.open(`../devices/${e.relatedTarget.options.test}`, "_blank")
.focus();
} catch (error) {
console.error("Failed in newLink function:", error);
}
};
const sameLink = (e) => {
alert(e.relatedTarget.options.test);
window
.open("../devices/" + e.relatedTarget.options.test, "_parent")
.focus();
};
const zoomIn = (e) => {
if (!map) {
console.error("Karte ist noch nicht initialisiert.");
return;
}
map.flyTo(e.latlng, 12);
};
const zoomOut = (e) => {
fly();
};
const showCoordinates = (e) => {
alert("Breitengrad: " + e.latlng.lat + "\nLängengrad: " + e.latlng.lng);
};
const showData = (e) => {
console.log(e);
};
const showTalas = (e) => {
map.addLayer(TALAS);
loadData();
};
const hideTalas = (e) => {
map.removeLayer(TALAS);
loadData();
};
const showGSM = (e) => {
map.addLayer(GMA);
loadData();
};
const hideGSM = (e) => {
map.removeLayer(GMA);
loadData();
};
//-----Kontextmenu----ende------------
function parsePoint(pointString) {
const match = pointString.match(
/POINT\s*\((\d+(\.\d+)?)\s+(\d+(\.\d+)?)\)/
);
if (match) {
return {
longitude: parseFloat(match[1]),
latitude: parseFloat(match[3]), // Achtung: Index 3 für die zweite Koordinate, wegen der Gruppe (\.\d+)?
};
} else {
// Handle the error or return a default/fallback value
console.error("Invalid POINT format:", pointString);
return null; // Oder eine sinnvolle Standardantwort
}
}
// Beispiel einer Funktion zum Aktualisieren der Position in der Datenbank
const updateLocationInDatabase = async (id, newLatitude, newLongitude) => {
const response = await fetch("/api/updateLocation", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id,
latitude: newLatitude,
longitude: newLongitude,
}),
});
if (response.ok) {
console.log("Position erfolgreich aktualisiert");
//schreib die neue Kooridnaten in die Console
console.log("Latitude: " + newLatitude);
console.log("Longitude: " + newLongitude);
console.log("ID: " + id);
console.log("Response: " + response);
//akuellisiere die Position in der Datenbank mit den neuen Koordinaten mit updateLocation mit SQL Anweisung UPDATE
} else {
console.error("Fehler beim Aktualisieren der Position");
}
};
//-------------------------------------
//------------------- loadData ---------------//
/*
const loadData = () => {
if (!dataStatic || !map) return;
console.log("Initialisiere Marker");
dataStatic.forEach(gisStatic => {
if (filterSystems.includes(gisStatic.System)) {
const markerOptions = {
icon: getIcon(gisStatic.Icon),
test: gisStatic.Link,
device: gisStatic.Device,
system: gisStatic.System,
IdLD: gisStatic.IdLD,
IdLocation: gisStatic.IdLocation,
contextmenu: true,
};
const marker = L.marker([gisStatic.X, gisStatic.Y], markerOptions);
marker.addTo(map);
// Speichern der Markerreferenz in einem Ref-Objekt
markersRef.current[gisStatic.IdLD] = marker;
// Popup und Event-Listener hinzufügen
marker.bindPopup(createPopupContent(gisStatic));
marker.on('click', () => {
console.log('Marker clicked:', gisStatic.IdLD);
});
}
});
};
useEffect(() => {
loadData();
}, [dataStatic, filterSystems, map]); // Abhängigkeiten, die den Neuladevorgang auslösen
*/
//------------------- loadData end---------------//
useEffect(() => {
// Entferne alte Marker
markers.forEach((marker) => map.removeLayer(marker));
if (map) {
const newMarkers = locations.map((location) => {
const { latitude, longitude } = parsePoint(location.position);
const marker = L.marker([latitude, longitude], {
icon: L.icon({
iconUrl: "/location.svg",
iconSize: [34, 34],
iconAnchor: [17, 34],
popupAnchor: [0, -34],
}),
draggable: true,
id: location.idPoi,
});
// Erstellt einen Popup-Inhalt basierend auf den aktuellen Marker-Daten
const createPopupContent = () => {
return `<b>${location.description || "Unbekannt"}</b><br>Type: ${
location.idPoiTyp || "N/A"
}<br>Lat: ${latitude.toFixed(5)}, Lng: ${longitude.toFixed(5)}`;
};
// Bindet das Popup mit dem initialen Inhalt
marker.bindPopup(createPopupContent());
marker.on("dragend", function (e) {
const newLat = e.target.getLatLng().lat;
const newLng = e.target.getLatLng().lng;
const markerId = e.target.options.id;
updateLocationInDatabase(markerId, newLat, newLng).then(() => {
onLocationUpdate(markerId, newLat, newLng);
});
});
// Fügt den Marker der Karte hinzu
marker.addTo(map);
return () => {
if (map) {
map.remove();
}
};
return marker;
});
// Aktualisiere die Marker-Liste im State
setMarkers(newMarkers);
}
}, [map, locations, onLocationUpdate]);
const showAddStationPopup = (e, map) => {
const popupContent = `
<form id="addStationForm" class="m-0 p-2 w-full">
<div class="flex items-center mb-4">
<label for="name" class="block mr-2 flex-none">Name:</label>
<input
type="text"
id="name"
name="name"
placeholder="Name der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="type" class="block mr-3 flex-none">Type:</label>
<input
type="text"
id="type"
name="type"
placeholder="Typ der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lat" class="block mr-2 flex-none">Breitengrad:</label>
<input
type="text"
id="lat"
name="lat"
value="${e.latlng.lat.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lng" class="block mr-2 flex-none">Längengrad:</label>
<input
type="text"
id="lng"
name="lng"
value="${e.latlng.lng.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full"
>
Station hinzufügen
</button>
</form>
`;
L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(map);
// Verzögerung hinzufügen, um sicherzustellen, dass das Formular im DOM verfügbar ist
setTimeout(() => {
const form = document.getElementById("addStationForm");
if (form) {
form.addEventListener("submit", async (event) => {
event.preventDefault();
const name = event.target.name.value;
const type = event.target.type.value;
const lat = event.target.lat.value;
const lng = event.target.lng.value;
// Hier wird `onAddLocation` mit den Werten aufgerufen, die aus dem Formular gesammelt wurden
await onAddLocation(name, type, lat, lng);
map.closePopup();
});
}
}, 10);
};
return <div id="map" ref={mapRef} className="h-screen"></div>;
};
export default MapComponent;

View File

@@ -1,309 +0,0 @@
import { useEffect, useRef, useState } from "react";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "leaflet-contextmenu/dist/leaflet.contextmenu.css";
import "leaflet-contextmenu";
const MapComponent = ({ locations, onAddLocation, onLocationUpdate, dataStatic, mapData }) => {
const [map, setMap] = useState(null);
const mapRef = useRef(null);
const [online, setOnline] = useState(navigator.onLine);
const offlineTileLayer = "../TileMap/mapTiles/{z}/{x}/{y}.png";
const onlineTileLayer = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png";
// Funktionen zur Überwachung der Internetverbindung
const checkInternet = () => {
console.log("Checking internet connectivity...");
fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" })
.then(response => setOnline(response.ok))
.catch(() => setOnline(false));
};
// Initialize map
useEffect(() => {
if (mapRef.current && !map) {
console.log("Initializing map...");
const initializedMap = L.map(mapRef.current, {
center: [53.111111, 8.4625],
zoom: 10,
contextmenu: true,
contextmenuWidth: 140,
contextmenuItems: [
{ text: "Station hinzufügen", callback: showAddStationPopup },
{ text: "Station öffnen (Tab)", icon: "img/screen_new.png", callback: newLink },
{ text: "Station öffnen", icon: "img/screen_same.png", callback: sameLink },
"-", // Divider
{ text: "Reinzoomen", callback: (e) => zoomIn(e, initializedMap) },
{ text: "Rauszoomen", callback: (e) => zoomOut(e, initializedMap) },
{ text: "Hier zentrieren", callback: (e) => centerMap(e, initializedMap) },
"-", // Divider
{ text: "Koordinaten", icon: "img/not_listed_location.png", callback: showCoordinates },
{ text: "Get Data to Console", icon: "img/not_listed_location.png", callback: showData }
]
});
// Adding initial tile layer
const tileLayer = L.tileLayer(online ? onlineTileLayer : offlineTileLayer, {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
minZoom: 7,
maxZoom: 19
});
tileLayer.addTo(initializedMap);
setMap(initializedMap);
// Cleanup function
return () => {
initializedMap.remove();
};
}
}, [mapRef, online]); // React only on online changes for initialization
// Handle online/offline status
useEffect(() => {
window.addEventListener("online", checkInternet);
window.addEventListener("offline", checkInternet);
return () => {
window.removeEventListener("online", checkInternet);
window.removeEventListener("offline", checkInternet);
};
}, []);
// Update map layers based on online status
useEffect(() => {
if (map) {
const newLayer = L.tileLayer(online ? onlineTileLayer : offlineTileLayer, {
minZoom: 7,
maxZoom: online ? 19 : 14,
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
});
map.eachLayer(layer => {
if (layer instanceof L.TileLayer) {
map.removeLayer(layer);
}
});
newLayer.addTo(map);
}
}, [online, map]);
// Marker handling
useEffect(() => {
// Remove old markers
if (map) {
map.eachLayer(layer => {
if (layer instanceof L.Marker) {
map.removeLayer(layer);
}
});
// Add new markers
locations.forEach(location => {
const { latitude, longitude } = parsePoint(location.position);
const marker = L.marker([latitude, longitude], {
icon: L.icon({
iconUrl: "/location.svg",
iconSize: [34, 34],
iconAnchor: [17, 34],
popupAnchor: [0, -34]
}),
draggable: true,
id: location.idPoi
});
marker.bindPopup(`<b>${location.description || "Unbekannt"}</b><br>Type: ${location.idPoiTyp || "N/A"}<br>Lat: ${latitude.toFixed(5)}, Lng: ${longitude.toFixed(5)}`);
marker.on("dragend", function (e) {
const newLat = e.target.getLatLng().lat;
const newLng = e.target.getLatLng().lng;
const markerId = e.target.options.id;
updateLocationInDatabase(markerId, newLat, newLng).then(() => {
onLocationUpdate(markerId, newLat, newLng);
});
});
marker.addTo(map);
});
}
}, [map, locations, onLocationUpdate]);
//------------------------------------------
function parsePoint(pointString) {
const match = pointString.match(
/POINT\s*\((\d+(\.\d+)?)\s+(\d+(\.\d+)?)\)/
);
if (match) {
return {
longitude: parseFloat(match[1]),
latitude: parseFloat(match[3]), // Achtung: Index 3 für die zweite Koordinate, wegen der Gruppe (\.\d+)?
};
} else {
// Handle the error or return a default/fallback value
console.error("Invalid POINT format:", pointString);
return null; // Oder eine sinnvolle Standardantwort
}
}
//----------------------------------
const centerMap = (e) => {
if (!map) {
console.error("Die Karte wurde noch nicht initialisiert.");
return;
}
if (!e || !e.latlng) {
console.error("Fehlerhafte Event-Daten: ", e);
return;
}
console.log("Zentrierung auf: ", e.latlng);
map.panTo(e.latlng);
};
//-----Kontextmenu----------------
const newLink = (e) => {
try {
if (!e.relatedTarget || !e.relatedTarget.options) {
throw new Error("relatedTarget or options not defined");
}
alert("Neues Fenster: " + e.relatedTarget.options.test);
window
.open(`../devices/${e.relatedTarget.options.test}`, "_blank")
.focus();
} catch (error) {
console.error("Failed in newLink function:", error);
}
};
const sameLink = (e) => {
alert(e.relatedTarget.options.test);
window
.open("../devices/" + e.relatedTarget.options.test, "_parent")
.focus();
};
const zoomIn = (e) => {
if (!map) {
console.error("Karte ist noch nicht initialisiert.");
return;
}
map.flyTo(e.latlng, map.getZoom() + 1);
};
const zoomOut = (e) => {
if (!map) {
console.error("Karte ist noch nicht initialisiert.");
return;
}
// Annahme: Du willst beim Rauszoomen die aktuelle Position halten
// und nur den Zoom-Level ändern. Hier reduzieren wir den Zoom-Level um 1.
const currentZoom = map.getZoom();
map.flyTo(e.latlng, map.getZoom() - 1);
};
const showCoordinates = (e) => {
alert("Breitengrad: " + e.latlng.lat + "\nLängengrad: " + e.latlng.lng);
};
const showData = (e) => {
console.log(e);
};
const showTalas = (e) => {
map.addLayer(TALAS);
loadData();
};
const hideTalas = (e) => {
map.removeLayer(TALAS);
loadData();
};
const showGSM = (e) => {
map.addLayer(GMA);
loadData();
};
const hideGSM = (e) => {
map.removeLayer(GMA);
loadData();
};
//-----Kontextmenu----ende------------
const showAddStationPopup = (e, map) => {
const popupContent = `
<form id="addStationForm" class="m-0 p-2 w-full">
<div class="flex items-center mb-4">
<label for="name" class="block mr-2 flex-none">Name:</label>
<input
type="text"
id="name"
name="name"
placeholder="Name der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="type" class="block mr-3 flex-none">Type:</label>
<input
type="text"
id="type"
name="type"
placeholder="Typ der Station"
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lat" class="block mr-2 flex-none">Breitengrad:</label>
<input
type="text"
id="lat"
name="lat"
value="${e.latlng.lat.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<div class="flex items-center mb-4">
<label for="lng" class="block mr-2 flex-none">Längengrad:</label>
<input
type="text"
id="lng"
name="lng"
value="${e.latlng.lng.toFixed(5)}"
readonly
class="block p-2 flex-grow border-2 border-gray-200 rounded-md text-sm"
/>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded w-full"
>
Station hinzufügen
</button>
</form>
`;
L.popup().setLatLng(e.latlng).setContent(popupContent).openOn(map);
// Verzögerung hinzufügen, um sicherzustellen, dass das Formular im DOM verfügbar ist
setTimeout(() => {
const form = document.getElementById("addStationForm");
if (form) {
form.addEventListener("submit", async (event) => {
event.preventDefault();
const name = event.target.name.value;
const type = event.target.type.value;
const lat = event.target.lat.value;
const lng = event.target.lng.value;
// Hier wird `onAddLocation` mit den Werten aufgerufen, die aus dem Formular gesammelt wurden
await onAddLocation(name, type, lat, lng);
map.closePopup();
});
}
}, 10);
};
return <div id="map" ref={mapRef} className="h-screen"></div>;
};
export default MapComponent;

View File

@@ -10,6 +10,7 @@ import "leaflet.smooth_marker_bouncing";
//import { OverlappingMarkerSpiderfier } from "../lib/OverlappingMarkerSpiderfier.js";
//import { OverlappingMarkerSpiderfier } from "../public/js/OverlappingMarkerSpiderfier.js";
import OverlappingMarkerSpiderfier from "overlapping-marker-spiderfier-leaflet";
import DataSheet from "../components/DataSheet";
const MapComponent = ({ locations, onLocationUpdate }) => {
const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte
@@ -635,17 +636,77 @@ const MapComponent = ({ locations, onLocationUpdate }) => {
${station.Location_Short} (${station.Location_Name})<br>
${statusInfo}<br>
`);
let LocID = station.IdLocation;
marker
.bindTooltip(
`<div class="bg-white text-black p-2 border border-gray-300 rounded shadow">${LocID}</div>`,
{
permanent: true,
direction: "right",
opacity: 0,
offset: L.point({ x: 10, y: 0 }),
}
)
.addTo(GMA);
});
}, [map, oms, GisStationsStaticDistrict, GisStationsStatusDistrict]);
//------------------------------------------
let uniqueIdLDsData = [];
let Tooltip = [];
for (let index = 0; index < uniqueIdLDsData.length; index++) {
let element = uniqueIdLDsData[index].split(",");
let lat = element[0];
let lng = element[1];
let ID = element[2];
let IdLD = element[3];
let LocID = element[4];
Tooltip[LocID] = L.marker([lat, lng], { icon: invisibleMarker })
.bindTooltip(
'<div id="tip-' +
LocID +
'">' +
'<div id="areaname' +
LocID +
'" style="font-weight:700;font-size:0.9rem">---</div>' +
'<div id="value1-' +
LocID +
'" style="font-weight:700;color:blue">---</div>' +
'<div id="value2-' +
LocID +
'" style="font-weight:700;color:red">---</div>' +
'<div id="value3-' +
LocID +
'" style="font-weight:700;color:#ECC5C0">---</div>' +
'<div id="value4-' +
LocID +
'" style="font-weight:700;color:green">---</div>' +
"</div>",
{
permanent: true,
direction: "right",
opacity: 0,
offset: L.point({ x: 10, y: 0 }),
}
)
.openTooltip()
.addTo(GMA);
}
//------------------------------------------
return (
<>
<DataSheet className="z-50" />
<div
id="map"
ref={mapRef}
style={{ height: "100vh", width: "100vw", overflow: "hidden" }}
className="z-0"
style={{ height: "100vh", width: "100vw" }}
></div>
</>
);
};

View File

@@ -3,7 +3,15 @@ module.exports = {
purge: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"],
content: [],
theme: {
extend: {},
extend: {
zIndex: {
60: "60",
70: "70",
80: "80",
90: "90",
100: "100",
},
},
},
plugins: [],
};