# Mapa de Tracking en Tiempo Real - Documentacion Tecnica **Feature:** tracking **Sprint:** S7 **Estado:** Funcional (mapas pendientes) **Fecha:** 2026-01-28 --- ## 1. Vision General El sistema de tracking en tiempo real permite: - Visualizar posicion actual de unidades en mapa - Ver historial de ruta recorrida - Monitorear eventos y alertas - Calcular y mostrar ETA dinamico - Recibir actualizaciones via WebSocket --- ## 2. Arquitectura de Componentes ``` ViajeTrackingView ├── MapSection (mapa con ruta) │ ├── RoutePolyline (ruta planificada) │ ├── HistoryPolyline (ruta recorrida) │ ├── CurrentPositionMarker │ ├── OriginMarker │ └── DestinationMarker ├── ETAProgressBar │ ├── MilestoneIndicators │ └── ProgressLine └── EventTimeline ├── EventCards (17 tipos) └── TimelineConnector ``` --- ## 3. Tipos Principales ### 3.1 ENUMs ```typescript enum TipoEventoTracking { // GPS POSICION = 'POSICION', GPS_POSICION = 'GPS_POSICION', // Geocercas GEOCERCA_ENTRADA = 'GEOCERCA_ENTRADA', GEOCERCA_SALIDA = 'GEOCERCA_SALIDA', // Flujo de viaje INICIO_VIAJE = 'INICIO_VIAJE', ARRIBO_ORIGEN = 'ARRIBO_ORIGEN', INICIO_CARGA = 'INICIO_CARGA', FIN_CARGA = 'FIN_CARGA', SALIDA = 'SALIDA', ARRIBO_DESTINO = 'ARRIBO_DESTINO', INICIO_DESCARGA = 'INICIO_DESCARGA', FIN_DESCARGA = 'FIN_DESCARGA', ENTREGA_POD = 'ENTREGA_POD', FIN_VIAJE = 'FIN_VIAJE', // Incidentes PARADA = 'PARADA', DESVIO = 'DESVIO', INCIDENTE = 'INCIDENTE' } enum FuenteEvento { GPS = 'GPS', APP_OPERADOR = 'APP_OPERADOR', SISTEMA = 'SISTEMA', MANUAL = 'MANUAL', GEOCERCA = 'GEOCERCA' } ``` ### 3.2 Interfaces ```typescript interface PosicionActual { lat: number; lng: number; velocidad: number; rumbo: number; timestamp: string; precision: number; } interface EventoTracking { id: string; viajeId: string; tipo: TipoEventoTracking; fuente: FuenteEvento; timestampEvento: string; ubicacion: { lat: number; lng: number } | null; descripcion: string; metadata: Record; } interface TrackingData { viajeId: string; posicionActual: PosicionActual; rutaPlanificada: [number, number][]; rutaRecorrida: [number, number][]; eventos: EventoTracking[]; eta: { llegadaEstimada: string; distanciaRestante: number; tiempoRestante: string; }; } ``` --- ## 4. WebSocket Integration ### 4.1 Hook useTrackingWebSocket ```typescript // hooks/useTrackingWebSocket.ts export function useTrackingWebSocket(viajeId: string) { const [isConnected, setIsConnected] = useState(false); const [lastPosition, setLastPosition] = useState(null); const [eventos, setEventos] = useState([]); useEffect(() => { const ws = new WebSocket(`${WS_URL}/tracking/${viajeId}`); ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'position') { setLastPosition(data.payload); } else if (data.type === 'event') { setEventos(prev => [...prev, data.payload]); } }; // Auto-reconnect logic included }, [viajeId]); return { isConnected, lastPosition, eventos }; } ``` ### 4.2 Mensajes WebSocket ```typescript // Posicion { type: 'position', payload: { lat: 19.4326, lng: -99.1332, velocidad: 85, rumbo: 45, timestamp: '2026-01-28T10:30:00Z' } } // Evento { type: 'event', payload: { id: 'evt-123', tipo: 'ARRIBO_DESTINO', fuente: 'GPS', timestamp: '2026-01-28T10:30:00Z', descripcion: 'Unidad arribo a destino' } } ``` --- ## 5. ETAProgressBar Component ### 5.1 Milestones ```typescript const milestones = [ { id: 'origin', label: 'Origen', icon: 'MapPin' }, { id: 'loaded', label: 'Cargado', icon: 'Package' }, { id: 'transit', label: 'En Transito', icon: 'Truck' }, { id: 'destination', label: 'Destino', icon: 'Flag' }, { id: 'delivered', label: 'Entregado', icon: 'CheckCircle' } ]; ``` ### 5.2 Progress Calculation ```typescript function calculateProgress(eventos: EventoTracking[]): number { const weights = { INICIO_VIAJE: 0, ARRIBO_ORIGEN: 10, FIN_CARGA: 25, SALIDA: 30, EN_TRANSITO: 50, // Interpolado por distancia ARRIBO_DESTINO: 80, FIN_DESCARGA: 90, ENTREGA_POD: 100 }; const lastEvent = eventos[eventos.length - 1]; return weights[lastEvent?.tipo] || 0; } ``` --- ## 6. EventTimeline Component ### 6.1 Iconos por Tipo ```typescript const eventIcons: Record = { POSICION: MapPin, GPS_POSICION: Satellite, GEOCERCA_ENTRADA: LogIn, GEOCERCA_SALIDA: LogOut, INICIO_VIAJE: PlayCircle, ARRIBO_ORIGEN: MapPin, INICIO_CARGA: Package, FIN_CARGA: PackageCheck, SALIDA: Truck, ARRIBO_DESTINO: Flag, INICIO_DESCARGA: PackageOpen, FIN_DESCARGA: PackageCheck, ENTREGA_POD: FileCheck, FIN_VIAJE: CheckCircle, PARADA: PauseCircle, DESVIO: AlertTriangle, INCIDENTE: AlertOctagon }; ``` ### 6.2 Colores por Tipo ```typescript const eventColors: Record = { INICIO_VIAJE: 'bg-green-500', FIN_VIAJE: 'bg-green-600', INCIDENTE: 'bg-red-500', PARADA: 'bg-yellow-500', DESVIO: 'bg-orange-500', // ... otros default: 'bg-blue-500' }; ``` --- ## 7. API Endpoints | Endpoint | Metodo | Descripcion | |----------|--------|-------------| | `/api/v1/tracking/viajes/:id` | GET | Datos de tracking de viaje | | `/api/v1/tracking/viajes/:id/eventos` | GET | Historial de eventos | | `/api/v1/tracking/viajes/:id/ruta` | GET | Ruta planificada y recorrida | | `/api/v1/gps/posiciones/ultima/:dispositivoId` | GET | Ultima posicion | | `WS /tracking/:viajeId` | WS | Streaming de posiciones | --- ## 8. Integracion con Mapas (Pendiente) ### 8.1 Estado Actual - Mapa placeholder con CSS gradient - Polylines simplificados con SVG - Marcadores posicionados con % relativo ### 8.2 Implementacion con Leaflet ```typescript import { MapContainer, Polyline, Marker, Popup } from 'react-leaflet'; const TrackingMap = ({ data }: { data: TrackingData }) => ( {/* Ruta planificada */} {/* Ruta recorrida */} {/* Posicion actual */} Velocidad: {data.posicionActual.velocidad} km/h ); ``` --- ## 9. Performance Considerations 1. **Throttle WebSocket updates**: Maximo 1 update por segundo en UI 2. **Virtualized EventTimeline**: Para viajes con 100+ eventos 3. **Route simplification**: Usar Douglas-Peucker para rutas largas 4. **Map tile caching**: Service worker para tiles frecuentes --- *Sprint S7 - TASK-007 | Sistema SIMCO v4.0.0*