91 lines
3.7 KiB
PHP
91 lines
3.7 KiB
PHP
<?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; // زيادة الوزن (حسب نوع الطلب)
|
|
}
|
|
?>
|