show cable lenght info

This commit is contained in:
2025-12-13 13:59:07 +05:00
parent e745ee47e2
commit 4b0722787e
2 changed files with 86 additions and 1 deletions

View File

@@ -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
<div className="text-sm dark:bg-gray-800 dark:text-white" style={{ minWidth: '200px' }}>
<div className="font-semibold text-gray-900 dark:text-white">{item.properties.name || 'Cable'}</div>
<div className="text-gray-600 dark:text-gray-400">Type: {cableType}</div>
<div className="text-gray-600 dark:text-gray-400 mt-1">
<span className="font-semibold">Total Length:</span> {formatDistance(totalDistance)}
</div>
{segmentDistances.length > 1 && (
<div className="mt-2 pt-2 border-t border-gray-200 dark:border-gray-700">
<div className="font-semibold text-gray-700 dark:text-gray-300 mb-1">Segment Distances:</div>
{segmentDistances.map((dist, idx) => (
<div key={idx} className="text-xs text-gray-600 dark:text-gray-400 ml-2">
Segment {idx + 1}: {formatDistance(dist)}
</div>
))}
</div>
)}
{startDevice && (
<div className="text-gray-600 dark:text-gray-400 mt-1">
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
<Popup>
<div className="text-sm dark:bg-gray-800 dark:text-white" style={{ minWidth: '200px' }}>
<div className="font-semibold text-gray-900 dark:text-white">{item.properties.name || 'Wireless Mesh'}</div>
<div className="text-gray-600 dark:text-gray-400 mt-1">
<span className="font-semibold">Distance:</span> {formatDistance(distance)}
</div>
{startAp && (
<div className="text-gray-600 dark:text-gray-400 mt-1">
From: {startAp.properties.name || startAp.type}

View File

@@ -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;
}