Last active
January 19, 2021 14:44
-
-
Save fhferreira/9081607 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; | |
} |
Excelent!! Thank you.
hello if i have the table places and my eloquent model is Place how do i use this?
For me following is not working:
instead of ->get(); change it to ->paginate(15)
Thank you
Call to undefined method Illuminate\Database\Query\Builder::haversine() wtf im so fucking noob
works like a charm!
$results = $mapHelpers->haversine(new Place(), $user->place->lat, $user->place->lng, 1000, 'kilometers', ['places.*']);
However I would like to know how to use this if I want to get the "nearest users" and the user table itself does not contain lat/lng values but instead there is a relation between User and Place on place_id field
How would I use this with such a relation in place?
How can I use paginate()
How can I use paginate()
change the ->get() for ->paginate(15) it should works
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works like charm! Thank you.