Geolocalización avanzada
Tracelet es más que un simple contenedor de ubicación en segundo plano. Contiene un conjunto de algoritmos avanzados diseñados específicamente para abordar los problemas más difíciles de la geolocalización móvil: fluctuaciones del GPS, apagones de túneles y consumo de batería a altas velocidades.
1. Filtro Kalman (suavizado de trayectoria)
Los datos GPS sin procesar son inherentemente ruidosos. Si un usuario camina por una carretera recta, las coordenadas sin procesar saltarán de izquierda a derecha de forma aleatoria, creando una línea “irregular”. Si calcula la distancia de esta línea irregular, inflará artificialmente la distancia total del usuario hasta en un 20%.
como funciona
Al configurar useKalmanFilter: true, Tracelet aplica un algoritmo matemático avanzado desarrollado originalmente para la navegación de naves espaciales. Fusiona la posición GPS actual con la velocidad del dispositivo (velocidad y rumbo) para predecir dónde se encuentra realmente el usuario, suavizando efectivamente el ruido y generando una línea curva perfecta.
final config = Config.highAccuracy(
geo: tl.GeoConfig(
filter: tl.LocationFilter(
useKalmanFilter: true, // Enable trajectory smoothing
trackingAccuracyThreshold: 50,
),
),
);2. Estimación (túneles y GPS denegados)
Cuando un usuario entra en un túnel largo o en un aparcamiento subterráneo, pierde la conexión a los satélites GPS. Los rastreadores tradicionales simplemente dibujarán una línea recta desde la entrada del túnel hasta la salida, omitiendo la ruta subterránea real.
como funciona
Al configurar enableDeadReckoning: true, Tracelet detecta cuando se pierde el GPS y cambia instantáneamente sin problemas a la IMU (Unidad de medición inercial) interna del dispositivo. Utiliza el acelerómetro y el giroscopio para continuar calculando la trayectoria del usuario en función de su última velocidad conocida, simulando actualizaciones del GPS incluso cuando está completamente bajo tierra.
final config = Config.balanced(
geo: tl.GeoConfig(
enableDeadReckoning: true,
deadReckoningActivationDelay: 10, // Wait 10 seconds of no GPS before activating
deadReckoningMaxDuration: 300, // Stop dead reckoning after 5 minutes to prevent drift
),
);3. Elasticidad (optimización de alta velocidad)
Si su distanceFilter está configurado en 20 metros, Tracelet se activa cada 20 metros. Si el usuario circula a 120 km/h en una autopista recta, recorre 20 metros en menos de un segundo. Esto hace que la base de datos se inunde con cientos de puntos inútiles en una línea perfectamente recta, agotando la batería.
como funciona
El Motor de Elasticidad de Tracelet detecta altas velocidades y dinámicamente estira su filtro de distancia. Un filtro de 20 m podría extenderse automáticamente a 200 m en la autopista y reducirse a 20 m cuando el usuario toma una rampa de salida hacia una ciudad.
final config = Config.balanced(
geo: tl.GeoConfig(
disableElasticity: false, // Ensure elasticity is on
elasticityMultiplier: 2.0, // Make the dynamic stretching 2x more aggressive
),
);4. Modo adaptativo (conservación de la batería)
Si la batería del teléfono de un empleado se está agotando, su prioridad no debería ser el seguimiento de alta frecuencia de 5 metros. Debería garantizarse que el teléfono sobreviva hasta el final del turno.
como funciona
Al configurar enableAdaptiveMode: true, Tracelet monitorea constantemente las API de la batería del sistema operativo. A medida que la batería cae por debajo de los umbrales críticos (por ejemplo, 20%, 10%), Tracelet degrada automáticamente desiredAccuracy de GPS a Wi-Fi/Celular y expande distanceFilter, conservando suficiente energía para mantener vivo el teléfono.
final config = Config.balanced(
geo: tl.GeoConfig(
enableAdaptiveMode: true,
),
);5. Actualizaciones escasas (solo torres de telefonía móvil)
A veces no necesitas precisión en la navegación paso a paso; sólo necesita saber aproximadamente en qué ciudad o vecindario se encuentra el usuario (por ejemplo, una aplicación de red social o una aplicación meteorológica).
como funciona
Al habilitar enableSparseUpdates, Tracelet evita por completo el chip GPS que consume mucha energía. Utiliza exclusivamente transferencias de torres de telefonía móvil y triangulación de Wi-Fi para actualizar la ubicación. El consumo de batería cae casi a cero.
final config = Config.lowPower(
geo: tl.GeoConfig(
enableSparseUpdates: true,
sparseDistanceThreshold: 500.0, // Only trigger if they move 500m
sparseMaxIdleSeconds: 3600, // Or trigger once an hour even if they haven't moved
),
);6. Opciones de proveedor en vivo (anulaciones de tiempo de ejecución)
A veces, su aplicación sabe algo que el SDK no puede: un conductor de reparto acaba de tomar un descanso de 30 minutos, un pasajero está esperando dentro de un lugar o su propia heurística estacionaria se activa. Quieres desconectar el GPS ahora mismo y recuperar la precisión total en el momento en que las cosas cambien.
Hasta ahora el único mando era setConfig(). Pero desiredAccuracy y distanceFilter son claves relevantes para el seguimiento, por lo que cambiarlas mediante config permite los nuevos valores y realiza un reinicio limpio y completo: correcto para la configuración permanente, pero crea una brecha de seguimiento evitable y reconstruye el estado del procesador solo para aplicar una política de energía temporal. Peor aún, debido a que el cambio persiste, una aplicación desactivada y reiniciada durante la fase de “bajo consumo” se activaría permanentemente con un seguimiento con una precisión degradada.
como funciona
Tracelet.updateLocationProviderOptions() actualiza el proveedor de ubicación del sistema operativo en ejecución: sin stop(), sin start(), sin espacios en el flujo de corrección:
- iOS asigna los nuevos valores directamente al
CLLocationManageractivo (desiredAccuracy/distanceFilterson mutables en un administrador activo). - Android vuelve a suscribir la devolución de llamada del proveedor fusionado existente con un nuevo
LocationRequest. Volver a registrar la misma devolución de llamada reemplaza la solicitud vigente, por lo que la suscripción nunca se cancela. - Web no tiene controles de proveedores en vivo y siempre devuelve
false.
La anulación es deliberadamente efímera y exclusiva del proveedor:
- Los
ConfigyTracelet.activeConfigpersistentes nunca se tocan; no se escribe nada en el almacenamiento, por lo que un reinicio del proceso siempre vuelve a su configuración real. - El filtro de puntos aceptados de Rust y el estado del procesador no cambian: la continuidad de la pista, el odómetro y los puntos entregados que se aceptan siguen funcionando exactamente como están configurados.
- Llamar a
stop()borra la anulación automáticamente.
// Device confirmed stationary — drop Core Location to ~100m accuracy
// and only deliver a fix every 25 meters:
await Tracelet.updateLocationProviderOptions(
desiredAccuracy: DesiredAccuracy.medium,
distanceFilter: 25,
);
// Movement detected — restore the configured provider options.
// No arguments = clear the override:
await Tracelet.updateLocationProviderOptions();Valor de retorno y validación
La llamada devuelve true cuando se aplicó la actualización en vivo y false cuando no pudo ser así; nunca reinicia la canalización como alternativa:
| Situación | Resultado |
|---|---|
| Seguimiento continuo activo (iOS / Android) | true — opciones aplicadas en vivo |
El seguimiento no se inició o se llamó a stop() | false |
| Modo de seguimiento periódico activo | false — las correcciones periódicas gestionan su propia adquisición |
| Web | false: no hay actualizaciones de proveedores en vivo |
distanceFilter debe ser finito y no negativo (de lo contrario, se lanza RangeError). Un valor de 0 solicita cada corrección que produce el proveedor (kCLDistanceFilterNone en iOS).
Anulación del tiempo de ejecución versus modo adaptativo — enableAdaptiveMode (sección 4) es la versión automática de esto: el SDK vigila la batería y degrada por usted. Utilice updateLocationProviderOptions() cuando la política sea suya (detección estacionaria, pausas de turno, permanencia de geovalla, umbrales de batería personalizados) y necesite que se aplique instantáneamente sin persistir nada ni interrumpir el seguimiento.