в базе есть объекты с полями широта\долгота нужно получить текущее положение юзера и отсортировать объекты от ближайших к дальним как лучше такое сделать?
Это зависит от того, с чем имеете дело. Если просто сайтом, то мб GEOIP вам поможет. Но там точность, кхм, в городах измеряется. Выбрать из базы по условию "широта < $широта_пользователя + N_градусов" AND "широта > $широта_пользователя - N_градусов" AND то же самое с долготой. Получите выборку объектов в квадрате N*N от указанной точки. Ну а там уж либо на стороне сервера сортируйте, вычисляя расстояния по формуле, либо через SQL и хитрым ORDER BY..
Клиент может и сам не знать своего местоположения. Проще конечно же по IP, но недостоверно для мобильных клиентов.
@vikrorpert и дальше что? 1) юзер может банально сказать "да пошел ты" - ответа не придет. 2) у юзера может отключена служба чуть более точного геопозиционирования (гпс) чем через триангуляцию гсм - ответ будет содержать неверные данные с разбросом в несколько километров. 3) у юзера включена счбтг (гпс) ччт гсм, но облачность висит плотная и девайс не видит спутников. Ответа может вообще не придти, если нет альтернативы в виде гсм, или придти неточным силами пары спутников или гсм.
теперь не пойму как быть с выборкой "широта < $широта_пользователя + N_градусов" AND "широта > $широта_пользователя - N_градусов" что за N_градусов? и как потом отсортировать выбранные объекты от ближайшего к дальним?
Н-градусов это максимальная дистанция относительно координаты пользователя. У тебя есть одна точка, она имеет координаты. Другая точка тоже имеет координаты. С учетом прямоугольности координатной системы - расстояние между точками условно равно гипотенузе треугольника, катеты которого просто параллельны осям координатной системы. "Условно равно" потому что Земля не плоская и не идеальный шар. У каждого градуса-минуты-секунды своя метрическая длина в зависимости от широты. Ну это детали. Через абсолютные значения дельт соответствующих координат получаешь длину гипотенузы (не в "градусах"), потом сортируешь по этим длинам - вот тебе и от ближнего к дальним.
с градусом понятно.по сути чем больше градус тем больше объектов выберется? а что насчет сортировки?что почитать?
@vikrorpert , вот теперь ты меня начал пугать. Следующий вопрос будет, случайно, не "что такое переменная"? Что с тобой случилось, ты за 6 лет начал учиться программировать в обратную сторону? О_о у тебя же не было таки проблем. Сортировка - это сортировка. В пыхе даже нативные средства для оной есть. На край - можно написать свою. Если объектов не тысячи, то сойдет даже "пузырек", который любой программист должен уметь написать самостоятельно с закрытыми глазами с нуля за 15 минут.
тебе не всё равно? выбери тех, кто попадает в квадрат. Потом уже в пхп посчитай расстояние по прямой, это ж быстрая операция, шестой класс школы (или какой там). Отсортируешь по удалённости и готово.
вот сам запрос Код (Text): SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
На скорость это не повлияет ведь? Только на читаемость? У самого сейчас такой запрос в проекте, не знаю, как будет под большой нагрузкой, но на локалке выбирает с нормальной скоростью. В базу специально нагнал 5000 тестовых записей - думаю, в реале не скоро столько организций наберёт проект. Хотя может позже нафигачу ещё тысяч 10000, пока хватает и так
Тут ничего сказать не могу за скорость. Не приходилось на практике с такими выражениями работать. Просто программерская логика подсказывает, что функция должна быть функцией, а запрос должен быть запросом. И что в запросе спрашивать надо function(lng,lat), а не кучу раз lng и lat, но каждый раз по-своему. Запрос должен получить условия и вернуть результат. Логикой обработки и выражениями должен заниматься либо вопрощающий сервер, либо код, обернутый в хранимую процедуру. Опять же, из вопроса скорости - если на БД будет предполагаться большая нагрузка, то я бы, все же, вынес вычисления на сторону PHP. Если в будущем будет иметь место масштабирование, с последующим выносом БД на отдельный физический сервер, то лучше тратить процессорное время этого сервера на чисто выборки данных, без обработки. Более того, если в связку PHP<->MySQL будет добавлено третье звено, какой-нибудь мемкеш, то схема с вычислениями на стороне БД накроет эту затею тазом. Потому что кэшировать в оперативке координаты статичных объектов - вообще как нехрен делать. А вот кэшировать в оперативке расчетные значения, полученные на основании динамических данных, уникальных для каждого пользователя...это, я бы сказал, и глупо, и бессмысленно. Есть такой термин "холодный кэш". Это когда кэширование настроено, но кэш еще пустой, и, покуда он пустой, то каждый запрос к себе проксирует в БД и, в итоге, портит производительность и мешается, потому что не генерирует ничего, кроме оверхедов. Но, в ходе работы кэш постепенно прогревается, наполняясь актуальными данными и процент пробросов к БД снижается. В итоге мы получаем "прогретый" или "горячий" кэш. Кэш, у которого экономия на запросах к БД превышает внутренний оверхед, и в общем ускоряет работу системы в разы. Это именно то, чего пытаются добиться, устанавливая его. Так вот, в случае с расчетами на стороне БД у нас будет "вечнохолодный кэш". Его будет невозможно прогреть.
В прошлом проекте я так и сделал, но в новом мне нужно находить ближайшие объекты к координатам, введённым пользователем, а это выборка, и выборка с формулой. И вроде база не сильно страдает от этой формулы.
А я простыню выше для чего написал? Ёлки-палки.. Хочешь сказать, у тебя сложная формула в WHERE? --- Добавлено --- Просто у @vikrorpert формулы в WHERE нет, так что для него моя простыня актуальна. Для тебя, наверное нет.