634 lines
25 KiB
PHP
634 lines
25 KiB
PHP
<?php
|
|
|
|
class Route {
|
|
|
|
/*
|
|
savvy=> select id,name from transport_providers;
|
|
id | name
|
|
----+---------------
|
|
1 | Uber
|
|
2 | Lyft
|
|
3 | Grab
|
|
4 | ComfortDelGro
|
|
5 | GOJEK
|
|
6 | Turo
|
|
7 | Getaround
|
|
10 | GrabWheels
|
|
11 | BART
|
|
12 | Muni
|
|
13 | LTA
|
|
(11 rows)
|
|
*/
|
|
public static function getTransportRoute($db, $origin, $destination, $option, $trip) {
|
|
$route = [];
|
|
switch ($option["transport_provider_id"]) {
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 8:
|
|
list($option, $trip, $route) = Route::drivingDirections($db, $origin, $destination, $option, $trip);
|
|
break;
|
|
case 11: // BART
|
|
list($option, $trip, $route) = Route::bartDirections($db, $origin, $destination, $option, $trip);
|
|
break;
|
|
case 12: // Muni
|
|
list($option, $trip, $route) = Route::muniDirections($db, $origin, $destination, $option, $trip);
|
|
break;
|
|
case 13: // LTA
|
|
list($option, $trip, $route) = Route::ltaDirections($db, $origin, $destination, $option, $trip);
|
|
break;
|
|
case 14: // MARTA
|
|
list($option, $trip, $route) = Route::martaDirections($db, $origin, $destination, $option, $trip);
|
|
break;
|
|
}
|
|
error_log(json_encode($trip));
|
|
return [$option, $trip, $route];
|
|
}
|
|
|
|
public static function drivingDirections($db, $origin, $destination, $option, $trip) {
|
|
list($option, $trip, $route) = Route::processRideshareOption($db, $option, $origin, $destination, $trip);
|
|
$option["travel_time"] = (int)$trip["duration"];
|
|
$option["travel_distance"] = (int)$trip["distance"];
|
|
$trip["source"] = strtolower($option["name"]);
|
|
return [$option, $trip, $route];
|
|
}
|
|
|
|
public static function drivingDirectionsOriginal($db, $origin, $destination, $option, $trip) {
|
|
$options = [];
|
|
$trip = [];
|
|
$option["travel_time"] = 0;
|
|
$option["travel_distance"] = 0;
|
|
$fromLat = $origin['lat'];
|
|
$fromLng = $origin['lng'];
|
|
$toLat = $destination['lat'];
|
|
$toLng = $destination['lng'];
|
|
// This is paranoid redudant check, but since the function is "public"...
|
|
if ($fromLat==null || $fromLng==null || $toLat==null || $toLng==null
|
|
|| ($fromLat==0 && $fromLng==0) || ($toLat==0 && $toLng==0)) {
|
|
throw new Exception('Invalid origin and/or destination coordinates');
|
|
}
|
|
list($res, $err) = Route::serviceRoute($db, $fromLat, $fromLng, $toLat, $toLng);
|
|
if ($err!=NULL || !is_array($res) || !isset($res["routes"]) || count($res["routes"])<1) {
|
|
$options['error'] = $err!=NULL ? $err : 'No available routes';
|
|
return [$option, $trip, $options];
|
|
}
|
|
$options["route_overlay"] = [];
|
|
$travel_time = PHP_INT_MAX;
|
|
$travel_distance = PHP_INT_MAX;
|
|
foreach ($res["routes"] as $route) {
|
|
$r = Route::processRoute($route);
|
|
if ($travel_time>$r['duration']) {
|
|
$travel_time = $r['duration'];
|
|
$travel_distance = $r['distance'];
|
|
}
|
|
$options["route_overlay"][] = $r;
|
|
}
|
|
$options["travel_time"] = $travel_time==PHP_INT_MAX ? NULL : $travel_time;
|
|
$options["travel_distance"] = $travel_distance==PHP_INT_MAX ? NULL : $travel_distance;
|
|
|
|
$option["travel_time"] = (int)$options["travel_time"];
|
|
$option["travel_distance"] = (int)$options["travel_distance"];
|
|
|
|
//https://developers.google.com/maps/documentation/utilities/polylinealgorithm
|
|
//overview_polyline
|
|
//bounds contains the viewport bounding box of the overview_polyline.
|
|
return [$option, $trip, $options];
|
|
}
|
|
|
|
public static function bartDirections($db, $origin, $destination, $option, $trip) {
|
|
$route = [];
|
|
|
|
$option["travel_time"] = 0;
|
|
$option["travel_distance"] = 0;
|
|
|
|
$route["travel_time"] = 0;
|
|
$route["travel_distance"] = 0;
|
|
$route["route_overlay"] = [];
|
|
|
|
$country = $origin["country"];
|
|
$member_id = $option["member_id"];
|
|
|
|
// New directions
|
|
$tripService = Route::tripService($trip["id"], $country, 'BART');
|
|
|
|
//error_log(json_encode($tripService));
|
|
if (is_array($tripService) && isset($tripService["travel_date"])) {
|
|
$tripService["member_id"] = $member_id; // Pass along
|
|
$tripService["country"] = $country;
|
|
$tripService = MultiModalFilter::byDuration($tripService);
|
|
//$tripService = MultiModalFilter::byCost($tripService);
|
|
$trip = $tripService;
|
|
|
|
$option["travel_time"] = (int)$trip["options"]["legs"][0]["duration"];
|
|
$option["travel_distance"] = (int)$trip["options"]["legs"][0]["distance"];
|
|
|
|
$route = Route::routeFromTrip($db, $origin, $destination, $option, $trip);
|
|
}
|
|
return [$option, $trip, $route];
|
|
}
|
|
|
|
public static function muniDirections($db, $origin, $destination, $option, $trip) {
|
|
$route = [];
|
|
|
|
$option["travel_time"] = 0;
|
|
$option["travel_distance"] = 0;
|
|
$country = $origin["country"];
|
|
$member_id = $option["member_id"];
|
|
|
|
// New directions
|
|
$tripService = Route::tripService($trip["id"], $country, 'MUNI');
|
|
|
|
//error_log(json_encode($tripService));
|
|
if (is_array($tripService) && isset($tripService["travel_date"])) {
|
|
$tripService["member_id"] = $member_id; // Pass along
|
|
$tripService["country"] = $country;
|
|
|
|
$tripService = MultiModalFilter::byDuration($tripService);
|
|
//$tripService = MultiModalFilter::byCost($tripService);
|
|
$trip = $tripService;
|
|
|
|
$option["travel_time"] = (int)$trip["options"]["legs"][0]["duration"];
|
|
$option["travel_distance"] = (int)$trip["options"]["legs"][0]["distance"];
|
|
|
|
$route = Route::routeFromTrip($db, $origin, $destination, $option, $trip);
|
|
}
|
|
return [$option, $trip, $route];
|
|
}
|
|
|
|
public static function ltaDirections($db, $origin, $destination, $option, $trip) {
|
|
$route = [];
|
|
|
|
$option["travel_time"] = 0;
|
|
$option["travel_distance"] = 0;
|
|
$country = $origin["country"];
|
|
$member_id = $option["member_id"];
|
|
|
|
// New directions
|
|
$tripService = Route::tripService($trip["id"], $country, 'LTA');
|
|
|
|
//error_log(json_encode($tripService));
|
|
if (is_array($tripService) && isset($tripService["travel_date"])) {
|
|
$tripService["member_id"] = $member_id; // Pass along
|
|
$tripService["country"] = $country;
|
|
|
|
$tripService = MultiModalFilter::byDuration($tripService);
|
|
//$tripService = MultiModalFilter::byCost($tripService);
|
|
$trip = $tripService;
|
|
|
|
$option["travel_time"] = (int)$trip["options"]["legs"][0]["duration"];
|
|
$option["travel_distance"] = (int)$trip["options"]["legs"][0]["distance"];
|
|
|
|
$route = Route::routeFromTrip($db, $origin, $destination, $option, $trip);
|
|
}
|
|
return [$option, $trip, $route];
|
|
}
|
|
|
|
public static function martaDirections($db, $origin, $destination, $option, $trip) {
|
|
$route = [];
|
|
|
|
$option["travel_time"] = 0;
|
|
$option["travel_distance"] = 0;
|
|
$country = $origin["country"];
|
|
$member_id = $option["member_id"];
|
|
|
|
// New directions
|
|
$tripService = Route::tripService($trip["id"], $country, 'MARTA');
|
|
|
|
//error_log(json_encode($tripService));
|
|
if (is_array($tripService) && isset($tripService["travel_date"])) {
|
|
$tripService["member_id"] = $member_id; // Pass along
|
|
$tripService["country"] = $country;
|
|
|
|
$tripService = MultiModalFilter::byDuration($tripService);
|
|
$trip = $tripService;
|
|
|
|
$option["travel_time"] = (int)$trip["options"]["legs"][0]["duration"];
|
|
$option["travel_distance"] = (int)$trip["options"]["legs"][0]["distance"];
|
|
|
|
$route = Route::routeFromTrip($db, $origin, $destination, $option, $trip);
|
|
}
|
|
return [$option, $trip, $route];
|
|
}
|
|
|
|
public static function routeFromTrip($db, $origin, $destination, $option, $trip) {
|
|
|
|
$leg = [
|
|
"distance" => 0,
|
|
"duration" => 0,
|
|
"polyline" => NULL
|
|
];
|
|
// Select leg
|
|
foreach ($trip["options"]["legs"] as $leg) {
|
|
break;
|
|
}
|
|
|
|
$route["travel_time"] = (int)$leg["duration"];
|
|
$route["travel_distance"] = (int)$leg["distance"];
|
|
|
|
// TODO: BART fix polyline!
|
|
|
|
$route["route_overlay"][] = [
|
|
"polyline" => [],
|
|
"distance" => $leg["distance"],
|
|
"duration" => $leg["duration"],
|
|
"summary" => "Generated option",
|
|
"overview_polyline" => [
|
|
"points" => Route::processPolyline($leg["polyline"])
|
|
],
|
|
"bounds" => [
|
|
"northeast" => [
|
|
"lat" => $origin["lat"],
|
|
"lng" => $origin["lng"]
|
|
],
|
|
"southwest" => [
|
|
"lat" => $destination["lat"],
|
|
"lng" => $destination["lng"]
|
|
]
|
|
]
|
|
];
|
|
return $route;
|
|
}
|
|
|
|
public static function checkValidRoute($db, $route) {
|
|
// Basic input sanity check: route
|
|
if (!is_array($route) || !array_key_exists('travel_time',$route) || !is_numeric($route['travel_time'])
|
|
|| !array_key_exists('travel_distance',$route) || !is_numeric($route['travel_distance'])
|
|
|| !array_key_exists('route_overlay',$route) || !is_array($route['route_overlay'])) {
|
|
throw new Exception('Invalid transport route');
|
|
}
|
|
}
|
|
|
|
public static function serviceRoute($db, $fromLat, $fromLng, $toLat, $toLng, $mode='driving',$waypoints=[]) {
|
|
global $savvyext;
|
|
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
|
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
|
error_log("Route::serviceRoute(\$db, $fromLat, $fromLng, $toLat, $toLng, $mode, \$waypoints=[])");
|
|
// Call geocoding service
|
|
$data = http_build_query(
|
|
array(
|
|
'gps' => implode(",",array($fromLat, $fromLng, $toLat, $toLng)),
|
|
'mode' => $mode,
|
|
'waypoints' => implode(",",$waypoints)
|
|
)
|
|
);
|
|
$url = $oauth2_url."route?" . $data;
|
|
$opts = array(
|
|
'http' => array(
|
|
'method' => "GET",
|
|
'timeout' => 60, /* 1 minute */
|
|
'header' =>
|
|
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
|
"Accept: application/json\r\n" .
|
|
"Authorization: Server-Token ${httpAuthToken}\r\n",
|
|
),
|
|
"ssl" => array(
|
|
"verify_peer"=>false,
|
|
"verify_peer_name"=>false,
|
|
)
|
|
);
|
|
$context = stream_context_create($opts);
|
|
$body = file_get_contents($url, false, $context);
|
|
$geocoded = json_decode($body,true);
|
|
if (is_array($geocoded) && is_array($geocoded["data"]) && !isset($geocoded["error"])) {
|
|
return array($geocoded["data"], NULL);
|
|
} else if (is_array($geocoded) && isset($geocoded["error"])) {
|
|
$body = $geocoded["error"];
|
|
}
|
|
return array(NULL, "Routing service call error: ".$body);
|
|
}
|
|
|
|
public static function processRoute($route) {
|
|
require_once('../common/Polyline.php');
|
|
$result = [
|
|
'polyline' => array(),
|
|
'distance' => NULL,
|
|
'duration' => NULL,
|
|
'summary' => $route["summary"],
|
|
'overview_polyline' => $route["overview_polyline"],
|
|
'bounds' => $route["bounds"]
|
|
];
|
|
$distance = 0;
|
|
$duration = 0;
|
|
foreach ($route["legs"] as $leg) {
|
|
$distance += $leg["distance"]["value"];
|
|
$duration += $leg["duration"]["value"];
|
|
foreach ($leg["steps"] as $step) {
|
|
$points = Polyline::decode($step["polyline"]["points"]);
|
|
$result['polyline'] = array_merge($result['polyline'],Polyline::pair($points));
|
|
}
|
|
}
|
|
$result['distance'] = $distance;
|
|
$result['duration'] = $duration;
|
|
return $result;
|
|
}
|
|
|
|
public static function processRideshareOption($db, $option, $origin, $destination, $trip) {
|
|
error_log("Options::processRideshareOption(\$db, \$option, \$origin, \$destination, \$trip)");
|
|
$route = [];
|
|
$route["travel_time"] = 0;
|
|
$route["travel_distance"] = 0;
|
|
$route["route_overlay"] = [];
|
|
$member_id = $option["member_id"];
|
|
$country = $origin["country"];
|
|
$rideshare = $option["name"];
|
|
$transport_provider_id = $option["transport_provider_id"];
|
|
if (array_key_exists("timeZoneId",$origin) && $origin["timeZoneId"]!="") {
|
|
$tz = $origin["timeZoneId"];
|
|
} else if (array_key_exists("timeZoneId",$destination) && $destination["timeZoneId"]!="") {
|
|
$tz = $destination["timeZoneId"];
|
|
} else {
|
|
$tz = Options::getTimezoneById($db, $origin["timezone"], "Asia/Singapore");
|
|
}
|
|
//"trips"=>$trips;
|
|
if (!is_array($trip) && count($trip)<1) {
|
|
syslog(LOG_WARNING,"Invalid trip");
|
|
return [$option, $trip, $route]; // No idea how to handle it
|
|
}
|
|
/*if (!array_key_exists('trip',$trip) || !is_array($trip['trip']) || count($trip['trip'])<10) {
|
|
syslog(LOG_WARNING,"Invalid trip[0]!");
|
|
return $trips; // No idea how to handle it
|
|
} //*/
|
|
$oldTrip = $trip; //['trip'];
|
|
|
|
$origin['latitude'] = $origin['lat'];
|
|
$origin['longitude'] = $origin['lng'];
|
|
$destination['latitude'] = $destination['lat'];
|
|
$destination['longitude'] = $destination['lng'];
|
|
list($res, $err) = Route::serviceRoute($db,
|
|
$origin['lat'], $origin['lng'],
|
|
$destination['lat'], $destination['lng'], 'driving'
|
|
);
|
|
if ($err!=NULL || !is_array($res) || !isset($res["routes"]) || count($res["routes"])<1) {
|
|
error_log('No available routes!');
|
|
error_log($err);
|
|
return [$option, $trip, $route]; // We cannot route driving!
|
|
}
|
|
$route_overlay = [];
|
|
$travel_time = PHP_INT_MAX;
|
|
$travel_distance = PHP_INT_MAX;
|
|
foreach ($res["routes"] as $item) {
|
|
$r = Route::processRoute($item);
|
|
if ($travel_time>$r['duration']) {
|
|
$travel_time = $r['duration'];
|
|
$travel_distance = $r['distance'];
|
|
}
|
|
$route_overlay[] = $r;
|
|
}
|
|
$oldTrip["duration"] = $travel_time==PHP_INT_MAX ? NULL : $travel_time;
|
|
$oldTrip["distance"] = $travel_distance==PHP_INT_MAX ? NULL : $travel_distance;
|
|
|
|
$route["travel_time"] = (int)$oldTrip["duration"];
|
|
$route["travel_distance"] = (int)$oldTrip["distance"];
|
|
$route["route_overlay"] = $route_overlay;
|
|
/*
|
|
$result = [
|
|
'polyline' => array(),
|
|
'distance' => NULL,
|
|
'duration' => NULL,
|
|
'summary' => $route["summary"],
|
|
'overview_polyline' => $route["overview_polyline"],
|
|
'bounds' => $route["bounds"]
|
|
];
|
|
*/
|
|
//syslog(LOG_WARNING,json_encode($res));
|
|
$route_0 = $res["routes"][0];
|
|
$route_leg = $route_0["legs"][0];
|
|
$route_leg_steps = $route_leg["steps"];
|
|
$overview_polyline = Route::processPolyline($route_0["overview_polyline"]["points"]);
|
|
|
|
$leg_steps = [];
|
|
$distance = 0;
|
|
$duration = 0;
|
|
$location_start_lat = 0;
|
|
$location_start_lng = 0;
|
|
$location_end_lat = 0;
|
|
$location_end_lng = 0;
|
|
$polyline = [];
|
|
$i = 0; $j=1; $n = count($route_leg_steps);
|
|
for (; $i<$n; $i++) {
|
|
$step = $route_leg_steps[$i];
|
|
if ($step["travel_mode"] == "DRIVING") {
|
|
$location_start_lat = $step["start_location"]["lat"];
|
|
$location_start_lng = $step["start_location"]["lng"];
|
|
break;
|
|
}
|
|
$leg_steps[] = [
|
|
'distance' => $step["distance"]["value"],
|
|
'duration' => $step["duration"]["value"],
|
|
'html_instructions' => $step["html_instructions"],
|
|
'location_end_lat' => $step["end_location"]["lat"],
|
|
'location_end_lng' => $step["end_location"]["lng"],
|
|
'location_start_lat' => $step["start_location"]["lat"],
|
|
'location_start_lng' => $step["start_location"]["lng"],
|
|
'polyline' => $step["polyline"]["points"], /*"yz|Fm_nxRi@e@_@P",*/
|
|
'sid' => $j++,
|
|
'travel_mode' => $step["travel_mode"]
|
|
];
|
|
}
|
|
for (;$i<$n; $i++) {
|
|
$step = $route_leg_steps[$i];
|
|
if ($step["travel_mode"] != "DRIVING") {
|
|
break;
|
|
}
|
|
$distance += $step["distance"]["value"];
|
|
$duration += $step["duration"]["value"];
|
|
$location_end_lat = $step["end_location"]["lat"];
|
|
$location_end_lng = $step["end_location"]["lng"];
|
|
$polyline[] = $step["polyline"]["points"];
|
|
}
|
|
$leg_steps[] = [
|
|
'distance' => $distance,
|
|
'duration' => $duration,
|
|
'fare_quote' => null,
|
|
'fare_raw' => null,
|
|
'html_instructions' => "Take ".$rideshare." to ".$destination["address"],
|
|
'location_end_lat' => $location_end_lat,
|
|
'location_end_lng' => $location_end_lng,
|
|
'location_start_lat' => $location_start_lat,
|
|
'location_start_lng' => $location_start_lng,
|
|
'polyline' => Route::processPolyline($polyline),
|
|
'quote_group_id' => null,
|
|
'sid' => $j++,
|
|
'travel_mode' => strtoupper($rideshare)
|
|
];
|
|
for (;$i<$n; $i++) {
|
|
$step = $route_leg_steps[$i];
|
|
$leg_steps[] = [
|
|
'distance' => $step["distance"]["value"],
|
|
'duration' => $step["duration"]["value"],
|
|
'html_instructions' => $step["html_instructions"],
|
|
'location_end_lat' => $step["end_location"]["lat"],
|
|
'location_end_lng' => $step["end_location"]["lng"],
|
|
'location_start_lat' => $step["start_location"]["lat"],
|
|
'location_start_lng' => $step["start_location"]["lng"],
|
|
'polyline' => $step["polyline"]["points"], /*"yz|Fm_nxRi@e@_@P",*/
|
|
'sid' => $j++,
|
|
'travel_mode' => $step["travel_mode"]
|
|
];
|
|
}
|
|
|
|
$cost = null;
|
|
|
|
$rideshare = [
|
|
'cost' => $cost,
|
|
'cost_raw' => $cost,
|
|
'count' => 1,
|
|
'country' => $country,
|
|
'distance' => $oldTrip['distance'],
|
|
'dup_id' => null,
|
|
'duration' => $oldTrip['duration'],
|
|
'id' => $oldTrip['id'],
|
|
'location_end' => $destination['address'],
|
|
'location_end_id' => $oldTrip['location_end_id'],
|
|
'location_end_lat' => $destination['latitude'],
|
|
'location_end_lng' => $destination['longitude'],
|
|
'location_end_tz' => $destination['timezone'],
|
|
'location_start' => $origin['address'],
|
|
'location_start_id' => $oldTrip['location_start_id'],
|
|
'location_start_lat' => $origin['latitude'],
|
|
'location_start_lng' => $origin['longitude'],
|
|
'location_start_tz' => $origin['timezone'],
|
|
'member_id' => $member_id,
|
|
'options' => [],
|
|
'parsedemail_item_id' => null, /* $trip['id'] ??? */
|
|
'private' => 't',
|
|
'scheduled' => null,
|
|
'trackedemail_item_id' => null,
|
|
'transport_provider_id' => $transport_provider_id,
|
|
'travel_date' => $oldTrip['travel_date'],
|
|
'travel_date_end' => $oldTrip['travel_date_end'],
|
|
'updated' => $oldTrip['updated']
|
|
];
|
|
// Create trip advice
|
|
$rideshare["source"] = strtolower($option["name"]);
|
|
$parsedemail_item_advice_google_id = Options::saveTripAdvice($db, $rideshare);
|
|
error_log(json_encode($parsedemail_item_advice_google_id));
|
|
|
|
$leg_fare = $cost;
|
|
// Get departure and arrival times...
|
|
$date = new DateTime("now", new DateTimeZone($tz));
|
|
$date->add(new DateInterval('PT15M'));
|
|
$departure_time = $date->getTimestamp();
|
|
$duration = Route::getDuration(array_key_exists('duration',$oldTrip)?$oldTrip['duration']:900);
|
|
$date->add(new DateInterval('PT'.$duration.'M'));
|
|
$arrival_time = $date->getTimestamp();
|
|
|
|
$leg = [
|
|
'id' => NULL,
|
|
'parsedemail_item_advice_google_id' => $parsedemail_item_advice_google_id,
|
|
'arrival_time' => $arrival_time,
|
|
'arrival_time_zone' => $destination['timezone'],
|
|
'arrival_timezone' => $tz,
|
|
'departure_time' => $departure_time,
|
|
'departure_time_zone' => $origin['timezone'],
|
|
'departure_timezone' => $tz,
|
|
'distance' => $oldTrip['distance'],
|
|
'duration' => $oldTrip['duration'],
|
|
'fare_raw' => $cost,
|
|
'polyline' => $overview_polyline,
|
|
'quote' => $cost,
|
|
'steps' => count($leg_steps),
|
|
];
|
|
// Create leg
|
|
$google_directions_leg_id = Options::saveTripAdviceLeg($db, $rideshare, $leg);
|
|
$leg['id'] = $google_directions_leg_id;
|
|
foreach ($leg_steps as $i=>$step) {
|
|
$step['google_directions_leg_id'] = $google_directions_leg_id;
|
|
$google_directions_leg_step_id = Options::saveTripAdviceLegStep($db, $rideshare, $leg, $step);
|
|
$step['id'] = $google_directions_leg_step_id;
|
|
$leg_steps[$i] = $step;
|
|
}
|
|
$options = [
|
|
'gid' => $google_directions_leg_id, /* ??? */
|
|
'leg_fare' => [$google_directions_leg_id => $leg_fare],
|
|
'leg_steps' => [$google_directions_leg_id => $leg_steps],
|
|
'legs' => [$leg],
|
|
'routes' => 1
|
|
];
|
|
$rideshare['options'] = $options;
|
|
return [$option, $rideshare, $route];
|
|
}
|
|
|
|
protected static function getDuration($duration=900) {
|
|
if ($duration==NULL) {
|
|
return 15;
|
|
}
|
|
if ($duration>60) {
|
|
return (int)($duration/60);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
public static function processPolyline($data) {
|
|
if (!is_array($data)) {
|
|
return $data;
|
|
}
|
|
require_once('../common/Polyline.php');
|
|
$points = [];
|
|
foreach ($data as $item) {
|
|
$points = array_merge($points, Polyline::decode($item));
|
|
//$points = array_merge(Polyline::decode($item),$points);
|
|
break;
|
|
}
|
|
return Polyline::encode($points);
|
|
}
|
|
|
|
public static function tripService($id, $country, $mode) {
|
|
global $savvyext;
|
|
$httpAuthToken = $savvyext->cfgReadChar('system.oauth2_token');
|
|
$oauth2_url = $savvyext->cfgReadChar('system.oauth2_url');
|
|
error_log("Route::tripService($id)");
|
|
if ($country!='SG' && $country!='US') {
|
|
throw new Exception('Unsupported country: '.$country);
|
|
}
|
|
// curl -d 'id=44254' -d 'mode=BART' -d 'country=US' -H 'Authorization: Server-Token 99dfe35fcb7de1ee' -X POST {$oauth2_url}modetrips
|
|
$postdata = http_build_query(
|
|
array(
|
|
'id'=> $id,
|
|
'mode' => $mode,
|
|
'country' => $country
|
|
)
|
|
);
|
|
$url = $oauth2_url."modetrips";
|
|
$opts = array(
|
|
'http' => array(
|
|
'method' => "POST",
|
|
'timeout' => 60, /* 1 minute */
|
|
'header' =>
|
|
"Content-Type: application/x-www-form-urlencoded\r\n" .
|
|
"Accept: application/json\r\n" .
|
|
"Authorization: Server-Token ${httpAuthToken}\r\n",
|
|
'content' => $postdata
|
|
),
|
|
"ssl" => array(
|
|
"verify_peer"=>false,
|
|
"verify_peer_name"=>false,
|
|
)
|
|
);
|
|
$context = stream_context_create($opts);
|
|
error_log("started trips service call");
|
|
$t = time();
|
|
$body = file_get_contents($url, false, $context);
|
|
error_log("complete trips service call: ".(time()-$t)." seconds");
|
|
$trip = json_decode($body,true);
|
|
return $trip;
|
|
}
|
|
}
|
|
/*
|
|
["id"]=>
|
|
string(1) "5"
|
|
["city_id"]=>
|
|
string(1) "2"
|
|
["name"]=>
|
|
string(4) "Uber"
|
|
["transport_provider_id"]=>
|
|
string(1) "1"
|
|
["custom"]=>
|
|
NULL
|
|
*/
|
|
|
|
// vi:ts=2
|
|
|