diff --git a/components/MapComponent.js b/components/MapComponent.js index f7cfb3cbe..c11eabfec 100644 --- a/components/MapComponent.js +++ b/components/MapComponent.js @@ -5,88 +5,16 @@ import "leaflet/dist/leaflet.css"; import "leaflet-contextmenu/dist/leaflet.contextmenu.css"; import "leaflet-contextmenu"; import * as config from "../config/config.js"; +import dynamic from "next/dynamic"; +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"; const MapComponent = ({ locations, onLocationUpdate }) => { const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte const [map, setMap] = useState(null); // Zustand der Karteninstanz const [online, setOnline] = useState(navigator.onLine); // Zustand der Internetverbindung - // Funktionen zur Überwachung der Internetverbindung - const checkInternet = () => { - fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) - .then((response) => setOnline(response.ok)) - .catch(() => setOnline(false)); - }; - - // Handle online/offline status - useEffect(() => { - window.addEventListener("online", checkInternet); - window.addEventListener("offline", checkInternet); - return () => { - window.removeEventListener("online", checkInternet); - window.removeEventListener("offline", checkInternet); - }; - }, []); - // Initialisiere die Karte - useEffect(() => { - if (mapRef.current && !map) { - initialMap = L.map(mapRef.current, { - center: [53.111111, 8.4625], - zoom: 10, - layers: [ - TALAS, - ECI, - ULAF, - GSMModem, - CiscoRouter, - WAGO, - Siemens, - OTDR, - WDM, - GMA, - Sonstige, - TALASICL, - ], - zoomControl: false, // Deaktiviere die Standard-Zoomsteuerung - contextmenu: true, - 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, - }, - { - text: "Koordinaten", - icon: "img/screen_same.png", - callback: lata, - }, - "-", // Divider - { text: "Reinzoomen", callback: zoomIn }, - { text: "Rauszoomen", callback: zoomOut }, - { text: "Hier zentrieren", callback: centerHere }, - ], - }); - L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { - attribution: - '© OpenStreetMap contributors', - }).addTo(initialMap); - - if (window.OverlappingMarkerSpiderfier) { - const oms = new window.OverlappingMarkerSpiderfier(initialMap, { - nearbyDistance: 50, - }); - setOms(oms); - } - setMap(initialMap); - - setMap(initialMap); - } - }, [mapRef, map]); const [GisStationsStaticDistrict, setGisStationsStaticDistrict] = useState( [] ); // Zustand für statische Daten @@ -154,65 +82,6 @@ const MapComponent = ({ locations, onLocationUpdate }) => { fetchData(); }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen - //------------------------------------------ - //\talas5\TileMap\img\icons\icon1.png - // minor-marker-icon-23.png - - // Marker hinzufügen für GisStationsStaticDistrict - useEffect(() => { - if (map && GisStationsStaticDistrict.length > 0) { - // Zuerst alte Marker entfernen - /* map.eachLayer((layer) => { - if (layer instanceof L.Marker) { - map.removeLayer(layer); - } - }); */ - - // Neue Marker für jede Station hinzufügen - GisStationsStaticDistrict.forEach((station) => { - const marker = L.marker([station.X, station.Y], { - // X als Breitengrad, Y als Längengrad - icon: L.icon({ - iconUrl: getIconPath(station.Icon), - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - shadowSize: [41, 41], - }), - }).addTo(map); - - // Popup beim Überfahren mit der Maus öffnen - marker.on("mouseover", function (e) { - this.openPopup(); - }); - - // Popup schließen, wenn die Maus den Marker verlässt - marker.on("mouseout", function (e) { - this.closePopup(); - }); - // Ein Popup mit Informationen zur Station hinzufügen - marker - .bindPopup(`${station.LD_Name}
${station.Device}`) - .openPopup(); - marker.bindTooltip( - `
${station.LD_Name}
`, - { permanent: false, direction: "top" } - ); - // Zugriff auf das Tooltip-Element und Anwendung von Stilen - marker.on("mouseover", () => { - document.querySelector(".tooltip-content").style.backgroundColor = - "#ffffff"; - document.querySelector(".tooltip-content").style.padding = "0.5rem"; - document.querySelector(".tooltip-content").style.borderRadius = - "0.25rem"; - document.querySelector(".tooltip-content").style.border = - "1px solid #d1d5db"; - }); - }); - } - }, [map, GisStationsStaticDistrict]); // Abhängigkeiten hinzufügen, um sicherzustellen, dass Effekt bei Änderungen neu ausgeführt wird - - //------------------------------------------ //GisStationsStaticDistrict Daten laden useEffect(() => { const fetchData = async () => { @@ -266,6 +135,7 @@ const MapComponent = ({ locations, onLocationUpdate }) => { }, []); // Dependency-Array ist leer, um den Effekt nur beim Mount auszuführen //------------------------------------------ //GisStationsMeasurements Daten laden + useEffect(() => { const fetchData = async () => { try { @@ -343,31 +213,74 @@ const MapComponent = ({ locations, onLocationUpdate }) => { } }, []); - // Update map layers based on online status + // Funktionen zur Überwachung der Internetverbindung + const checkInternet = () => { + fetch("https://tile.openstreetmap.org/1/1/1.png", { method: "HEAD" }) + .then((response) => setOnline(response.ok)) + .catch(() => setOnline(false)); + }; + // Initialisierung der karte und hinzuügen der Layers useEffect(() => { - if (map) { - const newLayer = L.tileLayer( - online ? onlineTileLayer : offlineTileLayer, - { - minZoom: 7, - maxZoom: online ? 19 : 14, - attribution: - 'Map data © OpenStreetMap contributors', - } - ); - - map.eachLayer((layer) => { - if (layer instanceof L.TileLayer) { - map.removeLayer(layer); - } + if (mapRef.current && !map) { + const newMap = L.map(mapRef.current, { + center: [53.111111, 8.4625], + zoom: 8, + layers: [ + TALAS, + ECI, + ULAF, + GSMModem, + CiscoRouter, + WAGO, + Siemens, + OTDR, + WDM, + GMA, + Sonstige, + TALASICL, + ], + zoomControl: false, // Deaktiviere die Standard-Zoomsteuerung + contextmenu: true, + 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, + }, + { + text: "Koordinaten", + icon: "img/screen_same.png", + callback: lata, + }, + "-", // Divider + { text: "Reinzoomen", callback: zoomIn }, + { text: "Rauszoomen", callback: zoomOut }, + { text: "Hier zentrieren", callback: centerHere }, + ], }); - newLayer.addTo(map); - } - }, [online, map]); + L.tileLayer(online ? onlineTileLayer : offlineTileLayer, { + attribution: + '© OpenStreetMap contributors', + }).addTo(newMap); - // Marker handling - useEffect(() => { + const newOms = new window.OverlappingMarkerSpiderfier(newMap, { + nearbyDistance: 50, + }); + + setMap(newMap); + setOms(newOms); + } + }, [mapRef, map]); // Abhängigkeiten prüfen + + // Marker hinzufügen von lokale MySQL Datenbank und nicht von APIs + /* useEffect(() => { // Remove old markers if (map) { map.eachLayer((layer) => { @@ -410,7 +323,7 @@ const MapComponent = ({ locations, onLocationUpdate }) => { marker.addTo(map); }); } - }, [map, locations, onLocationUpdate]); + }, [map, locations, onLocationUpdate]); */ //------------------------------------------ function parsePoint(pointString) { @@ -557,22 +470,6 @@ const MapComponent = ({ locations, onLocationUpdate }) => { L.DomEvent.on(popupContent, "submit", handleSubmit); }; - /* - const handleSubmit = (event) => { - event.preventDefault(); - const form = event.target; - const data = { - name: form.name.value, - type: form.type.value, - latitude: form.lat.value, - longitude: form.lng.value, - }; - - onAddLocation(name, type, lat, lng); - console.log("Name: ", name, "Type: ", type, "Lat: ", lat, "Lng: ", lng); - map.closePopup(); - }; -*/ // Funktion zum Hinzufügen eines neuen Standorts async function handleSubmit(event) { event.preventDefault(); @@ -615,138 +512,123 @@ const MapComponent = ({ locations, onLocationUpdate }) => { var y = 7.739617925303934; var zoom = 7; - /* for (var i = 0; i < GisStationsStaticDistrictlength; i++) { - var gisStatics = GisStationsStaticDistrict[i]; - if (stationValue === gisStatics.Area_Name) { - //console.log(gisStatics.X+","+gisStatics.Y); - x = gisStatics.X; - y = gisStatics.Y; + initialMap.flyTo([x, y], zoom); + } + + function getIconPath(status, iconNumber, marker) { + let path = status + ? `TileMap/img/icons/${status}-marker-icon-${iconNumber}.png` + : `TileMap/img/icons/marker-icon-${iconNumber}.png`; + + // Wenn der Pfad das Wort "critical" enthält, dann den Marker bouncing options setzen + if (path.includes("critical")) { + // Setze Bouncing-Optionen + marker.setBouncingOptions({ + bounceHeight: 15, // Höhe des Bounces + contractHeight: 12, // Höhe des Einzugs beim Landen + bounceSpeed: 52, // Geschwindigkeit des Bounces + contractSpeed: 52, // Geschwindigkeit des Einzugs + shadowAngle: null, // Standard-Schattenwinkel + }); + // Check if the icon path includes 'critical' + if (path.includes("critical")) { + // marker.bounce(3); } } - if (y === 7.739617925303934) { - zoom = 8; - } */ - initialMap.flyTo([x, y], zoom); - /* var popup = new L.Popup(); - oms.addListener("click", function (marker) { - popup.setContent(marker.desc); - popup.setLatLng(marker.getLatLng()); - map.openPopup(popup); - }); - - for (var i = 0; i < window.mapData.length; i++) { - var datum = window.mapData[i]; - var loc = new L.LatLng(datum.lat, datum.lon); - var marker = new L.Marker(loc); - marker.desc = datum.d; - map.addLayer(marker); - //oms.addMarker(marker); // <-- here - } */ - - //------------------------------------- + return path; } + //------------------------------------------ - //Informationen in Tooltips einfügen + //\talas5\TileMap\img\icons\icon1.png + // minor-marker-icon-23.png + // Marker hinzufügen für GisStationsStaticDistrict useEffect(() => { - if (map && oms && GisStationsStaticDistrict.length > 0) { - map.eachLayer((layer) => { - if (layer instanceof L.Marker) { - map.removeLayer(layer); - } - }); + // Stellen Sie sicher, dass sowohl `map` als auch `oms` initialisiert sind + if (!map || !oms) { + console.error("Map or OMS is not initialized"); + return; + } - GisStationsStaticDistrict.forEach((station) => { - // Filtere alle Statusobjekte für diese station.Na - const statusObjects = GisStationsStatusDistrict.filter( - (status) => status.IdLD === station.IdLD - ); + // Alte Marker entfernen, indem alle Marker, die durch OMS verwaltet werden, gelöscht werden + oms.clearMarkers(); + map.eachLayer((layer) => { + if (layer instanceof L.Marker) { + map.removeLayer(layer); + } + }); - // Alle Status-Objekte mit gleicher IdLD finden - const matchingStatuses = GisStationsStatusDistrict.filter( - (status) => status.IdLD === station.IdLD - ); - let status2 = ""; - let statusInfo = ""; + // Neue Marker für jede Station hinzufügen + GisStationsStaticDistrict.forEach((station) => { + // Filter für Statusobjekte dieser spezifischen Station + const matchingStatuses = GisStationsStatusDistrict.filter( + (status) => status.IdLD === station.IdLD + ); - // Umdrehen der Reihenfolge der Statusmeldungen - matchingStatuses.reverse().forEach((status) => { - statusInfo += ` -
-
- ${status.Me} (${status.Na}) -
`; + const marker = L.marker([station.X, station.Y], { + icon: L.icon({ + iconUrl: "default-icon.png", // Default, wird geändert + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41], + }), + }).addTo(map); - status2 = status.Na; - }); - - let iconPath = getIconPath(status2, station.Icon); - - const marker = L.marker([station.X, station.Y], { - icon: L.icon({ - iconUrl: iconPath, - iconSize: [25, 41], - iconAnchor: [12, 41], - popupAnchor: [1, -34], - shadowSize: [41, 41], - }), - }); - - marker.addTo(map); - oms.addMarker(marker); // Add marker to the OverlappingMarkerSpiderfier instance - marker.on("mouseover", function (e) { - this.openPopup(); - }); - - marker.on("mouseout", function (e) { - this.closePopup(); - }); + // String-Zusammenstellung für das Popup-Infofenster + let statusInfo = matchingStatuses + .reverse() + .map( + (status) => ` +
+
+ ${status.Me} (${status.Na}) +
+ ` + ) + .join(""); + // Bestimmen des Icons basierend auf dem Status + let iconPath = getIconPath( + matchingStatuses[0]?.Na || "", + station.Icon, marker - .bindPopup( - `${station.LD_Name}
${station.Device}
${station.Area_Short} (${station.Area_Name})
${station.Location_Short} (${station.Location_Name})
${statusInfo}

