Haversine and Laravel

笑着哭i 提交于 2020-01-23 12:52:38

问题


I'm attempting to compare a users location (Sent via params in the URL) to offers.offer_lat and offers.offer_long (in my DB) by a distance argument (set in miles)

I'm going crazy right now, a lot of solutions I have found online are proving hard to port over to laravels query builder using DB::raw, I currently have the function in a query scope as the user will be filtering API results using distance, no luck though!

I found some functions online for calculating the haversine but I have no idea how to use them. Here's an example: https://gist.github.com/fhferreira/9081607

Any help would be massively appreciated! :)

Thanks


回答1:


So you don't need all the bloat that is in that gist, instead, you can use the following formulae:

public function get_offers_near($latitude, $longitude, $radius = 1){

    $offers = Offer::select('offers.*')
        ->selectRaw('( 3959 * acos( cos( radians(?) ) *
                           cos( radians( offer_lat ) )
                           * cos( radians( offer_long ) - radians(?)
                           ) + sin( radians(?) ) *
                           sin( radians( offer_lat ) ) )
                         ) AS distance', [$latitude, $longitude, $latitude])
        ->havingRaw("distance < ?", [$radius])
        ->get();

    return $offers;
}

This assumes that you pass in the latitude and longitude from your user. Also, if you don't want the radius to be 1, you can pass in the 3rd argument and provide a custom radius.

And of course, we're assuming that this is for a model of Offer. Change your naming convention where required.




回答2:


Haversine in Laravel works in this way:

                Travel::select(
                    DB::raw("travels.*,
                          ( 6371 * acos( cos( radians($lat) ) *
                            cos( radians( lat ) )
                            * cos( radians( lon ) - radians($lng)
                            ) + sin( radians($lat) ) *
                            sin( radians( lat ) ) )
                          ) AS distance"))
                ->orderBy('distance', 'asc')
                ->get();

and you will get a collection of points ordered by distance (nearest first)

Was used travel model with params lat and lng. parameter distance is added by the raw query



来源:https://stackoverflow.com/questions/35467774/haversine-and-laravel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!