У меня просто широта и долгота магазина, теперь я хочу узнать все магазины рядом с вами за 1 час езды или сказать на расстоянии 10 км.
У меня есть таблица,
Id, storeName, store_lat, store_lng
Скажем, я выбрал lat и lng магазина 1, и я хочу узнать все близлежащие магазины. Как это сделать, используя php / mysql.
Я проверил много сообщений на SO, но когда я запускаю запрос, он все время возвращает 0 результатов.
Пожалуйста, помогите, спасибо!
Предполагая, что вы получите $ 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.