diff --git a/public/src/components/map/MapItemsLayer.tsx b/public/src/components/map/MapItemsLayer.tsx index fdb1faf..c966d46 100644 --- a/public/src/components/map/MapItemsLayer.tsx +++ b/public/src/components/map/MapItemsLayer.tsx @@ -1,12 +1,39 @@ import { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; -import { Polyline, Marker, Popup, Circle, useMapEvents } from 'react-leaflet'; +import { Polyline, Marker, Popup, Circle, Tooltip, useMapEvents } from 'react-leaflet'; import L from 'leaflet'; import { mapItemService } from '../../services/mapItemService'; import { CABLE_COLORS, type MapItem, type CableType } from '../../types/mapItem'; import { ItemContextMenu } from './ItemContextMenu'; import { useDrawingStore } from '../../stores/drawingStore'; +// Calculate distance between two lat/lng points in meters using Haversine formula +function calculateDistance(lat1: number, lng1: number, lat2: number, lng2: number): number { + const R = 6371e3; // Earth's radius in meters + const φ1 = (lat1 * Math.PI) / 180; + const φ2 = (lat2 * Math.PI) / 180; + const Δφ = ((lat2 - lat1) * Math.PI) / 180; + const Δλ = ((lng2 - lng1) * Math.PI) / 180; + + const a = + Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2); + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return R * c; // Distance in meters +} + +// Format distance for display +function formatDistance(meters: number): string { + if (meters < 1) { + return `${Math.round(meters * 100)} cm`; + } else if (meters < 1000) { + return `${Math.round(meters * 10) / 10} m`; + } else { + return `${Math.round(meters / 100) / 10} km`; + } +} + interface MapItemsLayerProps { mapId: string; refreshTrigger: number; @@ -128,6 +155,20 @@ export function MapItemsLayer({ mapId, refreshTrigger, readOnly = false }: MapIt const cableType = item.properties.cable_type as CableType; const color = CABLE_COLORS[cableType] || '#6B7280'; + // Calculate distances + const segmentDistances: number[] = []; + let totalDistance = 0; + for (let i = 0; i < positions.length - 1; i++) { + const dist = calculateDistance( + positions[i][0], + positions[i][1], + positions[i + 1][0], + positions[i + 1][1] + ); + segmentDistances.push(dist); + totalDistance += dist; + } + // Find connected devices const startDevice = item.properties.start_device_id ? items.find(i => i.id === item.properties.start_device_id) @@ -160,6 +201,19 @@ export function MapItemsLayer({ mapId, refreshTrigger, readOnly = false }: MapIt