【问题标题】:Order by latitude and longitude按经纬度排序
【发布时间】:2018-11-13 20:51:42
【问题描述】:

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

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


    【解决方案1】:

    试试这个:

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

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

    【讨论】:

    • thnx 先生,但是有语法错误,意外的 'DB' (T_STRING) 可以帮忙
    • @aymenmedjader 你一定错过了;
    • thnnnnnnnnnnnnnnx 先生 thnx 我现在正在哭泣。谢谢你,我已经完成了我的项目,谢谢,我很感激
    【解决方案2】:
    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;}
    

    【讨论】:

    • thnx 先生,但有语法错误,意外'因为'我没有找到原因!一些帮助
    • 对不起,我会解决的
    • 它仍然是相同的意外'as',我认为在这种情况下,php 作为查询构建器并不知道
    【解决方案3】:

    碰巧,我参与了一些做非常相似的事情的项目,并把一些可以提供帮助的辅助函数放在一起。有一种算法可以计算两组坐标之间的距离,因此这些助手将为您执行该算法,或者生成在数据库中执行它所需的 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;
        }
    }
    

    【讨论】:

    • 但是如何调用这个函数并从我的 finction 'get_searched' 中使用它,这对我来说是新的,你能帮忙吗!!
    • 基于Request对象的存在,我认为get_searched是Controller方法?您在这里需要的是一个模型类。见laravel.com/docs/5.6/eloquent#eloquent-model-conventions。尽可能使用 Model 类而不是 DB Facade,尤其是对于像这样的简单查询。 Eloquent 模型可以提供很多 QueryBuilder (DB) 本身无法提供的好处。不过,关于如何使用 Eloquent 的进一步详细说明将是一个更大的讨论,而且背后已经有大量文档,但这就是你应该开始的地方。
    • 作为旁注,文档中没有明确说明的几个专业提示可能会在以后让您免于心痛,因为听起来您还不熟悉 Eloquent。 1) 一些方法调用实际上会通过一个神奇的__call() 方法并实际上返回一个 QueryBuilder 对象而不是一个 Eloquent 模型或集合。 join() 就是其中之一。很高兴知道这一点。 2) Eager-loads,with()load(),实际上不会产生 JOIN 查询。它们生成全新的查询,仅在从主查询返回的 Id 上利用 IN()
    猜你喜欢
    • 1970-01-01
    • 2013-05-04
    • 2014-11-06
    • 1970-01-01
    • 2019-09-23
    • 2013-06-28
    • 1970-01-01
    • 2013-09-09
    • 2021-10-18
    相关资源
    最近更新 更多