From d183b0248fc7374851933de66ffe599825568771 Mon Sep 17 00:00:00 2001 From: Alexander Borg Date: Mon, 18 Aug 2025 09:05:20 +0200 Subject: [PATCH] Fix jwt-token --- client/src/pages/MapView.jsx | 219 ++++++++++++++++++++++++----------- 1 file changed, 154 insertions(+), 65 deletions(-) diff --git a/client/src/pages/MapView.jsx b/client/src/pages/MapView.jsx index 5bae316..c6185dd 100644 --- a/client/src/pages/MapView.jsx +++ b/client/src/pages/MapView.jsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { MapContainer, TileLayer, Marker, Popup, Circle, useMap } from 'react-leaflet'; import { Icon } from 'leaflet'; +import L from 'leaflet'; // For divIcon and other Leaflet utilities import { useSocket } from '../contexts/SocketContext'; import api from '../services/api'; import { format } from 'date-fns'; @@ -310,75 +311,157 @@ const MapView = () => { })} {/* RSSI-based Detection Rings around Detectors */} - {showDroneDetections && droneDetectionHistory - .filter(detection => { - const hasCoords = detection.geo_lat && detection.geo_lon; - console.log('MapView: Filtering detection:', detection, 'hasCoords:', hasCoords); - return hasCoords; - }) - .map(detection => { - console.log('MapView: Rendering ring for detection:', detection); - const opacity = getDetectionOpacity(detection); - const age = getDetectionAge(detection); - console.log('MapView: Detection age:', age, 'opacity:', opacity); - - // Calculate ring radius based on RSSI (rough distance estimation) - const getRssiRadius = (rssi) => { - if (rssi > -40) return 100; // <100m - very close - if (rssi > -60) return 500; // ~500m - close - if (rssi > -70) return 1500; // ~1.5km - medium - if (rssi > -80) return 4000; // ~4km - far - if (rssi > -90) return 8000; // ~8km - very far - return 15000; // ~15km - maximum range - }; + {showDroneDetections && (() => { + const filteredDetections = droneDetectionHistory + .filter(detection => { + const hasCoords = detection.geo_lat && detection.geo_lon; + console.log('MapView: Filtering detection:', detection, 'hasCoords:', hasCoords); + return hasCoords; + }); - const radius = getRssiRadius(detection.rssi); - console.log('MapView: Ring radius:', radius, 'for RSSI:', detection.rssi); - - // Color based on threat level and RSSI strength - const getRingColor = (rssi, droneType) => { - // Orlan drones (type 1) always red - if (droneType === 1) return '#dc2626'; // red-600 + // Group detections by detector position to handle multiple drones at same detector + const detectionsByDetector = filteredDetections.reduce((acc, detection) => { + const key = `${detection.geo_lat}_${detection.geo_lon}`; + if (!acc[key]) acc[key] = []; + acc[key].push(detection); + return acc; + }, {}); + + return Object.entries(detectionsByDetector).flatMap(([detectorKey, detections]) => { + return detections.map((detection, droneIndex) => { + console.log('MapView: Rendering ring for detection:', detection, 'droneIndex:', droneIndex, 'totalDrones:', detections.length); + const opacity = getDetectionOpacity(detection); + const age = getDetectionAge(detection); + console.log('MapView: Detection age:', age, 'opacity:', opacity); - // Other drones based on RSSI - if (rssi > -60) return '#dc2626'; // red-600 - close - if (rssi > -70) return '#ea580c'; // orange-600 - medium - return '#16a34a'; // green-600 - far - }; + // Calculate ring radius based on RSSI (rough distance estimation) + const getRssiRadius = (rssi) => { + if (rssi > -40) return 100; // <100m - very close + if (rssi > -60) return 500; // ~500m - close + if (rssi > -70) return 1500; // ~1.5km - medium + if (rssi > -80) return 4000; // ~4km - far + if (rssi > -90) return 8000; // ~8km - very far + return 15000; // ~15km - maximum range + }; - const ringColor = getRingColor(detection.rssi, detection.drone_type); - - return ( - - {/* Detection Ring around Detector (NOT drone position) */} - + const radius = getRssiRadius(detection.rssi); + console.log('MapView: Ring radius:', radius, 'for RSSI:', detection.rssi); + + // Color based on threat level and RSSI strength + const getRingColor = (rssi, droneType) => { + // Orlan drones (type 1) always red + if (droneType === 1) return '#dc2626'; // red-600 - {/* Optional: Small info marker at detector showing detection details */} - {age < 1 && ( // Only show for very recent detections (< 1 minute) - - - - - - )} - - ); - })} + // Other drones based on RSSI + if (rssi > -60) return '#dc2626'; // red-600 - close + if (rssi > -70) return '#ea580c'; // orange-600 - medium + return '#16a34a'; // green-600 - far + }; + + const ringColor = getRingColor(detection.rssi, detection.drone_type); + + // Different visual styles for multiple drones at same detector + const getDashPattern = (droneType, droneIndex, totalDrones) => { + if (droneType === 1) return null; // Orlan always solid + + if (totalDrones === 1) return '5, 5'; // Single drone - normal dashed + + // Multiple drones - different dash patterns + const patterns = [ + '5, 5', // Standard dashed + '10, 3, 3, 3', // Long dash, dot, dot + '15, 5', // Long dashes + '3, 3', // Short dashes + '8, 3, 3, 3, 3, 3' // Complex pattern + ]; + return patterns[droneIndex % patterns.length]; + }; + + // Slight offset for multiple rings to make them more visible + const getPositionOffset = (droneIndex, totalDrones) => { + if (totalDrones === 1) return [0, 0]; + + const offsetDistance = 0.0001; // Very small offset in degrees + const angle = (droneIndex * 360 / totalDrones) * (Math.PI / 180); + return [ + Math.cos(angle) * offsetDistance, + Math.sin(angle) * offsetDistance + ]; + }; + + const totalDrones = detections.length; + const dashPattern = getDashPattern(detection.drone_type, droneIndex, totalDrones); + const [latOffset, lonOffset] = getPositionOffset(droneIndex, totalDrones); + + return ( + + {/* Detection Ring around Detector (NOT drone position) */} + 1 ? 0.02 * opacity : 0.05 * opacity, // Less fill for multiple + weight: detection.drone_type === 1 ? 3 : (totalDrones > 1 ? 3 : 2), // Thicker for multiple or Orlan + opacity: opacity * 0.8, + dashArray: dashPattern + }} + /> + + {/* Drone ID label for multiple drones */} + {totalDrones > 1 && age < 5 && ( // Show labels for recent detections with multiple drones + + ${detection.drone_id || `D${droneIndex + 1}`} + `, + className: 'drone-id-label', + iconSize: [30, 16], + iconAnchor: [15, 8] + })} + opacity={opacity * 0.9} + > + + + + + )} + + {/* Optional: Small info marker at detector showing detection details (for single drone) */} + {totalDrones === 1 && age < 1 && ( // Only show for very recent detections (< 1 minute) and single drone + + + + + + )} + + ); + }); + }); + })()} {/* Map Legend - Fixed positioning and visibility */} @@ -419,6 +502,12 @@ const MapView = () => {
Far Range (<-70dBm) +
+
Multiple Drones:
+
• Different dash patterns
+
• Drone ID labels shown
+
• Slight position offsets
+
Ring size = estimated distance from detector