-
-
Save vesper8/d4502de7d883b435688b8f9cda54f60d to your computer and use it in GitHub Desktop.
Haversine Method for model Laravel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* find the n closest locations | |
* @param Model $query eloquent model | |
* @param float $lat latitude of the point of interest | |
* @param float $lng longitude of the point of interest | |
* @param float $max_distance distance in miles or km | |
* @param string $units miles or kilometers | |
* @param Array $fiels to return | |
* @return array | |
*/ | |
public static function haversine($query, $lat, $lng, $max_distance = 25, $units = 'miles', $fields = false ) | |
{ | |
if(empty($lat)){ | |
$lat = 0; | |
} | |
if(empty($lng)){ | |
$lng = 0; | |
} | |
/* | |
* Allow for changing of units of measurement | |
*/ | |
switch ( $units ) { | |
case 'miles': | |
//radius of the great circle in miles | |
$gr_circle_radius = 3959; | |
break; | |
case 'kilometers': | |
//radius of the great circle in kilometers | |
$gr_circle_radius = 6371; | |
break; | |
} | |
/* | |
* Support the selection of certain fields | |
*/ | |
if( ! $fields ) { | |
$fields = array( 'users.*', 'users_profile.*', 'users.username as user_name' ); | |
} | |
/* | |
* Generate the select field for disctance | |
*/ | |
$distance_select = sprintf( | |
" | |
ROUND(( %d * acos( cos( radians(%s) ) " . | |
" * cos( radians( lat ) ) " . | |
" * cos( radians( lng ) - radians(%s) ) " . | |
" + sin( radians(%s) ) * sin( radians( lat ) ) " . | |
" ) " . | |
") | |
, 2 ) " . | |
"AS distance | |
", | |
$gr_circle_radius, | |
$lat, | |
$lng, | |
$lat | |
); | |
$data = $query->select( DB::raw( implode( ',' , $fields ) . ',' . $distance_select ) ) | |
->having( 'distance', '<=', $max_distance ) | |
->orderBy( 'distance', 'ASC' ) | |
->get(); | |
//echo '<pre>'; | |
//echo $query->toSQL(); | |
//echo $distance_select; | |
//echo '</pre>'; | |
//die(); | |
// | |
//$queries = DB::getQueryLog(); | |
//$last_query = end($queries); | |
//var_dump($last_query); | |
//die(); | |
return $data; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment