import L from "leaflet"; export class OverlappingMarkerSpiderfier { constructor(map, options = {}) { this.map = map; this.markers = []; this.markerListeners = []; this.keepSpiderfied = options.keepSpiderfied || false; // Basiseinstellungen für die Distanz und die Zoomstufenabhängigkeit this.baseNearbyDistance = options.nearbyDistance || 20; this.nearbyDistance = this.baseNearbyDistance; // Initialwert setzen this.circleSpiralSwitchover = options.circleSpiralSwitchover || 9; this.circleFootSeparation = options.circleFootSeparation || 25; this.circleStartAngle = options.circleStartAngle || Math.PI / 6; this.spiralFootSeparation = options.spiralFootSeparation || 28; this.spiralLengthStart = options.spiralLengthStart || 11; this.spiralLengthFactor = options.spiralLengthFactor || 5; this.legWeight = options.legWeight || 1.5; this.legColors = options.legColors || { usual: "#222", highlighted: "#f00", }; this.initMarkerArrays(); this.map.on("click", () => this.unspiderfy()); this.map.on("zoomend", () => this.unspiderfy()); } initMarkerArrays() { this.markers = []; this.markerListeners = []; } addMarker(marker) { if (!marker._oms) { marker._oms = {}; // Stellt sicher, dass _oms ein Objekt ist } const listener = () => { this.spiderListener(marker); }; marker.on("click", listener); this.markerListeners.push(listener); this.markers.push(marker); return this; } spiderListener(marker) { const spidered = marker._oms.spidered; if (!spidered) { const nearMarkers = this.nearbyMarkers(marker); if (nearMarkers.length > 1) { this.spiderfy(nearMarkers); } } else { this.unspiderfy(); // Schließt alle gespiderfied Marker, wenn einer erneut geklickt wird } } nearbyMarkers(marker) { return this.markers.filter((m) => { const distance = this.map.distance(marker.getLatLng(), m.getLatLng()); return distance < this.nearbyDistance && marker !== m; }); } 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._oms) { marker._oms = {}; // Stellt sicher, dass _oms ein Objekt ist } // 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 } }); } }