From 4b0722787e54c9d2ec6af7ce228013bbfa1b470e Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Sat, 13 Dec 2025 13:59:07 +0500 Subject: [PATCH] show cable lenght info --- public/src/components/map/MapItemsLayer.tsx | 67 ++++++++++++++++++++- public/src/index.css | 20 ++++++ 2 files changed, 86 insertions(+), 1 deletion(-) 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
{item.properties.name || 'Cable'}
Type: {cableType}
+
+ Total Length: {formatDistance(totalDistance)} +
+ {segmentDistances.length > 1 && ( +
+
Segment Distances:
+ {segmentDistances.map((dist, idx) => ( +
+ Segment {idx + 1}: {formatDistance(dist)} +
+ ))} +
+ )} {startDevice && (
From: {startDevice.properties.name || startDevice.type} @@ -214,6 +268,14 @@ export function MapItemsLayer({ mapId, refreshTrigger, readOnly = false }: MapIt ([lng, lat]) => [lat, lng] as [number, number] ); + // Calculate distance + const distance = calculateDistance( + positions[0][0], + positions[0][1], + positions[1][0], + positions[1][1] + ); + // Find connected APs const startAp = item.properties.start_ap_id ? items.find(i => i.id === item.properties.start_ap_id) @@ -246,6 +308,9 @@ export function MapItemsLayer({ mapId, refreshTrigger, readOnly = false }: MapIt
{item.properties.name || 'Wireless Mesh'}
+
+ Distance: {formatDistance(distance)} +
{startAp && (
From: {startAp.properties.name || startAp.type} diff --git a/public/src/index.css b/public/src/index.css index cc884ad..22bb816 100644 --- a/public/src/index.css +++ b/public/src/index.css @@ -124,3 +124,23 @@ border-color: #F59E0B; color: #F59E0B; } + +/* Distance labels on map */ +.distance-label { + background-color: rgba(255, 255, 255, 0.95) !important; + border: 1px solid rgba(0, 0, 0, 0.2) !important; + border-radius: 4px !important; + padding: 2px 6px !important; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; +} + +.dark .distance-label { + background-color: rgba(31, 41, 55, 0.95) !important; + border-color: rgba(255, 255, 255, 0.2) !important; + color: white !important; +} + +.distance-label::before { + display: none !important; +}