Получить все профили в широте / дальности (laravel — laravel-mysql-spatial)

#php #mysql #laravel #eloquent #spatial-query

#php #mysql #laravel #красноречивый #пространственный запрос

Вопрос:

Я пытаюсь создать форму в своем приложении laravel, чтобы получить профили всех пользователей, которые находятся в пределах или в x км вокруг одного выбранного города из моей таблицы городов. Я пытаюсь использовать laravel-mysql-spatial, который использует функцию mysql ST_DISTANCE_SPHERE, но не могу по-настоящему разобраться в необходимых красноречивых вещах

В основном каждый профиль связан с определенным городом, в котором есть поле location POINT(), но я хотел бы иметь возможность возвращать все профили, которые находятся на расстоянии x км от города, который я выбираю через форму.

Модель пользователя:

 public function profile() {
    return $this->hasOne('AppProfile');
}
 

Модель профиля:

 public function user() {
    return $this->belongsTo('AppUser');
}
    
public function city() {
    return $this->belongsTo('AppCity');
}
 

Модель города:

 protected $spatialFields = [
    'location'
];

public function profiles() {
    return $this->hasMany('AppProfile');
}
 

laravel-mysql-spatial имеет следующую функцию для вычисления расстояния между 2 точками

 distanceSphere($point, $point, $range);
 

но не могу понять, как / куда его подключить, чтобы получить желаемый результат

 User::with(['reviews', 'profile', 'profile.media','profile.city', 'categories'])->where(['type' => 'mester'])
 

это получает моих пользователей / профили

 if (!empty($request->get('city_id')))
    $users_query->whereHas('profile', function (Builder $query) use ($request) {
        $query->where(['city_id' => $request->get('city_id')]);
    });
 

и я использую это для фильтрации по городу при выборе города.

 $request->input('range')
 

я получаю это через ввод диапазона в качестве расстояния

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

Комментарии:

1. Не уверен, в чем здесь вопрос. Если вам нужно получить все города в пределах заданного расстояния, вы бы сделали City::distanceSphere('location', $point, $distance) , где $point будет Geometry какое-то значение и расстояние до числа (я думаю). Это только из взгляда на github.com/grimzy/laravel-mysql-spatial

2. я выяснил, как работает функция… я не могу понять, как подключить функцию в моих красноречивых запросах, чтобы получить желаемый результат. вероятно, это скорее красноречивая функция / mysql, чем вопрос mysql-spatial.

Ответ №1:

Я думаю, вы можете использовать whereHas в профиле.город вместо профиля:

 $otherCityPoint = City::where('id', $request->city_id)->value('location');
$users_query->whereHas('profile.city', function (Builder $query) use ($request,$otherCityPoint) {
    $query->distanceSphere('location', $otherCityPoint, $request->input('range') * 1000);  // 3 arg is meters
});
 

Это должно вернуть всех пользователей, у которых есть профили, в которых есть город, который находится на заданном расстоянии.

Комментарии:

1. я сам зашел так далеко.. как бы мне передать 2-ю точку функции? прямо сейчас я делаю $query-> distanceSphere(‘location’, новая точка (0,0, 4326), $request-> input(‘range’) * 10000000000); и, как и ожидалось, я получаю все в таблице