feat: integrate persona D (recycling guide) and routes modules
This commit is contained in:
111
lib/features/routes/data/repositories/routes_repository.dart
Normal file
111
lib/features/routes/data/repositories/routes_repository.dart
Normal file
@@ -0,0 +1,111 @@
|
||||
// lib/features/routes/data/repositories/routes_repository.dart
|
||||
|
||||
import '../datasources/routes_local_datasource.dart';
|
||||
import '../../domain/entities/route_entities.dart';
|
||||
import '../../domain/entities/haversine.dart';
|
||||
|
||||
class RoutesRepository {
|
||||
final RoutesLocalDatasource _datasource;
|
||||
|
||||
RoutesRepository({RoutesLocalDatasource? datasource})
|
||||
: _datasource = datasource ?? RoutesLocalDatasource();
|
||||
|
||||
/// Obtiene todas las rutas disponibles
|
||||
Future<List<TruckRoute>> obtenerRutas() => _datasource.cargarRutas();
|
||||
|
||||
/// Obtiene una ruta por su ID
|
||||
Future<TruckRoute?> obtenerRutaPorId(String routeId) async {
|
||||
final rutas = await obtenerRutas();
|
||||
try {
|
||||
return rutas.firstWhere((r) => r.routeId == routeId);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Asigna la ruta más cercana a un domicilio usando Haversine.
|
||||
/// Cero Google Maps — motor espacial propio.
|
||||
Future<RouteAssignmentResult> asignarRuta(
|
||||
double userLat,
|
||||
double userLng,
|
||||
) async {
|
||||
final centroides = await _datasource.generarCentroides();
|
||||
return Haversine.findNearestRoute(userLat, userLng, centroides);
|
||||
}
|
||||
|
||||
/// Calcula ETA en minutos desde la posición actual del camión
|
||||
/// hasta el punto más cercano al domicilio del usuario.
|
||||
Future<ETAResult> calcularETA(
|
||||
String routeId,
|
||||
double userLat,
|
||||
double userLng,
|
||||
) async {
|
||||
final ruta = await obtenerRutaPorId(routeId);
|
||||
if (ruta == null) throw Exception('Ruta $routeId no encontrada');
|
||||
|
||||
// Encontrar posición más cercana al usuario en la ruta
|
||||
double minDist = double.infinity;
|
||||
int nearestIndex = 0;
|
||||
|
||||
for (int i = 0; i < ruta.positions.length - 1; i++) {
|
||||
final pos = ruta.positions[i];
|
||||
final d = Haversine.distanceKm(userLat, userLng, pos.lat, pos.lng);
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
nearestIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
final posicionCercana = ruta.positions[nearestIndex];
|
||||
final ahora = DateTime.now();
|
||||
|
||||
// Simular cuándo llegará el camión a esa posición
|
||||
final horaLlegada = posicionCercana.timestamp;
|
||||
final etaMinutos = horaLlegada.difference(ahora).inMinutes;
|
||||
|
||||
return ETAResult(
|
||||
routeId: routeId,
|
||||
routeName: ruta.name,
|
||||
etaMinutos: etaMinutos.clamp(0, 999),
|
||||
distanciaKm: minDist,
|
||||
posicionActual: posicionCercana,
|
||||
ventanaInicio: _formatHora(horaLlegada),
|
||||
ventanaFin: _formatHora(horaLlegada.add(const Duration(minutes: 15))),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatHora(DateTime dt) {
|
||||
final hora = dt.hour > 12 ? dt.hour - 12 : dt.hour;
|
||||
final minutos = dt.minute.toString().padLeft(2, '0');
|
||||
final periodo = dt.hour >= 12 ? 'pm' : 'am';
|
||||
return '$hora:$minutos $periodo';
|
||||
}
|
||||
}
|
||||
|
||||
class ETAResult {
|
||||
final String routeId;
|
||||
final String routeName;
|
||||
final int etaMinutos;
|
||||
final double distanciaKm;
|
||||
final RoutePosition posicionActual;
|
||||
final String ventanaInicio;
|
||||
final String ventanaFin;
|
||||
|
||||
const ETAResult({
|
||||
required this.routeId,
|
||||
required this.routeName,
|
||||
required this.etaMinutos,
|
||||
required this.distanciaKm,
|
||||
required this.posicionActual,
|
||||
required this.ventanaInicio,
|
||||
required this.ventanaFin,
|
||||
});
|
||||
|
||||
String get ventana => '$ventanaInicio – $ventanaFin';
|
||||
|
||||
String get mensaje {
|
||||
if (etaMinutos <= 0) return 'El camión está pasando ahora. ¡Saca tu basura!';
|
||||
if (etaMinutos <= 10) return 'El camión llega en ~$etaMinutos min. ¡Saca tu basura!';
|
||||
return 'El camión llega entre $ventana.';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user