Haversine和Laravel

3
我正在尝试通过距离参数(以英里为单位设置)将用户位置(通过URL中的参数发送)与我的数据库中的offers.offer_lat和offers.offer_long进行比较。目前,我已经在查询作用域中拥有此功能,因为用户将使用距离过滤API结果,但是很难使用DB :: raw将发现在线上的许多解决方案移植到Laravel的查询构建器中。我发现了一些用于计算haversine的函数,但我不知道如何使用它们。这里是一个例子:https://gist.github.com/fhferreira/9081607。如果有帮助,将不胜感激!:)谢谢。

你已经掌握了解决方案,将你自己链接中找到的函数放入控制器中并使用它。 - phaberest
2个回答

13

所以你不需要那个代码片段中的所有冗余代码,相反,你可以使用以下公式:

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;
}

假设您从用户那里传递了latitudelongitude。此外,如果您不想半径为1,可以传入第三个参数并提供自定义半径。

当然,我们假设这是针对Offer模型的。根据需要更改您的命名约定。


1
对于任何发现此问题的人。如果您遇到非分组字段错误,请参考以下链接 - https://dev59.com/3lkT5IYBdhLWcg3wG74_ - RushVan

3
在Laravel中,Haversine的工作方式如下:
                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();

您将获得一个按距离排序的点集合(最近的优先)

使用了带有参数latlng的旅行模型。参数distance由原始查询添加。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接