How to find nearest users from Latitude and Longitude - laravel-5

I want to query nearby users, but I am getting this error:
SQLSTATE[42000]: Syntax error or access violation: 1582 Incorrect parameter count in the call to native function 'radians' (SQL: select *, ( 6367 * acos( cos( radians() ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians() ) + sin( radians() ) * sin( radians( latitude ) ) ) ) AS distance from `users` having `distance` < 25 order by `distance` asc)
My Query:
$user = User::where('id' , Auth()->user()->id)->first();
$latitude = $user->lat;
$longitude = $user->long;
$suggestions = User::select(DB::raw('*, ( 6367 * acos( cos( radians('.$latitude.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$longitude.') ) + sin( radians('.$latitude.') ) * sin( radians( latitude ) ) ) ) AS distance'))
->having('distance', '<', 25)
->orderBy('distance')
->get();

Related

Change order of main query according to Eloquent WhereHas Relationship

$collection = USER::whereHas('userLocations', function ($query) use ($filterId) {
$query->select(DB::raw('*, ( 6367 * acos( cos( radians('.$filterId['lat'].') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$filterId['lng'].') ) + sin( radians('.$filterId['lat'].') ) * sin( radians( latitude ) ) ) ) AS distance'))
->having('distance', '<', 10)
->orderBy('distance);
});
$collection = $collection->paginate(config('p.number_of_rows'));
return $collection;
I am trying to display user whose location range is from near to far. The orderBy doesn't seem to work. The user collection should be in the order of ascending distance.
Any advice would be appreciated?
Orderby in your query is using just for nested select. You should use join, if you wanna order by distance parameter. Try something like this:
UPD:
$raw = '( 6367 * acos( cos( radians(' . $filterId['lat'] . ') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(' . $filterId['lng'] . ') ) + sin( radians(' . $filterId['lat'] . ') ) * sin( radians( latitude ) ) ) )';
$collection = USER::select('users.*', DB::raw($raw . 'as distance'))
->join('userLocations', 'userLocations.user_id', '=', 'users.id')
->having(DB::raw($raw), '<', 10)
->orderBy($raw);

#Query return wierd error

im creating store locator using google map. im using springboot-starter-jpa
and put the harsvine formula to my repository service like below :
//this is store locator in km
#Query("SELECT p, (6371 * acos(cos( radians( :latitude ) ) * cos( radians( p.latitude ) ) * cos(radians( p.long ) - radians( :longitude )) +sin(radians(:latitude)) * sin(radians(p.latitude)))) AS distance FROM Location p HAVING distance < :radius ORDER BY distance LIMIT 25")
List<Location> getMeListPlaces(#Param("radius") long radius, #Param("latitude") long latitude, #Param("longitude") long longitude);
and the error that ive got is like below
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: HAVING near line 1, column 233 [SELECT p, (6371 * acos(cos( radians( :latitude ) ) * cos( radians( p.latitude ) ) * cos(radians( p.long ) - radians( :longitude )) +sin(radians(:latitude)) * sin(radians(p.latitude)))) AS distance FROM com.mashitah.model.Location p HAVING distance < :radius ORDER BY distance LIMIT 25]
am i doing some mistakes here? because i taking this formula for google map documentation here

Raw Query TO Laravel Eloquent

DB::select("SELECT *, ( 3959 * acos( cos( radians($lat) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians($lng) ) + sin( radians($lat) ) * sin( radians( lat ) ) )) AS distance FROM salons HAVING distance < 25 ORDER BY distance LIMIT 0 , 3");
this is my query which give me nearest ares according to lot and lng
I want syntax in laravel
A possible option with the Haversine query is using selectRaw and havingRaw.
$salons = Salon::select('salons.*')
->selectRaw('( 3959 * acos( cos( radians(?) ) *
cos( radians( lat ) )
* cos( radians( lng ) - radians(?)
) + sin( radians(?) ) *
sin( radians( lat ) ) )
) AS distance', [$lat, $lng, $lat])
->havingRaw("distance < 25")
->get();
You can pass a specific distance by modifying the havingRaw:
->havingRaw("distance < ?", [$radius])

Nearby stores in Laravel

i'm try to get neraby store in Laravel 5.1 I have geocoding parser that caluclate coorinate. But i have problem with haversine formulas. Basically i need that from table Aziende (Stores) given a lat, long e category passed trough url, fetch the nearby stores.
I try with this code:
$dove = Input::get('dove');
$categoria_id = Input::get('id_categoria');
// 4: check if any matches found in the database table
if (!empty($dove)) {
$response = \GoogleMaps::load('geocoding')->setParamByKey ('address', $dove)->get();
$response = json_decode($response, true);
$latitude = $response['results'][0]['geometry']['location']['lat'];
$longitude = $response['results'][0]['geometry']['location']['lng'];
$radius = '5';
$aziende = DB::table('aziende')
->select(
( 'lat * acos( cos( radians(50) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) )
+ sin( radians(37) ) * sin( radians( lat ) ) ) as distance') )->get();
} else {
$aziende = DB::table("aziende")->where('categoria', $categoria_id)->get();
}
?>
The following should work for you to implement the haversine formula in an SQL query. My answer is assuming you have a model setup to correspond with the database table "aziende".
$lat = floatval($response['results'][0]['geometry']['location']['lat']);
$lng = floatval($response['results'][0]['geometry']['location']['lng']);
$radius = 5;
$distance = DB::raw("*, ( 6371 * acos( cos( radians($lat) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians($lng) ) + sin( radians($lat) ) * sin( radians( lat ) ) ) ) AS distance");
$aziende = Aziende::select($distance)->orderBy('distance')->where('distance', '<=', $radius)->get();

Missing data when getting data from SQL using coordinates with this (Google) given algorithm

SELECT *, ( 3959 * acos( cos( radians('.$lat.') ) * cos( radians( latitude ) ) *
cos( radians( longitude ) -
radians('.$lng.') ) +
sin( radians('.$lat.') ) *
sin( radians( latitude ) ) ) ) AS distance ORDER BY distance LIMIT 0 , 20
This query has not failed me so far except for now.
I've tried playing with my database for a while and I found out that some data are not displayed that has a certain coordinate. All data I have on my database are displayed except for these two:
Coordinates that CANNOT be displayed using the algorithm:
Longitude: -80.155897 Latitude: 25.889437
Longitude: -80.175042 Latitude: 26.362099
Coordinates that CAN be displayed using the algorithm:
Longitude: -81.727737 Latitude: 30.164858
Longitude: -84.379269 Latitude: 33.786884
Longitude: -84.366086 Latitude: 33.823498
Longitude: -104.956408 Latitude: 39.727102
There's still a lot of data in my database that are working correctly except those two above. I can assure you that the coordinates are the problem because I did a bunch of testing. I'd love to debug this myself but I am very inexperienced with that certain algorithm, I am hoping that someone experienced in using it could help me out. I got that algorithm from a google map's developer page. I'll post it here when I find it. Lots of thanks!

Resources