refactor(tactical-app): modernize state management with GetX controllers, bindings, and clean MVP architecture
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intaleq_maps/intaleq_maps.dart';
|
||||
import '../services/offline_los_engine.dart';
|
||||
|
||||
/// ============================================================================
|
||||
/// [LosController] - وحدة التحكم بتبادل الرؤية والمقطع التضاريسي (LOS)
|
||||
/// ============================================================================
|
||||
/// English:
|
||||
/// GetX Controller managing Line of Sight (LOS) observer & target coordinates,
|
||||
/// elevation sampling, terrain obstruction detection, and cross-section reports.
|
||||
///
|
||||
/// العربية:
|
||||
/// متحكم GetX لإدارة تبادل الرؤية والمراقبة (LOS)، استخراج المقطع التضاريسي،
|
||||
/// كشف نقاط الحجب الجبلي والنقاط الميتة (Dead Ground) بالارتفاعات الحقيقية.
|
||||
/// ============================================================================
|
||||
class LosController extends GetxController {
|
||||
// ── Observables / الحالات التفاعلية ──────────────────────────────────────
|
||||
final Rx<LatLng?> observerPosition = Rx<LatLng?>(null);
|
||||
final Rx<LatLng?> targetPosition = Rx<LatLng?>(null);
|
||||
final RxDouble observerHeightM = 2.0.obs;
|
||||
final RxDouble targetHeightM = 2.0.obs;
|
||||
final RxBool isLoading = false.obs;
|
||||
final Rx<OfflineLosReport?> losReport = Rx<OfflineLosReport?>(null);
|
||||
|
||||
/// Set Observer Position / تعيين موقع الراصد الميداني
|
||||
void setObserver(LatLng pos) {
|
||||
observerPosition.value = pos;
|
||||
computeLos();
|
||||
}
|
||||
|
||||
/// Set Target Position / تعيين موقع الهدف التكتيكي
|
||||
void setTarget(LatLng pos) {
|
||||
targetPosition.value = pos;
|
||||
computeLos();
|
||||
}
|
||||
|
||||
/// Swap Observer & Target / تبديل موقع الراصد والهدف
|
||||
void swapPositions() {
|
||||
final temp = observerPosition.value;
|
||||
observerPosition.value = targetPosition.value;
|
||||
targetPosition.value = temp;
|
||||
computeLos();
|
||||
}
|
||||
|
||||
/// Set Eye and Target Heights / ضبط ارتفاع العين والهدف بالمتر
|
||||
void setHeights({double? obsHeight, double? tgtHeight}) {
|
||||
if (obsHeight != null) observerHeightM.value = obsHeight;
|
||||
if (tgtHeight != null) targetHeightM.value = tgtHeight;
|
||||
computeLos();
|
||||
}
|
||||
|
||||
/// Compute High-Precision LOS Report / احتساب تقرير تبادل الرؤية التضاريسي
|
||||
Future<void> computeLos() async {
|
||||
if (observerPosition.value == null || targetPosition.value == null) {
|
||||
losReport.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
isLoading.value = true;
|
||||
final rep = OfflineLosEngine.calculate(
|
||||
observer: observerPosition.value!,
|
||||
target: targetPosition.value!,
|
||||
observerHeightM: observerHeightM.value,
|
||||
targetHeightM: targetHeightM.value,
|
||||
);
|
||||
losReport.value = rep;
|
||||
} catch (e) {
|
||||
losReport.value = null;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset LOS state / إعادة ضبط خط الرؤية
|
||||
void reset() {
|
||||
observerPosition.value = null;
|
||||
targetPosition.value = null;
|
||||
losReport.value = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user