%PDF- %PDF-
Direktori : /home/graphicd/public_html/vebto/vendor/teamtnt/tntsearch/src/ |
Current File : /home/graphicd/public_html/vebto/vendor/teamtnt/tntsearch/src/TNTGeoSearch.php |
<?php namespace TeamTNT\TNTSearch; use PDO; use TeamTNT\TNTSearch\Indexer\TNTGeoIndexer; use TeamTNT\TNTSearch\Support\Collection; class TNTGeoSearch extends TNTSearch { protected $earthRadius = 6371; /** * Distance is in KM */ public function findNearest($currentLocation, $distance, $limit = 10) { $startTimer = microtime(true); $res = $this->buildQuery($currentLocation, $distance, $limit); $stopTimer = microtime(true); return [ 'ids' => $res->pluck('doc_id'), 'distances' => $res->pluck('distance'), 'hits' => $res->count(), 'execution_time' => round($stopTimer - $startTimer, 7) * 1000 ." ms" ]; } public function buildQuery($currentLocation, $distance, $limit) { $query = " SELECT doc_id, longitude, latitude, :CUR_sin_lat * sin_lat + :CUR_cos_lat * cos_lat * (cos_lng * :CUR_cos_lng + sin_lng * :CUR_sin_lng) AS distance FROM locations AS l JOIN ( SELECT :latpoint AS latpoint, :longpoint AS longpoint, :radius AS radius, 111.045 AS distance_unit ) AS p WHERE l.latitude BETWEEN p.latpoint - (p.radius / p.distance_unit) AND p.latpoint + (p.radius / p.distance_unit) AND l.longitude BETWEEN p.longpoint - (p.radius / (p.distance_unit * :CUR_cos_lat)) AND p.longpoint + (p.radius / (p.distance_unit * :CUR_cos_lat)) ORDER BY distance DESC LIMIT :limit"; $stmtDoc = $this->index->prepare($query); $cur_lat = $currentLocation['latitude']; $cur_lng = $currentLocation['longitude']; $CUR_cos_lat = cos($cur_lat * pi() / 180); $CUR_sin_lat = sin($cur_lat * pi() / 180); $CUR_cos_lng = cos($cur_lng * pi() / 180); $CUR_sin_lng = sin($cur_lng * pi() / 180); $stmtDoc->bindValue(':latpoint', $cur_lat); $stmtDoc->bindValue(':longpoint', $cur_lng); $stmtDoc->bindValue(':radius', $distance); $stmtDoc->bindValue(':CUR_cos_lat', $CUR_cos_lat); $stmtDoc->bindValue(':CUR_sin_lat', $CUR_sin_lat); $stmtDoc->bindValue(':CUR_cos_lng', $CUR_cos_lng); $stmtDoc->bindValue(':CUR_sin_lng', $CUR_sin_lng); $stmtDoc->bindValue(':limit', $limit); $stmtDoc->execute(); $locations = new Collection($stmtDoc->fetchAll(PDO::FETCH_ASSOC)); $locations = $locations->map(function ($location) use ($distance) { $location['distance'] = acos($location['distance']) * $this->earthRadius; if ($location['distance'] <= $distance) { return $location; } }); return $locations; } public function getIndex() { $indexer = new TNTGeoIndexer; $indexer->inMemory = false; $indexer->setIndex($this->index); return $indexer; } }