2017-02-01 5 views
0

У меня возникла проблема при разработке этого.Выполнение запроса на расстояние haversine на основе lng и lat

У меня есть эта функция реализована сфера, что я бегу на модели как

листинга :: ближайший ($ лат, $ LNG) -> постраничной (5);

public function scopeClosest($query, $lat, $lng, $distance = 0, $units = 'km') 
{ 

    switch ($units) { 
     case 'miles': 
      //radius of the great circle in miles 
      $gr_circle_radius = 3959; 
     break; 
     case 'km': 
      //radius of the great circle in kilometers 
      $gr_circle_radius = 6371; 
     break; 
    } 

    return $query->selectRaw(
     '*, ('.$gr_circle_radius.' * acos(cos(radians('.$lat.')) * cos(radians(lat)) * cos(radians(lng) - radians('.$lng.')) + sin(radians('.$lat.')) * sin(radians(lat)))) AS distance' 
    )->havingRaw("distance < ?", [10]); 

} 

Однако я бегу в эту ошибку, что я сейчас не как исправить

SQLSTATE [42S22]: Column не найдено: 1054 Unknown столбца 'расстояние' в 'имеет пункт' (SQL: выберите COUNT (*) в качестве заполнителя из listings имеющих расстояние < 10)

кажется, что Laravel запущен 2 запросов, это то, как это выглядит, если я не использую havingRaw()

array:2 [▼ 
    0 => array:3 [▼ 
    "query" => "select count(*) as aggregate from `listings`" 
    "bindings" => [] 
    "time" => 0.48 
    ] 
    1 => array:3 [▼ 
    "query" => "select *, (3959 * acos(cos(radians(37)) * cos(radians(lat)) * cos(radians(lng) - radians(-122)) + sin(radians(37)) * sin(radians(lat)))) AS distance from `listings` limit 5 offset 0" 
    "bindings" => [] 
    "time" => 0.97 
    ] 
] 

Когда я использую hasRaw, кажется, что laravel применяет его к первому запросу, и, конечно же, он не сработает. Но почему он применяет его к первому запросу, а не к второму?

+0

, что это ваше требование, пожалуйста, вы можете объяснить немного? Вы хотите получить ближайшие 5 местоположений на основе заданной широты и долготы? – sumit

+0

5 просто пример, мне нужно это разбито на страницы –

+0

[Вы можете получить мой ответ здесь] (http://stackoverflow.com/a/37877412/1206267). – Ohgodwhy

ответ

1

Это то, что я сделал в моем случае. Мне нужно запросить расстояние, которое было в радиусе 5 км. Я использовал whereRaw вместе с paginate

$vtl = VehicleTrackerLog::whereRaw("(
            111.1111 
            *DEGREES(ACOS(COS(RADIANS('-33.873415')) 
            * COS(RADIANS(lat)) 
            * COS(RADIANS('151.227538' - lng))+ SIN (RADIANS('-33.873415'))   
            * SIN(RADIANS(lat))))<=5)" 
            )->paginate(5); 

Если вы хотите в Miles просто умножить на 69.041236 вместо 111.111

+0

Я еще не пробовал, но он отлично выглядит , чтобы также предлагать мили в качестве единицы, что я могу заменить 111.1111? –

+0

Для миль, разделите км на 1.609344 – sumit

+0

так «<= 5/1.609344»? –