Update: 2026-07-06 00:53:15

This commit is contained in:
Hamza-Ayed
2026-07-06 00:53:15 +03:00
parent 0c19486a24
commit d00502769a
4 changed files with 92 additions and 30 deletions
+14 -3
View File
@@ -85,9 +85,6 @@ foreach ($data as $row) {
}
$distanceKm = (float)($resultData['distance_km'] ?? 1);
if ($distanceKm <= 0) $distanceKm = 1; // Prevent division by zero
$pricePerKm = $amount / $distanceKm;
$durationMin = isset($resultData['duration_min']) ? (int)$resultData['duration_min'] : null;
$startLat = $resultData['start_lat'] ?? null;
@@ -95,6 +92,20 @@ foreach ($data as $row) {
$endLat = $resultData['end_lat'] ?? null;
$endLng = $resultData['end_lng'] ?? null;
// --- OSRM Integration (Dynamic Distance & Duration) ---
require_once __DIR__ . '/../core/osrm_routing.php';
if ($startLat && $endLat && (!$durationMin || $durationMin <= 0)) {
$osrmResult = getOsrmRouteDetails($startLat, $startLng, $endLat, $endLng);
if ($osrmResult) {
$distanceKm = $osrmResult['distance_km']; // Override with accurate OSRM distance
$durationMin = $osrmResult['duration_min'];
}
}
// ------------------------------------------------------
if ($distanceKm <= 0) $distanceKm = 1; // Prevent division by zero
$pricePerKm = $amount / $distanceKm;
$countryCode = $row['country_code'] ?? 'JO'; // Default
if ($stmt->execute([
+16 -3
View File
@@ -131,15 +131,28 @@ if ($method === 'GET') {
$pricePerKm = $distance_km > 0 ? ($price / $distance_km) : 0.0;
$country_code = $result_data['country_code'] ?? 'SY';
// --- OSRM Integration (Dynamic Distance & Duration) ---
require_once __DIR__ . '/../core/osrm_routing.php';
$duration_min = 0;
if ($start_lat != 0 && $end_lat != 0) {
$osrmResult = getOsrmRouteDetails($start_lat, $start_lng, $end_lat, $end_lng);
if ($osrmResult) {
$distance_km = $osrmResult['distance_km']; // Override with accurate OSRM distance
$duration_min = $osrmResult['duration_min'];
$pricePerKm = $distance_km > 0 ? ($price / $distance_km) : 0.0; // Recalculate based on OSRM
}
}
// ------------------------------------------------------
// 1. Save to MySQL
$stmt = $con->prepare("
INSERT INTO scraped_competitor_prices
(task_id, app_name, competitor_name, start_location, end_location, start_lat, start_lng, end_lat, end_lng, price_amount, price_per_km, currency, country_code)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
(task_id, app_name, competitor_name, start_location, end_location, start_lat, start_lng, end_lat, end_lng, price_amount, price_per_km, distance_km, duration_min, currency, country_code)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$start_loc = "Lat: $start_lat, Lng: $start_lng";
$end_loc = "Lat: $end_lat, Lng: $end_lng";
$stmt->execute([$task_id, $app_name, $app_name, $start_loc, $end_loc, (string)$start_lat, (string)$start_lng, (string)$end_lat, (string)$end_lng, $price, $pricePerKm, 'JOD', $country_code]);
$stmt->execute([$task_id, $app_name, $app_name, $start_loc, $end_loc, (string)$start_lat, (string)$start_lng, (string)$end_lat, (string)$end_lng, $price, $pricePerKm, $distance_km, $duration_min, 'JOD', $country_code]);
// 2. Save to Redis (Calculate Price Per KM)
if ($distance_km > 0 && $price > 0) {
+54
View File
@@ -0,0 +1,54 @@
<?php
// ============================================================
// osrm_routing.php
// Helper functions for OpenStreetMap Routing Machine (OSRM)
// Used to estimate accurate distance (km) and duration (mins)
// ============================================================
/**
* Get Distance and Duration between two coordinates using public OSRM server.
* Note: If you host your own OSRM, replace the $osrmBaseUrl.
*
* @param float $startLat
* @param float $startLng
* @param float $endLat
* @param float $endLng
* @return array|null Returns ['distance_km' => float, 'duration_min' => float] or null on failure.
*/
function getOsrmRouteDetails($startLat, $startLng, $endLat, $endLng) {
// Format: longitude,latitude
$coordinates = "{$startLng},{$startLat};{$endLng},{$endLat}";
// Using public demo server. Note: Has rate limits.
// For production, highly recommended to use: "http://your-own-osrm-server.com:5000"
$osrmBaseUrl = "http://router.project-osrm.org";
$url = "{$osrmBaseUrl}/route/v1/driving/{$coordinates}?overview=false";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 5 seconds timeout
// Add a User-Agent to avoid being blocked by the public demo server
curl_setopt($ch, CURLOPT_USERAGENT, "SiroRideHailingApp/1.0");
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 && $response) {
$data = json_decode($response, true);
if (isset($data['code']) && $data['code'] === 'Ok' && isset($data['routes'][0])) {
$route = $data['routes'][0];
$distanceMeters = isset($route['distance']) ? (float)$route['distance'] : 0;
$durationSeconds = isset($route['duration']) ? (float)$route['duration'] : 0;
return [
'distance_km' => round($distanceMeters / 1000, 2),
'duration_min' => round($durationSeconds / 60, 2)
];
}
}
return null;
}
+7 -23
View File
@@ -184,19 +184,12 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
break;
}
$longSpeedThresholdKm = 40.0;
$longSpeedPerKm = 26.0;
$mediumDistThresholdKm = 25.0;
$longDistThresholdKm = 35.0;
$longTripPerMin = 6.0;
$minuteCapMedium = 60;
$minuteCapLong = 80;
$freeMinutesLong = 10;
$extraReduction100 = 0.07;
$maxReductionCap = 0.35;
$totalMinutes = floor($duration / 60);
$airportCtx = (stripos($startNameAddress, 'airport') !== false || stripos($startNameAddress, 'مطار') !== false || stripos($endNameAddress, 'airport') !== false || stripos($endNameAddress, 'مطار') !== false);
@@ -210,23 +203,15 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
$isInDamascusAirportBoundCtx = ($passengerLat <= $northLat && $passengerLat >= $southLat && $passengerLng <= $eastLng && $passengerLng >= $westLng);
$billableDistance = ($distance < $minBillableKm) ? $minBillableKm : $distance;
$isLongSpeed = $billableDistance > $longSpeedThresholdKm;
$perKmSpeedBaseFromServer = getPerKmRate($carType, $kazanRow);
$perKmSpeed = $isLongSpeed ? $longSpeedPerKm : $perKmSpeedBaseFromServer;
$reductionPct40 = 0.0;
if ($perKmSpeedBaseFromServer > 0) {
$r = 1.0 - ($longSpeedPerKm / $perKmSpeedBaseFromServer);
$reductionPct40 = max(0.0, min($maxReductionCap, $r));
}
$reductionPct100 = max(0.0, min($maxReductionCap, $reductionPct40 + $extraReduction100));
$distanceReduction = 0.0;
if ($billableDistance > 100.0) {
$distanceReduction = $reductionPct100;
} else if ($billableDistance > 40.0) {
$distanceReduction = $reductionPct40;
// Apply dynamic percentage discount instead of hardcoded currencies for long trips
$perKmSpeed = $perKmSpeedBaseFromServer;
if ($billableDistance > $longDistThresholdKm) {
$perKmSpeed = $perKmSpeedBaseFromServer * 0.85; // 15% discount per km
} else if ($billableDistance > $mediumDistThresholdKm) {
$perKmSpeed = $perKmSpeedBaseFromServer * 0.90; // 10% discount per km
}
date_default_timezone_set('Asia/Damascus');
@@ -242,11 +227,10 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
$billableMinutes = $totalMinutes;
if ($billableDistance > $longDistThresholdKm) {
$effectivePerMin = $longTripPerMin;
// Prevent absurd time billing for very long trips
$capped = ($billableMinutes > $minuteCapLong) ? $minuteCapLong : $billableMinutes;
$billableMinutes = max(0, $capped - $freeMinutesLong);
} else if ($billableDistance > $mediumDistThresholdKm) {
$effectivePerMin = $longTripPerMin;
$billableMinutes = ($billableMinutes > $minuteCapMedium) ? $minuteCapMedium : $billableMinutes;
}