chore: add build artifacts, map assets, and routing data
This commit is contained in:
@@ -1,21 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import '../services/offline_road_graph_engine.dart';
|
||||
import '../services/offline_routing_engine.dart';
|
||||
import '../services/offline_routing_package_service.dart';
|
||||
import '../services/tactical_api_service.dart';
|
||||
import '../services/turn_by_turn_navigation_engine.dart';
|
||||
import '../services/valhalla_offline_engine.dart';
|
||||
|
||||
/// ============================================================================
|
||||
/// [NavigationController] - وحدة التحكم بالملاحة وتوجيه القوافل التكتيكية
|
||||
/// ============================================================================
|
||||
/// English:
|
||||
/// GetX Controller managing hybrid tactical convoy routing (Online API + Sovereign
|
||||
/// Offline Engine fallback), active turn-by-turn guidance, and navigation metrics.
|
||||
///
|
||||
/// العربية:
|
||||
/// متحكم GetX لإدارة توجيه القوافل والآليات العسكرية (هجين: سيرفر أونلاين + محرك أوفلاين محلي)،
|
||||
/// وتتبع مسار الملاحة خطوة بخطوة وحساب السرعة والوقت المتبقي للهدف.
|
||||
/// ============================================================================
|
||||
class NavigationController extends GetxController {
|
||||
// ── Observables / الحالات التفاعلية ──────────────────────────────────────
|
||||
final Rx<OfflineRoutePlan?> activeRoute = Rx<OfflineRoutePlan?>(null);
|
||||
@@ -23,7 +18,20 @@ class NavigationController extends GetxController {
|
||||
Rx<TacticalVehicleProfile>(TacticalVehicleProfile.convoy);
|
||||
final RxBool isCalculating = false.obs;
|
||||
|
||||
/// Calculate Hybrid Tactical Route / احتساب مسار تكتيكي هجين (سيرفر + محلي)
|
||||
/// هل التوجيه المحلي الحقيقي (شبكة الطرق الكاملة) جاهز على الجهاز؟
|
||||
final RxBool isRealRoadEngineReady = false.obs;
|
||||
|
||||
NavigationController() {
|
||||
_refreshEngineStatus();
|
||||
}
|
||||
|
||||
Future<void> _refreshEngineStatus() async {
|
||||
final pkgInstalled = await OfflineRoutingPackageService.isInstalled();
|
||||
final dbReady = await OfflineRoadGraphEngine.isDatabaseAvailable();
|
||||
isRealRoadEngineReady.value = pkgInstalled || dbReady;
|
||||
}
|
||||
|
||||
/// Calculate Hybrid Tactical Route / احتساب مسار تكتيكي هجين
|
||||
Future<OfflineRoutePlan?> calculateRoute({
|
||||
required LatLng origin,
|
||||
required LatLng destination,
|
||||
@@ -53,13 +61,47 @@ class NavigationController extends GetxController {
|
||||
profile: activeProfile,
|
||||
tacticalWaypoints: const ['موقع الانطلاق', 'الهدف التكتيكي المحدد'],
|
||||
isOffline: false,
|
||||
usesRealRoadNetwork: true,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Online route fallback: $e');
|
||||
}
|
||||
|
||||
// 2. Fallback to 100% Sovereign On-Device Offline Routing Engine
|
||||
// ── Offline chain preparation ──
|
||||
// تأكد من وجود حزمة التوجيه محلياً؛ إن غابت وحُاول الحساب أثناء توفر
|
||||
// الشبكة تُنزَّل مرة واحدة تلقائياً (يفشل بسرعة عند انقطاع الإنترنت).
|
||||
final routingPackageReady = await OfflineRoutingPackageService.ensureInstalled();
|
||||
if (!routingPackageReady) {
|
||||
debugPrint('Navigation: routing package unavailable — offline engines will degrade gracefully');
|
||||
}
|
||||
|
||||
// 2. On-Device SQLite road graph engine (667K real edges, Arabic street names)
|
||||
// الأولوية الأعلى أوفلاين: يحتوي على كامل شبكة طرق الأردن الحقيقية
|
||||
// (1.99 مليون عقدة، 667 ألف حافة) مع أسماء شوارع عربية وانحناءات واقعية.
|
||||
// يعمل بسرعة < 150ms حتى للمسافات الطويلة (عمان ← العقبة).
|
||||
plan ??= await OfflineRoadGraphEngine.calculateRoute(
|
||||
start: origin,
|
||||
destination: destination,
|
||||
profile: activeProfile,
|
||||
);
|
||||
|
||||
// 3. On-Device Valhalla engine (native bridge — may not be available on all platforms)
|
||||
// يحترم الاتجاه الممنوع وقيود الدوران + ارتفاعات SRTM.
|
||||
plan ??= await ValhallaOfflineEngine.calculateOfflineRoute(
|
||||
start: origin,
|
||||
destination: destination,
|
||||
profile: activeProfile,
|
||||
regionDir: await OfflineRoutingPackageService.installDirPath(),
|
||||
);
|
||||
|
||||
if (plan != null) {
|
||||
debugPrint('Navigation: using real road network route '
|
||||
'(${plan.polylinePoints.length} pts, ${plan.totalDistanceKm.toStringAsFixed(1)} km, '
|
||||
'${plan.maneuvers.length} maneuvers, offline=${plan.isOffline})');
|
||||
}
|
||||
|
||||
// 4. Last resort: legacy built-in synthetic graph (36 strategic nodes only)
|
||||
plan ??= OfflineRoutingEngine.calculateOnDeviceRoute(
|
||||
start: origin,
|
||||
destination: destination,
|
||||
|
||||
Reference in New Issue
Block a user