82 lines
3.1 KiB
Dart
82 lines
3.1 KiB
Dart
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;
|
|
}
|
|
}
|