Упорядочить по широте и долготе - PullRequest
0 голосов
/ 04 июня 2018

Я работаю над проектом, который использовался для размещения рекламы, этот проект основан на локализации, поэтому, когда пользователь публикует свои объявления, приложение определяет его позицию, поэтому, когда другие люди интересуются его объявлениями, они могут найти его на Картах.Проблема в том, что я хочу заказать эти объявления от ближайшего к ближайшему, используя широту и долготу рекламы, а также широту и долготу того, кто использует приложение

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)

Если кто-то может помочь, это будет большим удовольствием

Ответы [ 3 ]

0 голосов
/ 04 июня 2018

Как оказалось, я работал над некоторыми проектами, которые делали очень похожие вещи, и собрал несколько вспомогательных функций, которые могут помочь.Существует алгоритм, который вычисляет расстояния между двумя наборами координат, поэтому эти помощники либо выполнят это за вас, либо создадут 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 голосов
/ 04 июня 2018

Попробуйте использовать это:

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 голосов
/ 04 июня 2018
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;}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...