myks92
@myks92
Нашёл решение — пометь вопрос ответом!

Как выгрузить записи по ближайшим городам определенного радиуса?

Здравствуйте. У меня есть список мероприятий в базе данных с названием города и полного адреса. Как мне выгрузить из базы данных все мероприятия в радиусе, например, 500км от текущего пользователя? И как получить координаты пользователя, если используем вычисления по координатам?

Как это грамотно реализовать?
  • Вопрос задан
  • 228 просмотров
Решения вопроса 1
kawabanga
@kawabanga
1) использовать яндекс АПИ, чтобы конвертировать адрес в координаты. (геокодер) проходим по бэкенду и конвертируем адреса. потом конвертируем уже при добавлении нового мероприятия. Заметьте, это раньше нарушало лицензионное соглашение яндекса.
2) Смотрим в сторону POINT. Наблюдаем за Spatial index если данных/пользователей много(mysql 5.7.19+)
3) читаем доки по гис функциям. ST_Distance_Sphere . В yii2 есть пара библиотек для работы с point.
4) грубо вычисляем город пользователя и координаты - ip-api.com
5) точно вычисляем место пользователя, используя гугл мапс и систему определения локации. работает точнее, но заморочек больше.

По сути, если что-то не получается, можно ограничиться конвертацией адресов в координаты, использовать не радиус, а квадрат вокруг пользователя, пусть даже не точный.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
PavelBlum
@PavelBlum
Web developer
Скорее всего нужно юзать js, или дописывать базу с городами с полем "радиус" и это поле должно иметь значение которое откуда-то отсчитывается ( например у вас есть магазин и это 0, а от него ведете отсчет до складов и у складов будет значение радиуса равно расстоянию от магазина до склада ), но это путь со статичной точкой, для не статичной я бы использовал js.
Ответ написан
@Sunsetboy
senior web developer, IT entrepreneur
Если у вас есть координаты пользователя и координаты мероприятия, запрос будет примерно таким (код на Yii1, но идея должна быть понятна)

$this->lat и $this->lng - широта и долгота текущего пользователя
$radius - радиус в километрах
lat, lng - поля с широтой и долготой объектов в базе (в моем случае городов)

$criteria = new CDbCriteria();
$criteria->select = "*, SQRT(
POW(110.6* (lat - " . $this->lat. "), 2) +
POW(110.6 * (" . $this->lng. " - lng) * COS(lat / 57.3), 2)) AS distance";
$criteria->having = "distance < " . $radius;
$towns = Town::model()->findAll($criteria);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы