em = $em; $this->gmaps_api_key = $gmaps_api_key; } protected function mapGetDistances(Point $point, $outlets) { $client = new GuzzleClient(); // origins $origins_value = $point->getLatitude() . ',' . $point->getLongitude(); // destinations $dests = []; foreach ($outlets as $outlet) { $coord = $outlet->getCoordinates(); $dests[] = round($coord->getLatitude(),5) . ',' . round($point->getLongitude(), 5); } $dests_value = implode('|', $dests); // google maps url $maps_url = self::URL_DISTANCE_MATRIX; // parameters $gmaps_params = [ 'origins' => $origins_value, 'destinations' => $dests_value, ]; //error_log(print_r($gmaps_params, true)); // query google maps api $res = $client->request('GET', $maps_url, ['query' => $gmaps_params]); return $res->getBody(); } public function getClosestOutlets(Point $point, $limit, $time = false) { // get closest outlets based on st_distance function from db $query = $this->em->createQuery('SELECT o, st_distance(o.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Outlet o' . ($time ? ' WHERE :time BETWEEN o.time_open AND o.time_close' : '') . ' ORDER BY dist') ->setParameter('lat', $point->getLatitude()) ->setParameter('lng', $point->getLongitude()); if ($time) { $query->setParameter('time', $time); } $query->setMaxResults($limit); // error_log($query->getSql()); $result = $query->getResult(); $outlets = []; $final_data = []; foreach ($result as $row) { //error_log($row[0]->getName() . ' - ' . $row['dist']); $outlets[] = $row[0]; $final_data[] = [ 'outlet' => $row[0], 'db_distance' => $row['dist'], 'distance' => 0, 'duration' => 0, ]; } // get actual distance details with eta from google maps api $raw_res = $this->mapGetDistances($point, $outlets); $res = json_decode($raw_res, true); //error_log(print_r($res, true)); // check if status is ok if ($res['status'] != 'OK') { return $final_data; // error_log('status not ok'); } // check that the elements array is there if (!isset($res['rows'][0]['elements'])) { // error_log('no elements'); return $final_data; } foreach($res['rows'][0]['elements'] as $index => $gm_row) { // check status if (isset($gm_row['status']) && $gm_row['status'] != 'OK') { // error_log('element row status not ok'); continue; } // set distance if (isset($gm_row['distance']['value'])) $final_data[$index]['distance'] = $gm_row['distance']['value']; // set duration if (isset($gm_row['duration']['value'])) $final_data[$index]['duration'] = $gm_row['duration']['value']; } return $final_data; } }