Here I did something similar to what you are trying to do:
public function scopeNearest($query, Geo $geo, $miles = 25) { return $query ->select(DB::raw("*, ( 3959 * acos( cos( radians({$geo->lat}) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians({$geo->lng}) ) + sin( radians({$geo->lat}) ) * sin( radians( lat ) ) ) ) AS distance")) ->groupBy('id') ->having('distance', '<', $miles) ->orderBy('distance'); }
In this example, I had a separate model processing latitude and longitude coordinates, as well as address information called Geo
. You may not need this level of separation, so you can probably reorganize something like this:
public function scopeNearest($query, $lat, $lng, $miles = 25) { return $query ->select(DB::raw("*, ( 3959 * acos( cos( radians({$lat}) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians({$lng}) ) + sin( radians({$lat}) ) * sin( radians( latitude ) ) ) ) AS distance")) ->groupBy('id') ->having('distance', '<', $miles) ->orderBy('distance'); }
Remember that you need two points to calculate the distance. The model will be able to check the distance between two points using its latitude
and longitude
columns against the latitude and longitude provided in the query area as an argument.
You can put this in your car model and call it like this:
Vehicle::nearest($latitude, $longitude, 200);
This is untested for your use case, so I canβt guarantee that it will work out of the box, but I hope it should point you in the right direction.
source share