Files

406 lines
12 KiB
Dart

import 'package:latlong2/latlong.dart';
// Modelo 1: Reglas de Notificaciones Push (JSON Parte 1)
class NotificationRule {
final String triggerEvent;
final String condition;
final String title;
final String body;
NotificationRule({
required this.triggerEvent,
required this.condition,
required this.title,
required this.body,
});
}
// Modelo 2: Catálogo de Colonias y Horarios (JSON Parte 2)
class ZoneSchedule {
final String colonia;
final String routeId;
final String horarioEstimado;
ZoneSchedule({
required this.colonia,
required this.routeId,
required this.horarioEstimado,
});
}
// Modelo 3: Geometría Perimetral de la Ruta (JSON Parte 3 de tus Imágenes)
class RouteTelemetry {
final String routeId;
final String name;
final int truckId;
final String status;
final List<LatLng> boundaryPoints;
RouteTelemetry({
required this.routeId,
required this.name,
required this.truckId,
required this.status,
required this.boundaryPoints,
});
}
class MockWasteData {
// Datos reales cargados de tu JSON Parte 1
static final List<NotificationRule> alerts = [
NotificationRule(
triggerEvent: 'ROUTE_START',
condition: 'Cuando positionId cambia de 1 a 2',
title: '¡Ruta Iniciada!',
body:
'El camión recolector ha salido del Relleno Sanitario rumbo a tu sector. Asegúrate de tener listos tus residuos.',
),
NotificationRule(
triggerEvent: 'TRUCK_PROXIMITY',
condition: 'Cuando positionId llega a 4 (punto previo al destino)',
title: 'Camión Cercano 🚚',
body:
'El camión está a menos de 15 minutos de tu domicilio. Es momento de sacar tus bolsas a la acera.',
),
NotificationRule(
triggerEvent: 'ROUTE_COMPLETED',
condition: 'Cuando positionId llega a 8 (retorno al basurero)',
title: 'Servicio Finalizado',
body:
'El camión de tu sector ha concluido su jornada de recolección diaria.',
),
];
// Datos reales cargados de tu JSON Parte 2 (Expandido para dar soporte a más rutas)
static final List<ZoneSchedule> schedules = [
ZoneSchedule(
colonia: 'Zona Centro',
routeId: 'RUTA-01',
horarioEstimado: 'Matutino (06:30 - 07:15)'),
ZoneSchedule(
colonia: 'Las Arboledas',
routeId: 'RUTA-01',
horarioEstimado: 'Matutino (07:00 - 07:30)'),
ZoneSchedule(
colonia: 'San Juanico',
routeId: 'RUTA-03',
horarioEstimado: 'Matutino (06:45 - 07:15)'),
ZoneSchedule(
colonia: 'Los Olivos',
routeId: 'RUTA-04',
horarioEstimado: 'Matutino (07:00 - 07:40)'),
ZoneSchedule(
colonia: 'Rancho Seco',
routeId: 'RUTA-05',
horarioEstimado: 'Vespertino (14:15 - 15:00)'),
ZoneSchedule(
colonia: 'Las Insurgentes',
routeId: 'RUTA-12',
horarioEstimado: 'Matutino (06:35 - 07:10)'),
ZoneSchedule(
colonia: 'Trojes',
routeId: 'RUTA-13',
horarioEstimado: 'Matutino (06:40 - 07:10)'),
ZoneSchedule(
colonia: 'Tecnológico',
routeId: 'RUTA-02',
horarioEstimado: 'Matutino (07:15 - 08:00)'),
ZoneSchedule(
colonia: 'Rumbos de Roque',
routeId: 'RUTA-06',
horarioEstimado: 'Matutino (08:30 - 09:15)'),
ZoneSchedule(
colonia: 'Ciudad Industrial',
routeId: 'RUTA-07',
horarioEstimado: 'Vespertino (15:00 - 16:00)'),
ZoneSchedule(
colonia: 'Universidad Latina',
routeId: 'RUTA-08',
horarioEstimado: 'Matutino (07:45 - 08:30)'),
ZoneSchedule(
colonia: 'Hospital General',
routeId: 'RUTA-09',
horarioEstimado: 'Vespertino (13:30 - 14:15)'),
ZoneSchedule(
colonia: 'Eje Juan Pablo II',
routeId: 'RUTA-10',
horarioEstimado: 'Nocturno (19:00 - 20:00)'),
ZoneSchedule(
colonia: 'Torres Landa',
routeId: 'RUTA-11',
horarioEstimado: 'Matutino (06:50 - 07:30)'),
ZoneSchedule(
colonia: 'La Toscana',
routeId: 'RUTA-14',
horarioEstimado: 'Nocturno (20:15 - 21:00)'),
ZoneSchedule(
colonia: 'San José de Celaya',
routeId: 'RUTA-15',
horarioEstimado: 'Vespertino (16:30 - 17:15)'),
];
// Base de datos de Geometría extraída de tus capturas (Mapeo RUTA-01 a RUTA-15)
static final Map<String, RouteTelemetry> boundaries = {
'RUTA-01': RouteTelemetry(
routeId: 'RUTA-01',
name: 'Zona Centro - Las Arboledas',
truckId: 101,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5185, -100.8450),
LatLng(20.5215, -100.8142),
LatLng(20.5212, -100.8175),
LatLng(20.5210, -100.8210),
LatLng(20.5235, -100.8212),
LatLng(20.5260, -100.8215),
LatLng(20.5111, -100.9037)
],
),
'RUTA-02': RouteTelemetry(
routeId: 'RUTA-02',
name: 'Sector Norte - Av. Tecnológico',
truckId: 102,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5280, -100.8135),
LatLng(20.5410, -100.8130),
LatLng(20.5445, -100.8132),
LatLng(20.5480, -100.8135),
LatLng(20.5515, -100.8160),
LatLng(20.5540, -100.8110),
LatLng(20.5111, -100.9037)
],
),
'RUTA-03': RouteTelemetry(
routeId: 'RUTA-03',
name: 'Sector Poniente - San Juanico',
truckId: 103,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5185, -100.8510),
LatLng(20.5290, -100.8320),
LatLng(20.5315, -100.8355),
LatLng(20.5340, -100.8390),
LatLng(20.5362, -100.8425),
LatLng(20.5330, -100.8430),
LatLng(20.5111, -100.9037)
],
),
'RUTA-04': RouteTelemetry(
routeId: 'RUTA-04',
name: 'Oriente - Los Olivos',
truckId: 104,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5260, -100.8010),
LatLng(20.5295, -100.7890),
LatLng(20.5320, -100.7850),
LatLng(20.5350, -100.7790),
LatLng(20.5310, -100.7760),
LatLng(20.5270, -100.7820),
LatLng(20.5111, -100.9037)
],
),
'RUTA-05': RouteTelemetry(
routeId: 'RUTA-05',
name: 'Sector Sur - Rancho Seco',
truckId: 105,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5050, -100.8620),
LatLng(20.5020, -100.8350),
LatLng(20.4995, -100.8210),
LatLng(20.4970, -100.8150),
LatLng(20.5010, -100.8120),
LatLng(20.5060, -100.8160),
LatLng(20.5111, -100.9037)
],
),
'RUTA-06': RouteTelemetry(
routeId: 'RUTA-06',
name: 'Norte Extremo - Rumbos de Roque',
truckId: 106,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5380, -100.8380),
LatLng(20.5610, -100.8370),
LatLng(20.5750, -100.8360),
LatLng(20.5820, -100.8350),
LatLng(20.5780, -100.8310),
LatLng(20.5650, -100.8320),
LatLng(20.5111, -100.9037)
],
),
'RUTA-07': RouteTelemetry(
routeId: 'RUTA-07',
name: 'Nororiente - Ciudad Industrial',
truckId: 107,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5350, -100.8050),
LatLng(20.5450, -100.7950),
LatLng(20.5480, -100.7850),
LatLng(20.5510, -100.7750),
LatLng(20.5460, -100.7720),
LatLng(20.5390, -100.7820),
LatLng(20.5111, -100.9037)
],
),
'RUTA-08': RouteTelemetry(
routeId: 'RUTA-08',
name: 'Suroriente - Universidad Latina',
truckId: 108,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5180, -100.8310),
LatLng(20.5245, -100.7980),
LatLng(20.5210, -100.7995),
LatLng(20.5175, -100.8010),
LatLng(20.5140, -100.8030),
LatLng(20.5110, -100.8055),
LatLng(20.5111, -100.9037)
],
),
'RUTA-09': RouteTelemetry(
routeId: 'RUTA-09',
name: 'Poniente - Hospital General',
truckId: 109,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5210, -100.8650),
LatLng(20.5260, -100.8520),
LatLng(20.5275, -100.8490),
LatLng(20.5285, -100.8460),
LatLng(20.5250, -100.8470),
LatLng(20.5220, -100.8550),
LatLng(20.5111, -100.9037)
],
),
'RUTA-10': RouteTelemetry(
routeId: 'RUTA-10',
name: 'Eje Juan Pablo II - Sede UG Sur',
truckId: 110,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5015, -100.8520),
LatLng(20.4990, -100.8390),
LatLng(20.4950, -100.8320),
LatLng(20.4920, -100.8280),
LatLng(20.4945, -100.8240),
LatLng(20.4980, -100.8300),
LatLng(20.5111, -100.9037)
],
),
'RUTA-11': RouteTelemetry(
routeId: 'RUTA-11',
name: 'Zona de Oro - Torres Landa',
truckId: 111,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5240, -100.8350),
LatLng(20.5280, -100.8250),
LatLng(20.5295, -100.8210),
LatLng(20.5310, -100.8170),
LatLng(20.5290, -100.8140),
LatLng(20.5260, -100.8200),
LatLng(20.5111, -100.9037)
],
),
'RUTA-12': RouteTelemetry(
routeId: 'RUTA-12',
name: 'Nororiente - Las Insurgentes',
truckId: 112,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5280, -100.8080),
LatLng(20.5320, -100.7980),
LatLng(20.5340, -100.7940),
LatLng(20.5360, -100.7900),
LatLng(20.5310, -100.7920),
LatLng(20.5270, -100.8020),
LatLng(20.5111, -100.9037)
],
),
'RUTA-13': RouteTelemetry(
routeId: 'RUTA-13',
name: 'Sector Norte - Trojes e Irrigación',
truckId: 113,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5360, -100.8190),
LatLng(20.5420, -100.8080),
LatLng(20.5440, -100.8040),
LatLng(20.5460, -100.8000),
LatLng(20.5410, -100.8020),
LatLng(20.5370, -100.8120),
LatLng(20.5111, -100.9037)
],
),
'RUTA-14': RouteTelemetry(
routeId: 'RUTA-14',
name: 'Sur Poniente - La Toscana',
truckId: 114,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5150, -100.8580),
LatLng(20.5140, -100.8390),
LatLng(20.5125, -100.8310),
LatLng(20.5110, -100.8250),
LatLng(20.5135, -100.8280),
LatLng(20.5160, -100.8420),
LatLng(20.5111, -100.9037)
],
),
'RUTA-15': RouteTelemetry(
routeId: 'RUTA-15',
name: 'Norponiente - Camino a San José de Celaya',
truckId: 115,
status: 'EN_RUTA',
boundaryPoints: [
LatLng(20.5111, -100.9037),
LatLng(20.5320, -100.8590),
LatLng(20.5390, -100.8480),
LatLng(20.5420, -100.8440),
LatLng(20.5450, -100.8410),
LatLng(20.5410, -100.8430),
LatLng(20.5360, -100.8520),
LatLng(20.5111, -100.9037),
],
),
}; // 🔒 AQUÍ SE CIERRA EL MAPA DE BOUNDARIES
} // 🔒 AQUÍ SE CIERRA LA CLASE MOCKWASTEDATA
// 📍 LA CLASE DE OPTIMIZACIÓN DE COSTOS DEBE IR TOTALMENTE AQUÍ AFUERA:
class SpatialAnalysisService {
// Simula la fórmula matemática de Haversine para calcular distancias en el Backend
// Esto evita hacer llamadas de pago a la Distance Matrix API de Google Maps
static double calcularDistanciaEntrePuntos(LatLng p1, LatLng p2) {
// El Backend resuelve esto de forma interna con PostGIS o librerías del lenguaje
return const Distance().as(LengthUnit.Meter, p1, p2);
}
// Simula la consulta única a OpenStreetMap Nominatim en el registro
static Future<LatLng> geocodificarDomicilioUnicaVez(String direccion, String colonia) async {
final schedule = MockWasteData.schedules.firstWhere(
(e) => e.colonia.toLowerCase() == colonia.toLowerCase(),
orElse: () => MockWasteData.schedules.first,
);
final telemetry = MockWasteData.boundaries[schedule.routeId]!;
return telemetry.boundaryPoints.first; // Retorna la coordenada almacenada
}
}