406 lines
12 KiB
Dart
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
|
|
}
|
|
} |