按纬度和经度排序

问题描述 投票:1回答:3

我正在研究一个用于发布广告的项目,该项目基于本地化,因此当用户发布他的广告时,应用程序会检测他的位置,这样当其他人对他的广告产生兴趣时,他们可以在地图上找到他。问题是,我想使用广告的纬度和经度,以及使用该应用的人的经度和纬度,从最近的广告到最远的广告订购这些广告

public function get_searched(Request $request){
    $annonce =DB::table('annonces')
    ->where('nomAnnonce','like','%'.$request->input("nomAnnonce").'%')
    ->orderby(((('latitude'- $request->input("lat"))*('latitude'-$request->input("lat"))) + (('longitude' - $request->input("lon"))*('longitude' - $request->input("lon")))), 'ASC')
    ->get();
    echo $annonce;}

这就是我能做的所有事情,这给了我一个错误的结果:

SQLSTATE[42S22]: Column not found: 1054 Champ '1359.309643206' inconnu dans 
order clause (SQL: select * from `annonces` where `nomAnnonce` like %P% 
order by `1359`.`309643206` asc)

如果有人可以帮助那将是一件非常愉快的事情

php laravel sql-order-by latitude-longitude
3个回答
0
投票

试试这个:

public function get_searched(Request $request){
    $annonces = DB::table("annonces")
    ->where('nomAnnonce','like','%'.$request->input("nomAnnonce").'%')
    ->orderBy(DB::raw("3959 * acos( cos( radians({$request->input('lat')}) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-{$request->input('lon')}) ) + sin( radians({$request->input('lat')}) ) * sin(radians(latitude)) )"), 'ASC')
    ->get()
    dd($annonces);
}

这种方法使用余弦球面法来获得距离


0
投票

碰巧的是,我已经完成了一些做类似事情的项目,并且组合了几个可以提供帮助的辅助函数。有一种算法可以计算两组坐标之间的距离,因此这些助手将为您执行该算法,或者生成在数据库中执行它所需的SQL。 distance_sql()听起来像你正在寻找的。通过使查询执行工作而不是脚本,您可以在结果集返回之前对结果集进行排序和分页。我建议在你的模型中放置一个query-scope方法来调用它。

如果您还没有这样做,请创建一个app/helpers.php文件并将其添加到您的composer.json文件中,然后运行composer install

"autoload": {
    "files": [
        "app/helpers.php",
        ...
    ],
    ...
},
...

最后,将它们放在你的helpers.php中:

if (!function_exists('distance')) {
    /**
     * Calculate the distance between two sets of coordinates
     *
     * @param float $latitude1
     * @param float $longitude1
     * @param float $latitude2
     * @param float $longitude2
     * @param float $padding
     * @return float
     */
    function distance($latitude1, $longitude1, $latitude2, $longitude2, $padding = 0.0)
    {
        $earthRadiusInMiles = 3959;

        $latitude1 = deg2rad($latitude1);
        $latitude2 = deg2rad($latitude2);
        $longitude1 = deg2rad($longitude1);
        $longitude2 = deg2rad($longitude2);

        $miles = $earthRadiusInMiles * acos(
            cos($latitude1) * cos($latitude2)
            * cos($longitude2 - $longitude1)
            + sin($latitude1) * sin($latitude2)
        );

        $miles += $padding * $miles;

        return round($miles, 3);
    }
}

if (!function_exists('distance_sql')) {
    /**
     * Generate the SQL needed to calculate the distance between two sets of coordinates
     *
     * @param float|string $latitude1
     * @param float|string $longitude1
     * @param float|string $latitude2
     * @param float|string $longitude2
     * @param float $padding
     * @return string
     */
    function distance_sql($latitude1, $longitude1, $latitude2, $longitude2, $padding = 0.0)
    {
        $earthRadiusInMiles = 3959;

        $latitude1 = 'RADIANS('.DB::connection()->getPdo()->quote($latitude1).')';
        $latitude2 = "RADIANS($latitude2)";
        $longitude1 = 'RADIANS('.DB::connection()->getPdo()->quote($longitude1).')';
        $longitude2 = "RADIANS($longitude2)";

        $sql = "$earthRadiusInMiles * ACOS("
            . "COS($latitude1) * COS($latitude2)"
            . " * COS($longitude2 - $longitude1)"
            . " + SIN($latitude1) * SIN($latitude2))";

        $sql .= " + $padding * $sql";

        return $sql;
    }
}

0
投票
public function get_searched(Request $request){
    $annonce =DB::table('annonces')
    ->select('*', 
    DB::raw(((('latitude'- $request->input("lat"))*('latitude'-$request->input("lat"))) + (('longitude' - $request->input("lon"))*('longitude' - $request->input("lon")))) 
            as 'distance'
            )
    ->where('nomAnnonce','like','%'.$request->input("nomAnnonce").'%')
    ->orderby('distance', 'ASC')
    ->get();
    echo $annonce;}
© www.soinside.com 2019 - 2024. All rights reserved.