/**
  * get certain arrival code by arrival code
  *
  * @param $arrival_code
  * @return \Illuminate\Http\JsonResponse
  */
 public function getArrivalEstimationByCode($arrival_code)
 {
     $arrivalEstimationModel = new ArrivalEstimation();
     try {
         $arrivalEstimation = $arrivalEstimationModel->where('arrival_code', '=', $arrival_code)->with('thisHalte')->with('toHalte')->first();
         if ($arrivalEstimation != null) {
             $response = array();
             $response['code'] = 200;
             $response['data'] = $arrivalEstimation;
         } else {
             $response['code'] = 400;
             $response['data']['msg'] = 'could not find arrival schedule. make sure you type a correct arrival code';
         }
     } catch (\Exception $e) {
         $response['code'] = 500;
         $response['data']['msg'] = 'internal error, please try again later or contact administrator';
     }
     header("Access-Control-Allow-Origin: *");
     return response()->json($response);
 }
 /**
  * check if bus has arrived to nearest bus stop on its route
  * todo: detect if bus has arrived to certain bus stop
  */
 public function checkBusLocationStatus()
 {
     $this->filterNearestBusStop();
     if ($this->nearestBusStop['routes'][0]['legs'][0]['distance']['value'] <= 15) {
         $arrivalEstimationModel = new ArrivalEstimation();
         $arrivalEstimationModel->where('halte_id_tujuan', '=', $this->nearestBusStop['halte_id'])->delete();
         $busStop = new BusStop();
         $busStop->where('halte_id', '=', $this->nearestBusStop['halte_id'])->update(['last_bus' => $this->plat_nomor]);
         $busStopHistoryModel = new BusStopHistory();
         $busStopHistoryModel->plat_nomor = $this->plat_nomor;
         $busStopHistoryModel->halte_id = $this->nearestBusStop['halte_id'];
         $busStopHistoryModel->rute_id = $this->rute_id;
         $busStopHistoryModel->save();
     }
 }
 /**
  * Display bus operating in certain route
  *
  * @param $rute_id
  * @return \Illuminate\Http\JsonResponse
  */
 public function busOperationInRoute($rute_id)
 {
     $response = array();
     try {
         $arrivalEstimationModel = new ArrivalEstimation();
         $arrivalEstimation = $arrivalEstimationModel->where('rute_id', '=', $rute_id)->with(array('toHalte' => function ($query) {
             $query->addSelect('nama_halte', 'halte_id');
         }))->get()->toArray();
         if (isset($arrivalEstimation[0])) {
             $response['code'] = 200;
             $response['data'] = $arrivalEstimation;
         } else {
             $response['code'] = 400;
             $response['data']['msg'] = "cannot find operating bus in this route, please try again later";
         }
     } catch (\Exception $e) {
         $response['code'] = 500;
         $response['data']['msg'] = "internal server error, please contact administrator";
     }
     header("Access-Control-Allow-Origin: *");
     return response()->json($response);
 }
 public function getNearestArrivalByBus($plat_nomor, $position)
 {
     $arrivalEstimationModel = new ArrivalEstimation();
     $arrivalEstimation = $arrivalEstimationModel->where('plat_nomor', '=', $plat_nomor)->orderBy('waktu_kedatangan', 'asc')->with('thisHalte')->with('toHalte')->first();
     $this->listDetailAllBus[$position]['arrival'] = $arrivalEstimation;
 }
 /**
  * route planner controller. consist of 2 input, origin bus stop and destination bus stop
  * total time obtained from previous request arrival estimation to google maps api
  *
  * @param $halte_id_origin
  * @param $halte_id_dest
  * @return \Illuminate\Http\JsonResponse
  */
 public function searchRoutePlanner($halte_id_origin, $halte_id_dest)
 {
     $baseTreeLevel = 0;
     $this->baseSearchRouteRecursion($halte_id_origin, $halte_id_dest, $baseTreeLevel);
     $containerRoute = array();
     $totalTime = 0;
     $arrivalEstimationModel = new ArrivalEstimation();
     $routePlanner = InverseResponse::inverseResponse($this->response);
     $anomaly = json_decode(json_encode($routePlanner[0]), true);
     if ($routePlanner != null) {
         if ($routePlanner[0]['halte_id'] == $halte_id_origin) {
             for ($i = 0; $i < sizeof($routePlanner); $i++) {
                 if ($i < sizeof($routePlanner) - 1) {
                     $arrivalEstimation = $arrivalEstimationModel->where('halte_id_tujuan', '=', $routePlanner[$i]['halte_id'])->where('rute_id', '=', $routePlanner[$i + 1]['rute_id'])->where('waktu_kedatangan', '>', $totalTime)->orderBy('waktu_kedatangan', 'asc')->get()->toArray();
                     $containerRoute[$i]['origin'] = $routePlanner[$i]['halte_id'];
                     if ($i == 0) {
                         $containerRoute[$i]['detail_origin'] = $anomaly['detail_halte'];
                     } else {
                         $containerRoute[$i]['detail_origin'] = $routePlanner[$i]['detail_halte'];
                     }
                     $containerRoute[$i]['destination'] = $routePlanner[$i + 1]['halte_id'];
                     $containerRoute[$i]['detail_destination'] = $routePlanner[$i + 1]['detail_halte'];
                     $containerRoute[$i]['rute_id'] = $routePlanner[$i + 1]['rute_id'];
                     if ($arrivalEstimation != null) {
                         //find out waiting time
                         $waitingTime = $arrivalEstimation[0]['waktu_kedatangan'];
                         $totalTime = $totalTime + $waitingTime;
                         $containerRoute[$i]['plat_nomor'] = $arrivalEstimation[0]['plat_nomor'];
                         $containerRoute[$i]['waiting_time'] = $waitingTime;
                         //finding out travel time, make request to google distance matrix api
                         //alternative 1: google distance matrix
                         $param = array('units' => 'metric', 'origins' => $containerRoute[$i]['detail_origin']['latitude'] . ', ' . $containerRoute[$i]['detail_origin']['longitude'], 'destinations' => $containerRoute[$i]['detail_destination']['latitude'] . ', ' . $containerRoute[$i]['detail_destination']['longitude'], 'key' => 'AIzaSyDkN-x6OugkPjuxqgibtHe3bSTt5y3WoRU');
                         $url = 'https://maps.googleapis.com/maps/api/distancematrix/json?' . http_build_query($param);
                         $response = \Httpful\Request::get($url)->send();
                         $dataResponse = json_decode($response->raw_body, true);
                         $travelTime = $dataResponse['rows'][0]['elements'][0]['duration']['value'];
                         $containerRoute[$i]['travel_time'] = $travelTime;
                         //alternative 2: google directions - recommended, but a lot cost
                         $waypoints = '';
                         $busRouteModel = new BusRoute();
                         $busRoute = $busRouteModel->select('urutan')->where('rute_id', '=', $containerRoute[$i]['rute_id'])->where('halte_id', '=', $containerRoute[$i]['origin'])->get()->toArray();
                         if ($busRoute != null) {
                             $busStopOriginOrder = $busRoute[0]['urutan'];
                         }
                         $busRoute = $busRouteModel->select('urutan')->where('rute_id', '=', $containerRoute[$i]['rute_id'])->where('halte_id', '=', $containerRoute[$i]['destination'])->get()->toArray();
                         if ($busRoute != null) {
                             $busStopDestinationOrder = $busRoute[0]['urutan'];
                         }
                         if ($busStopDestinationOrder > $busStopOriginOrder) {
                             //search bus stop between origin and destination directly
                             $listBusRoute = $busRouteModel->whereBetween('urutan', [$busStopOriginOrder + 1, $busStopDestinationOrder - 1])->where('rute_id', '=', $containerRoute[$i]['rute_id'])->with('detailHalte')->get()->toArray();
                             $counterWaypoint = 0;
                             foreach ($listBusRoute as $busRoute) {
                                 if ($counterWaypoint < 22) {
                                     if ($counterWaypoint == 0) {
                                         $waypoints = 'via:' . $busRoute['detail_halte']['latitude'] . ', ' . $busRoute['detail_halte']['longitude'];
                                     } else {
                                         $waypoints = $waypoints . '|via:' . $busRoute['detail_halte']['latitude'] . ', ' . $busRoute['detail_halte']['longitude'];
                                     }
                                     $counterWaypoint++;
                                 }
                             }
                         } else {
                             //search bus stop between origin to max order, AND min order to destination
                             $busRoute = $busRouteModel->select('urutan')->where('rute_id', '=', $containerRoute[$i]['rute_id'])->orderBy('urutan', 'desc')->take(1)->get()->toArray();
                             $busStopMaxOrder = $busRoute[0]['urutan'];
                             $listBusRoute = $busRouteModel->where('rute_id', '=', $containerRoute[$i]['rute_id'])->whereBetween('urutan', [$busStopOriginOrder + 1, $busStopMaxOrder])->with('detailHalte')->get()->toArray();
                             //todo: waypoint loop
                             $counterWaypoint = 0;
                             foreach ($listBusRoute as $busRoute) {
                                 if ($counterWaypoint < 15) {
                                     if ($counterWaypoint == 0) {
                                         $waypoints = 'via:' . $busRoute['detail_halte']['latitude'] . ', ' . $busRoute['detail_halte']['longitude'];
                                     } else {
                                         $waypoints = $waypoints . '|via:' . $busRoute['detail_halte']['latitude'] . ', ' . $busRoute['detail_halte']['longitude'];
                                     }
                                 }
                                 $counterWaypoint++;
                             }
                             if ($busStopDestinationOrder != 1) {
                                 $listBusRoute = $busRouteModel->where('rute_id', '=', $containerRoute[$i]['rute_id'])->whereBetween('urutan', [1, $busStopDestinationOrder - 1])->with('detailHalte')->get()->toArray();
                                 foreach ($listBusRoute as $busRoute) {
                                     if ($waypoints < 22) {
                                         $waypoints = $waypoints . '|via:' . $busRoute['detail_halte']['latitude'] . ', ' . $busRoute['detail_halte']['longitude'];
                                     }
                                     $counterWaypoint++;
                                 }
                             }
                         }
                         $param = array('units' => 'metric', 'origin' => $containerRoute[$i]['detail_origin']['latitude'] . ', ' . $containerRoute[$i]['detail_origin']['longitude'], 'destination' => $containerRoute[$i]['detail_destination']['latitude'] . ', ' . $containerRoute[$i]['detail_destination']['longitude'], 'waypoints' => $waypoints, 'key' => 'AIzaSyDkN-x6OugkPjuxqgibtHe3bSTt5y3WoRU');
                         $url = $url = 'https://maps.googleapis.com/maps/api/directions/json?' . http_build_query($param);
                         $response = \Httpful\Request::get($url)->send();
                         $dataResponse = json_decode($response->raw_body, true);
                         $travelTime = $dataResponse['routes'][0]['legs'][0]['duration']['value'];
                         $containerRoute[$i]['travel_time'] = $travelTime;
                         $totalTime = $totalTime + $travelTime;
                     }
                 }
             }
         }
     }
     $containerResponse = array();
     $containerResponse['travel_info'] = $containerRoute;
     $containerResponse['total_time'] = $totalTime;
     $response = array();
     $response['code'] = 200;
     $response['data'] = $containerResponse;
     //echo '<br><br><br><br>'.json_encode($response);
     header("Access-Control-Allow-Origin: *");
     return response()->json($response);
 }