` - ) - .openPopup(); - }); - } - }, [map, GisStationsStaticDistrict, oms, GisStationsStatusDistrict]); // Include GisStationsStatusDistrict in dependencies + ); + + marker.setIcon( + L.icon({ + iconUrl: iconPath, + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41], + }) + ); + // Check if the icon path includes 'critical' and initiate bouncing + if (iconPath.includes("critical")) { + marker.setBouncingOptions({ + bounceHeight: 15, + contractHeight: 12, + bounceSpeed: 52, + contractSpeed: 52, + shadowAngle: null, + }); + marker.bounce(3); + } + // Marker zu OMS und der Karte hinzufügen + oms.addMarker(marker); + marker.addTo(map).bindPopup(` + ${station.LD_Name}
+ ${station.Device}
+ ${station.Area_Short} (${station.Area_Name})
+ ${station.Location_Short} (${station.Location_Name})
+ ${statusInfo}
+ `); + }); + }, [map, oms, GisStationsStaticDistrict, GisStationsStatusDistrict]); //------------------------------------------ - // Funktion, die den Pfad zum entsprechenden Icon basierend auf dem Status generiert - /* function getIconPath(status, iconId) { - let prefix = ""; - switch (status) { - case "critical": - prefix = "critical-marker-icon"; - break; - case "major": - prefix = "major-marker-icon"; - break; - case "minor": - prefix = "minor-marker-icon"; - break; - case "system": - prefix = "system-marker-icon"; - break; - case "ok": - default: - prefix = "marker-icon"; // Annahme: "ok" ist der Standardstatus und grün - break; - } - return `path/to/icons/${prefix}-${iconId}.png`; - } */ - //------------------------------------------ - function getIconPath(status, iconNumber) { - if (status) { - // Wenn status vorhanden ist, füge ihn in den Pfad ein mit Bindestrich - - return `TileMap/img/icons/${status}-marker-icon-${iconNumber}.png`; - } else { - // Wenn kein status vorhanden ist, lasse den Status-Teil ganz weg - return `TileMap/img/icons/marker-icon-${iconNumber}.png`; - } - } return (
this.unspiderfy()); + this.map.on("zoomend", () => this.unspiderfy()); } - this['OverlappingMarkerSpiderfier'] = (function() { - var p, twoPi; + initMarkerArrays() { + this.markers = []; + this.markerListeners = []; + } - p = _Class.prototype; - - p['VERSION'] = '0.2.6'; - - twoPi = Math.PI * 2; - - p['keepSpiderfied'] = false; - - p['nearbyDistance'] = 20; - - p['circleSpiralSwitchover'] = 9; - - p['circleFootSeparation'] = 25; - - p['circleStartAngle'] = twoPi / 12; - - p['spiralFootSeparation'] = 28; - - p['spiralLengthStart'] = 11; - - p['spiralLengthFactor'] = 5; - - p['legWeight'] = 1.5; - - p['legColors'] = { - 'usual': '#222', - 'highlighted': '#f00' - }; - - function _Class(map, opts) { - var e, k, v, _i, _len, _ref, - _this = this; - - this.map = map; - if (opts == null) { - opts = {}; - } - for (k in opts) { - if (!__hasProp.call(opts, k)) continue; - v = opts[k]; - this[k] = v; - } - this.initMarkerArrays(); - this.listeners = {}; - _ref = ['click', 'zoomend']; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - e = _ref[_i]; - this.map.addEventListener(e, function() { - return _this['unspiderfy'](); - }); - } + addMarker(marker) { + if (!marker._oms) { + marker._oms = {}; // Stellt sicher, dass _oms ein Objekt ist } - p.initMarkerArrays = function() { - this.markers = []; - return this.markerListeners = []; + const listener = () => { + this.spiderListener(marker); }; - p['addMarker'] = function(marker) { - var markerListener, - _this = this; + marker.on("click", listener); + this.markerListeners.push(listener); + this.markers.push(marker); - if (marker['_oms'] != null) { - return this; + return this; + } + + spiderListener(marker) { + const spidered = marker._oms.spidered; + if (!spidered) { + const nearMarkers = this.nearbyMarkers(marker); + if (nearMarkers.length > 1) { + this.spiderfy(nearMarkers); } - marker['_oms'] = true; - markerListener = function() { - return _this.spiderListener(marker); - }; - marker.addEventListener('click', markerListener); - this.markerListeners.push(markerListener); - this.markers.push(marker); - return this; - }; + } else { + this.unspiderfy(); // Schließt alle gespiderfied Marker, wenn einer erneut geklickt wird + } + } - p['getMarkers'] = function() { - return this.markers.slice(0); - }; + nearbyMarkers(marker) { + return this.markers.filter((m) => { + const distance = this.map.distance(marker.getLatLng(), m.getLatLng()); + return distance < this.nearbyDistance && marker !== m; + }); + } - p['removeMarker'] = function(marker) { - var i, markerListener; + spiderfy(markers) { + const centerPt = this.map.latLngToLayerPoint(markers[0].getLatLng()); + markers.forEach((marker, i) => { + const angle = this.circleStartAngle + (i * 2 * Math.PI) / markers.length; + const legLength = this.circleFootSeparation * (2 + i / markers.length); + const newPt = L.point( + centerPt.x + legLength * Math.cos(angle), + centerPt.y + legLength * Math.sin(angle) + ); + const newLatLng = this.map.layerPointToLatLng(newPt); - if (marker['_omsData'] != null) { - this['unspiderfy'](); + if (!marker._oms) { + marker._oms = {}; // Stellt sicher, dass _oms ein Objekt ist } - i = this.arrIndexOf(this.markers, marker); - if (i < 0) { - return this; + + // Speichert die aktuelle Position, bevor sie verändert wird + marker._oms.usualPosition = marker.getLatLng(); + marker._oms.spidered = true; // Markiert, dass der Marker gespiderfied ist + + marker.setLatLng(newLatLng); + marker.setZIndexOffset(1000); + }); + } + unspiderfy() { + this.markers.forEach((marker) => { + if (marker._oms && marker._oms.spidered) { + // Setzt den Marker nur dann zurück, wenn er gespiderfied war + marker.setLatLng(marker._oms.usualPosition); + marker.setZIndexOffset(0); + marker._oms.spidered = false; // Setzt zurück, dass der Marker nicht mehr gespiderfied ist } - markerListener = this.markerListeners.splice(i, 1)[0]; - marker.removeEventListener('click', markerListener); - delete marker['_oms']; - this.markers.splice(i, 1); - return this; - }; - - p['clearMarkers'] = function() { - var i, marker, markerListener, _i, _len, _ref; - - this['unspiderfy'](); - _ref = this.markers; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - marker = _ref[i]; - markerListener = this.markerListeners[i]; - marker.removeEventListener('click', markerListener); - delete marker['_oms']; - } - this.initMarkerArrays(); - return this; - }; - - p['addListener'] = function(event, func) { - var _base, _ref; - - ((_ref = (_base = this.listeners)[event]) != null ? _ref : _base[event] = []).push(func); - return this; - }; - - p['removeListener'] = function(event, func) { - var i; - - i = this.arrIndexOf(this.listeners[event], func); - if (!(i < 0)) { - this.listeners[event].splice(i, 1); - } - return this; - }; - - p['clearListeners'] = function(event) { - this.listeners[event] = []; - return this; - }; - - p.trigger = function() { - var args, event, func, _i, _len, _ref, _ref1, _results; - - event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - _ref1 = (_ref = this.listeners[event]) != null ? _ref : []; - _results = []; - for (_i = 0, _len = _ref1.length; _i < _len; _i++) { - func = _ref1[_i]; - _results.push(func.apply(null, args)); - } - return _results; - }; - - p.generatePtsCircle = function(count, centerPt) { - var angle, angleStep, circumference, i, legLength, _i, _results; - - circumference = this['circleFootSeparation'] * (2 + count); - legLength = circumference / twoPi; - angleStep = twoPi / count; - _results = []; - for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) { - angle = this['circleStartAngle'] + i * angleStep; - _results.push(new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))); - } - return _results; - }; - - p.generatePtsSpiral = function(count, centerPt) { - var angle, i, legLength, pt, _i, _results; - - legLength = this['spiralLengthStart']; - angle = 0; - _results = []; - for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) { - angle += this['spiralFootSeparation'] / legLength + i * 0.0005; - pt = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle)); - legLength += twoPi * this['spiralLengthFactor'] / angle; - _results.push(pt); - } - return _results; - }; - - p.spiderListener = function(marker) { - var m, mPt, markerPt, markerSpiderfied, nearbyMarkerData, nonNearbyMarkers, pxSq, _i, _len, _ref; - - markerSpiderfied = marker['_omsData'] != null; - if (!(markerSpiderfied && this['keepSpiderfied'])) { - this['unspiderfy'](); - } - if (markerSpiderfied) { - return this.trigger('click', marker); - } else { - nearbyMarkerData = []; - nonNearbyMarkers = []; - pxSq = this['nearbyDistance'] * this['nearbyDistance']; - markerPt = this.map.latLngToLayerPoint(marker.getLatLng()); - _ref = this.markers; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - m = _ref[_i]; - if (!this.map.hasLayer(m)) { - continue; - } - mPt = this.map.latLngToLayerPoint(m.getLatLng()); - if (this.ptDistanceSq(mPt, markerPt) < pxSq) { - nearbyMarkerData.push({ - marker: m, - markerPt: mPt - }); - } else { - nonNearbyMarkers.push(m); - } - } - if (nearbyMarkerData.length === 1) { - return this.trigger('click', marker); - } else { - return this.spiderfy(nearbyMarkerData, nonNearbyMarkers); - } - } - }; - - p.makeHighlightListeners = function(marker) { - var _this = this; - - return { - highlight: function() { - return marker['_omsData'].leg.setStyle({ - color: _this['legColors']['highlighted'] - }); - }, - unhighlight: function() { - return marker['_omsData'].leg.setStyle({ - color: _this['legColors']['usual'] - }); - } - }; - }; - - p.spiderfy = function(markerData, nonNearbyMarkers) { - var bodyPt, footLl, footPt, footPts, leg, marker, md, mhl, nearestMarkerDatum, numFeet, spiderfiedMarkers; - - this.spiderfying = true; - numFeet = markerData.length; - bodyPt = this.ptAverage((function() { - var _i, _len, _results; - - _results = []; - for (_i = 0, _len = markerData.length; _i < _len; _i++) { - md = markerData[_i]; - _results.push(md.markerPt); - } - return _results; - })()); - footPts = numFeet >= this['circleSpiralSwitchover'] ? this.generatePtsSpiral(numFeet, bodyPt).reverse() : this.generatePtsCircle(numFeet, bodyPt); - spiderfiedMarkers = (function() { - var _i, _len, _results, - _this = this; - - _results = []; - for (_i = 0, _len = footPts.length; _i < _len; _i++) { - footPt = footPts[_i]; - footLl = this.map.layerPointToLatLng(footPt); - nearestMarkerDatum = this.minExtract(markerData, function(md) { - return _this.ptDistanceSq(md.markerPt, footPt); - }); - marker = nearestMarkerDatum.marker; - leg = new L.Polyline([marker.getLatLng(), footLl], { - color: this['legColors']['usual'], - weight: this['legWeight'], - clickable: false - }); - this.map.addLayer(leg); - marker['_omsData'] = { - usualPosition: marker.getLatLng(), - leg: leg - }; - if (this['legColors']['highlighted'] !== this['legColors']['usual']) { - mhl = this.makeHighlightListeners(marker); - marker['_omsData'].highlightListeners = mhl; - marker.addEventListener('mouseover', mhl.highlight); - marker.addEventListener('mouseout', mhl.unhighlight); - } - marker.setLatLng(footLl); - marker.setZIndexOffset(1000000); - _results.push(marker); - } - return _results; - }).call(this); - delete this.spiderfying; - this.spiderfied = true; - return this.trigger('spiderfy', spiderfiedMarkers, nonNearbyMarkers); - }; - - p['unspiderfy'] = function(markerNotToMove) { - var marker, mhl, nonNearbyMarkers, unspiderfiedMarkers, _i, _len, _ref; - - if (markerNotToMove == null) { - markerNotToMove = null; - } - if (this.spiderfied == null) { - return this; - } - this.unspiderfying = true; - unspiderfiedMarkers = []; - nonNearbyMarkers = []; - _ref = this.markers; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - marker = _ref[_i]; - if (marker['_omsData'] != null) { - this.map.removeLayer(marker['_omsData'].leg); - if (marker !== markerNotToMove) { - marker.setLatLng(marker['_omsData'].usualPosition); - } - marker.setZIndexOffset(0); - mhl = marker['_omsData'].highlightListeners; - if (mhl != null) { - marker.removeEventListener('mouseover', mhl.highlight); - marker.removeEventListener('mouseout', mhl.unhighlight); - } - delete marker['_omsData']; - unspiderfiedMarkers.push(marker); - } else { - nonNearbyMarkers.push(marker); - } - } - delete this.unspiderfying; - delete this.spiderfied; - this.trigger('unspiderfy', unspiderfiedMarkers, nonNearbyMarkers); - return this; - }; - - p.ptDistanceSq = function(pt1, pt2) { - var dx, dy; - - dx = pt1.x - pt2.x; - dy = pt1.y - pt2.y; - return dx * dx + dy * dy; - }; - - p.ptAverage = function(pts) { - var numPts, pt, sumX, sumY, _i, _len; - - sumX = sumY = 0; - for (_i = 0, _len = pts.length; _i < _len; _i++) { - pt = pts[_i]; - sumX += pt.x; - sumY += pt.y; - } - numPts = pts.length; - return new L.Point(sumX / numPts, sumY / numPts); - }; - - p.minExtract = function(set, func) { - var bestIndex, bestVal, index, item, val, _i, _len; - - for (index = _i = 0, _len = set.length; _i < _len; index = ++_i) { - item = set[index]; - val = func(item); - if ((typeof bestIndex === "undefined" || bestIndex === null) || val < bestVal) { - bestVal = val; - bestIndex = index; - } - } - return set.splice(bestIndex, 1)[0]; - }; - - p.arrIndexOf = function(arr, obj) { - var i, o, _i, _len; - - if (arr.indexOf != null) { - return arr.indexOf(obj); - } - for (i = _i = 0, _len = arr.length; _i < _len; i = ++_i) { - o = arr[i]; - if (o === obj) { - return i; - } - } - return -1; - }; - - return _Class; - - })(); - -}).call(this); \ No newline at end of file + }); + } +} diff --git a/package-lock.json b/package-lock.json index 9ece24073..a312a76d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "wwwrootTalas5NodeMap", + "name": "wwwrootTalas5NodeMap4", "lockfileVersion": 3, "requires": true, "packages": { @@ -8,8 +8,10 @@ "http-proxy-middleware": "^3.0.0", "leaflet": "^1.9.4", "leaflet-contextmenu": "^1.4.0", + "leaflet.smooth_marker_bouncing": "^3.0.3", "mysql": "^2.18.1", "next": "^14.2.0", + "overlapping-marker-spiderfier-leaflet": "^0.2.7", "react": "^18.2.0", "react-dom": "^18.2.0", "react-leaflet": "^4.2.1" @@ -1013,6 +1015,11 @@ "resolved": "https://registry.npmjs.org/leaflet-contextmenu/-/leaflet-contextmenu-1.4.0.tgz", "integrity": "sha512-BXASCmJ5bLkuJGDCpWmvGqhZi5AzeOY0IbQalfkgBcMAMfAOFSvD4y0gIQxF/XzEyLkjXaRiUpibVj4+Cf3tUA==" }, + "node_modules/leaflet.smooth_marker_bouncing": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/leaflet.smooth_marker_bouncing/-/leaflet.smooth_marker_bouncing-3.0.3.tgz", + "integrity": "sha512-Y+1MJ1nX0vy/NjvzW4Kq2gE3Pnpz3fgP3dZJQNMQW90bFQ8d2TjXrqazP5oWKNUWjvrVVzfMv/FrB7vUFmsLDA==" + }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", @@ -1258,6 +1265,11 @@ "node": ">= 6" } }, + "node_modules/overlapping-marker-spiderfier-leaflet": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/overlapping-marker-spiderfier-leaflet/-/overlapping-marker-spiderfier-leaflet-0.2.7.tgz", + "integrity": "sha512-U2biV2Ge0SU+4IEmq4BZOglvzA8Aj8G7/hp5v6lBnF9Kd3/Xf6ZEPsJyPOExtLvMxOqlrlTAfl55s6JJDND7Ew==" + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", diff --git a/package.json b/package.json index b1fcd9074..cd8729262 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,10 @@ "http-proxy-middleware": "^3.0.0", "leaflet": "^1.9.4", "leaflet-contextmenu": "^1.4.0", + "leaflet.smooth_marker_bouncing": "^3.0.3", "mysql": "^2.18.1", "next": "^14.2.0", + "overlapping-marker-spiderfier-leaflet": "^0.2.7", "react": "^18.2.0", "react-dom": "^18.2.0", "react-leaflet": "^4.2.1" diff --git a/pages/_app.js b/pages/_app.js index d53589400..608d571a7 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -14,3 +14,20 @@ export default function MyApp({ Component, pageProps }) { ); } + +// Bibliotheken, die in der _app.js-Datei importiert werden, werden auf jeder Seite geladen. +/* import Script from 'next/script'; + +function MyApp({ Component, pageProps }) { + return ( + <> +