It's not really an answer to your question - but if you are doing this kind of thing you might be interested in Postgres's GIS facilities : http://postgis.net/
Haversine query using Eloquent
Hi, I need some help with eloquent relationships. I have a 'User' table having two columns: 'latitude' and 'longitude' A 'User' is owner of many 'Products', so in my 'Product' model I have:
public function owner()
{
return $this->belongsTo('App\User', 'user_id');
}
I need a method that returns all the products of the owners that are positioned within a certain distance, which I calc using the params lat, lng, and radius, using the haversine formula. I could do it using the query builder:
public static function findByLatLng( $lat, $lng, $radius = 1) {
$products = DB::table('products')
->select('products.*', DB::raw("( 6371 * acos( cos( radians($lat) ) *
cos( radians( latitude ) )
* cos( radians( longitude ) - radians($lng)
) + sin( radians($lat) ) *
sin( radians( latitude ) ) )
) AS distance"))
->join('users', function($join)
{
$join->on('products.user_id', '=', 'users.id');
})
->having("distance", "<", $radius)
->get();
}
My problem is that I need the same but returning a Eloquent Model, to use in my views...I'm trying to do:
$products = Product::with(['owner' => function($query) use ($latitude, $longitude, $radius) {
$query->selectRaw('( 6371 * acos( cos( radians(?) ) *
cos( radians( latitude ) )
* cos( radians( longitude ) - radians(?)
) + sin( radians(?) ) *
sin( radians( latitude ) ) )
) AS distance', [$latitude, $longitude])
->havingRaw("distance < ?", [$radius]);
}])->get();
But I get the following sql error: 'Invalid parameter number' I appreciate any help!
I've just solved!
$products = Product::select('products.*')
->join('users', function($join)
{
$join->on('products.user_id', '=', 'users.id');
})
->selectRaw('( 6371 * acos( cos( radians(?) ) *
cos( radians( latitude ) )
* cos( radians( longitude ) - radians(?)
) + sin( radians(?) ) *
sin( radians( latitude ) ) )
) AS distance', [$latitude, $longitude, $latitude])
->havingRaw("distance < ?", [$radius])
->get();
Thanks!
Please or to participate in this conversation.