keys("demand:grid:*"); } catch (Exception $e) { error_log("[heatmap_live.php] Redis keys error: " . $e->getMessage()); echo json_encode([]); exit(); } $heatmap_data = []; foreach ($keys as $key) { // The keys returned by $redis->keys() will actually contain the 'siro:' prefix // e.g. siro:demand:grid:33.5135_36.2735 $parts = explode(":", $key); $coords = explode("_", end($parts)); if (count($coords) == 2) { $lat = (float)$coords[0]; $lng = (float)$coords[1]; // We must strip 'siro:' to use $redis->get() because $redis auto-prefixes everything! // Actually, $redis->keys() returns the physical key "siro:demand:grid:X" // But $redis->get("demand:grid:X") automatically prepends "siro:". // So we must strip the "siro:" part before passing to get() $clean_key = str_replace("siro:", "", $key); $count = (int)$redis->get($clean_key); // Fetch active drivers using Location Redis $available_drivers = 0; try { global $redisLocation; if (isset($redisLocation) && $redisLocation !== null) { $drivers = $redisLocation->georadius('geo:drivers:available', $lng, $lat, 0.75, 'km'); $availableDrivers = count($drivers); } } catch (Exception $e) {} $intensity = 'low'; $surge_ratio = ($available_drivers > 0) ? ($count / $available_drivers) : $count; if ($surge_ratio > 2.0 || $count >= 5) { $intensity = 'high'; } else if ($surge_ratio > 1.2 || $count >= 3) { $intensity = 'medium'; } $heatmap_data[] = [ "lat" => $lat, "lng" => $lng, "count" => $count, "intensity" => $intensity ]; } } // === MERGE AI HOT ZONES === // ندمج مناطق الذروة الخاصة بالمنافسين (التي استخرجها الذكاء الاصطناعي) لتظهر باللون الأحمر (High) try { $aiHotZonesJson = $redis->get('siro:cache:ai:hotzones'); if ($aiHotZonesJson) { $aiZonesData = json_decode($aiHotZonesJson, true); if (isset($aiZonesData['status']) && $aiZonesData['status'] == 'success' && isset($aiZonesData['data'])) { foreach ($aiZonesData['data'] as $zone) { // نضيفها للمصفوفة ليقوم تطبيق الفلاتر برسمها كمربعات حمراء تلقائياً $heatmap_data[] = [ "lat" => (float)$zone['latitude'], "lng" => (float)$zone['longitude'], "count" => 99, // رقم كبير لإجبار التطبيق على تلوينها بالأحمر (High) "intensity" => "high", "is_ai_surge" => true, "competitor" => $zone['top_competitor'] ?? '', "price" => $zone['avg_price'] ?? 0 ]; } } } } catch (Exception $e) { error_log("[heatmap_live.php] AI Hotzones merge error: " . $e->getMessage()); } // Output the JSON array as expected by home_captain_controller.dart header('Content-Type: application/json'); echo json_encode($heatmap_data); ?>