Files
intaleq_v3_pure_php/ride/rides/getRealTimeHeatmap.php
2026-04-28 13:04:27 +03:00

91 lines
3.7 KiB
PHP
Executable File

<?php
// getRealTimeHeatmap.php
require_once __DIR__ . '/../../get_connect.php';
header('Content-Type: application/json; charset=utf-8');
try {
$precision = 2; // دقة الشبكة (تقريباً 1 كم)
// الأوزان
$WEIGHT_WAITING = 5; // طلب انتظار = 5 نقاط
$WEIGHT_MISSED = 8; // طلب ضائع = 8 نقاط (أهمية قصوى)
$WEIGHT_ACTIVE = 1; // طلب نشط = 1 نقطة
$grid = [];
// 1. طلبات الانتظار (Waiting)
$stmtW = $con->prepare("SELECT start_lat, start_lng FROM waitingRides WHERE status IN ('wait', 'waiting')");
$stmtW->execute();
while ($row = $stmtW->fetch(PDO::FETCH_ASSOC)) {
addToGrid($grid, $row['start_lat'], $row['start_lng'], $precision, $WEIGHT_WAITING);
}
// 2. طلبات ضائعة (Timeout)
$stmtM = $con->prepare("SELECT start_location FROM ride WHERE (status = 'timeout' OR status = 'cancelled_no_driver_found') AND created_at >= DATE_SUB(NOW(), INTERVAL 20 MINUTE)");
$stmtM->execute();
while ($row = $stmtM->fetch(PDO::FETCH_ASSOC)) {
$parts = explode(',', $row['start_location']);
if (count($parts) == 2) addToGrid($grid, $parts[0], $parts[1], $precision, $WEIGHT_MISSED);
}
// 3. طلبات نشطة (Active)
$stmtA = $con->prepare("SELECT start_location FROM ride WHERE created_at >= DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND status NOT IN ('timeout', 'cancelled_no_driver_found')");
$stmtA->execute();
while ($row = $stmtA->fetch(PDO::FETCH_ASSOC)) {
$parts = explode(',', $row['start_location']);
if (count($parts) == 2) addToGrid($grid, $parts[0], $parts[1], $precision, $WEIGHT_ACTIVE);
}
// تجهيز البيانات النهائية
$finalData = [];
foreach ($grid as $cell) {
$score = $cell['score']; // مجموع النقاط (الوزن)
$count = $cell['count']; // العدد الحقيقي للطلبات
// 🧠 المنطق المزدوج: نحدد اللون بناءً على النقاط أو العدد
$intensity = "low";
$surge = 1.0;
// المعادلة: منطقة حمراء إذا كان السكور عالي جداً (مشاكل) أو العدد كبير جداً (زحمة)
if ($score >= 15 || $count >= 5) {
$intensity = "high"; // أحمر (خطر/فرصة ذهبية)
$surge = 1.5;
} elseif ($score >= 8 || $count >= 3) {
$intensity = "medium"; // برتقالي
$surge = 1.2;
} elseif ($score >= 3 || $count >= 1) {
$intensity = "normal"; // أصفر
}
if ($score > 0) {
$finalData[] = [
'lat' => $cell['lat'],
'lng' => $cell['lng'],
'count' => $count, // ✅ العدد الحقيقي (مهم للعرض)
'intensity' => $intensity, // ✅ التصنيف الذكي
'surge' => $surge
];
}
}
file_put_contents('heatmap_live.json', json_encode($finalData)); // الكاش
echo json_encode(["status" => "success", "data" => $finalData]);
} catch (Exception $e) {
echo json_encode(["status" => "failure", "message" => $e->getMessage()]);
}
function addToGrid(&$grid, $lat, $lng, $precision, $weight) {
if (empty($lat) || empty($lng)) return;
$rLat = round(floatval($lat), $precision);
$rLng = round(floatval($lng), $precision);
$key = "$rLat,$rLng";
if (!isset($grid[$key])) {
$grid[$key] = ['lat' => $rLat, 'lng' => $rLng, 'count' => 0, 'score' => 0];
}
$grid[$key]['count']++; // زيادة العدد (+1 دائماً)
$grid[$key]['score'] += $weight; // زيادة الوزن (حسب نوع الطلب)
}
?>