Update: 2026-07-04 04:05:08
This commit is contained in:
@@ -61,8 +61,13 @@ class HomeCaptainController extends GetxController {
|
||||
double widthMapTypeAndTraffic = 50;
|
||||
// === متغيرات الهيت ماب الجديدة ===
|
||||
bool isHeatmapVisible = false;
|
||||
Set<Polygon> heatmapPolygons =
|
||||
{}; // سنستخدم Polygon لرسم المربعات على جوجل مابس
|
||||
Set<Polygon> heatmapPolygons = {};
|
||||
|
||||
// === متغيرات التنبؤ الذكي بالطلب ===
|
||||
bool isPredictiveVisible = false;
|
||||
Set<Polygon> predictivePolygons = {};
|
||||
List<Map<String, dynamic>> predictiveZones = [];
|
||||
Timer? _predictiveTimer;
|
||||
|
||||
// Inject the LocationController class
|
||||
// final locationController = Get.put(LocationController());
|
||||
@@ -198,6 +203,97 @@ class HomeCaptainController extends GetxController {
|
||||
});
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════════════
|
||||
// 🔮 التنبؤ الذكي بالطلب
|
||||
// ════════════════════════════════════════════════════════
|
||||
|
||||
/// تبديل عرض/إخفاء طبقة التنبؤ الذكي
|
||||
void togglePredictiveDemand() {
|
||||
isPredictiveVisible = !isPredictiveVisible;
|
||||
if (isPredictiveVisible) {
|
||||
_startPredictiveCycle();
|
||||
} else {
|
||||
_predictiveTimer?.cancel();
|
||||
predictivePolygons.clear();
|
||||
predictiveZones.clear();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void _startPredictiveCycle() {
|
||||
_predictiveTimer?.cancel();
|
||||
fetchAndDrawPredictiveDemand();
|
||||
// تحديث كل 30 دقيقة (يتوافق مع دورة الـ cron)
|
||||
_predictiveTimer = Timer.periodic(const Duration(minutes: 30), (_) {
|
||||
if (isPredictiveVisible) fetchAndDrawPredictiveDemand();
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> fetchAndDrawPredictiveDemand() async {
|
||||
print("🔮 [Predictive] Fetching demand zones...");
|
||||
try {
|
||||
final myLat = locationController.myLocation.latitude;
|
||||
final myLng = locationController.myLocation.longitude;
|
||||
|
||||
final response = await http.get(
|
||||
Uri.parse(
|
||||
"${AppLink.getPredictiveDemand}?lat=$myLat&lng=$myLng&radius=10"
|
||||
"&t=${DateTime.now().millisecondsSinceEpoch}",
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final body = json.decode(response.body);
|
||||
if (body['success'] == true) {
|
||||
final zones = List<Map<String, dynamic>>.from(body['zones'] ?? []);
|
||||
predictiveZones = zones;
|
||||
_drawPredictivePolygons(zones);
|
||||
print("✅ [Predictive] ${zones.length} zones loaded.");
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print("❌ [Predictive] Error: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void _drawPredictivePolygons(List<Map<String, dynamic>> zones) {
|
||||
const double offset = 0.008; // أكبر قليلاً من الهيتماب (0.005) ليكون مميزاً
|
||||
final Set<Polygon> temp = {};
|
||||
|
||||
for (final zone in zones) {
|
||||
final double lat = (zone['lat'] as num).toDouble();
|
||||
final double lng = (zone['lng'] as num).toDouble();
|
||||
final int score = (zone['demand_score'] as num).toInt();
|
||||
|
||||
// ألوان التنبؤ: أزرق/سماوي (مختلف تماماً عن الهيتماب)
|
||||
final Color fill = score >= 8
|
||||
? const Color(0xFF0EA5E9).withOpacity(0.35) // أزرق قوي
|
||||
: score >= 4
|
||||
? const Color(0xFF38BDF8).withOpacity(0.30) // أزرق فاتح
|
||||
: const Color(0xFF7DD3FC).withOpacity(0.25); // سماوي خفيف
|
||||
|
||||
final Color stroke = score >= 8
|
||||
? const Color(0xFF0369A1).withOpacity(0.9)
|
||||
: const Color(0xFF0EA5E9).withOpacity(0.8);
|
||||
|
||||
temp.add(Polygon(
|
||||
polygonId: PolygonId("pred_${lat}_$lng"),
|
||||
points: [
|
||||
LatLng(lat - offset, lng - offset),
|
||||
LatLng(lat + offset, lng - offset),
|
||||
LatLng(lat + offset, lng + offset),
|
||||
LatLng(lat - offset, lng + offset),
|
||||
],
|
||||
fillColor: fill,
|
||||
strokeColor: stroke,
|
||||
strokeWidth: 2,
|
||||
));
|
||||
}
|
||||
|
||||
predictivePolygons = temp;
|
||||
update();
|
||||
}
|
||||
|
||||
void goToWalletFromConnect() {
|
||||
Get.back();
|
||||
Get.back();
|
||||
|
||||
Reference in New Issue
Block a user