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 ]; } } // Output the JSON array as expected by home_captain_controller.dart header('Content-Type: application/json'); echo json_encode($heatmap_data); ?>