Ближайшие местоположения с широтой и долготой

У меня просто широта и долгота магазина, теперь я хочу узнать все магазины рядом с вами за 1 час езды или сказать на расстоянии 10 км.

У меня есть таблица,

Id, storeName, store_lat, store_lng 

Скажем, я выбрал lat и lng магазина 1, и я хочу узнать все близлежащие магазины. Как это сделать, используя php / mysql.

Я проверил много сообщений на SO, но когда я запускаю запрос, он все время возвращает 0 результатов.

Пожалуйста, помогите, спасибо!

Solutions Collecting From Web of "Ближайшие местоположения с широтой и долготой"

Предполагая, что вы получите $ lat и $ long как latitidue / longitude вашей начальной точки:

 $sql = 'SELECT *, (6371 * acos(cos(radians(' . $lat . ')) * cos(radians(latitude)) * cos(radians(longitude) - radians(' . $lng . ')) + sin(radians(' . $lat . ')) * sin(radians(latitude)))) AS distance from table_name WHERE distance < 10'; 

Один из подходов состоит в том, чтобы взять вашу входную партию lat / long, создать диапазон, а затем запросить все записи, которые попадают в этот диапазон:

 Distance = 0.1; // Range in degrees (0.1 degrees is close to 11km) LatN = lat + Distance; LatS = lat - Distance; LonE = lon + Distance; LonW = lon - Distance; ...Query DB with something like the following: SELECT * FROM table_name WHERE (store_lat BETWEEN LatN AND LatS) AND (store_lon BETWEEN LonE AND LonW) 

Запрос должен найти все, где хранимый лат меньше LatN и больше, чем LatS, и где сохраненный lon меньше LonE и больше LonW.

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

Используйте API карт с указаниями, чтобы добраться на расстоянии, если «как вороньи мухи» недостаточно хороши.

 SELECT * FROM `table` WHERE acos(sin(LATITUDE) * sin(`store_lat`) + cos(LATITUDE) * cos(`store_lat`) * cos(`store_lng` - (LONGITUDE))) * 6371 <= 1000; 

Просто замените LONGITUDE и LATITUDE.

Расстояние здесь в км – в настоящее время оно установлено в 1000. Это также можно изменить по мере необходимости.

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

 function inRange ( $lat1, $lng1, $lat2, $lng2, $range = 100 ) { return ( 6371 * acos( cos( deg2rad( $lat1 ) ) * cos( deg2rad( $lat2 ) ) * cos( deg2rad( $lng2 ) - deg2rad( $lng1 ) ) + sin( deg2rad( $lat1 ) ) * sin( deg2rad( $lat2 ) ) ) ) <= $range; } 

Это создает расстояние. Вы можете преобразовать его в запрос MySQL.