У меня есть база данных со списком магазинов с широтами и долготами каждого. Поэтому, основываясь на текущем (lat, lng) месте, которое я вводил, я хотел бы получить список предметов из тех, которые находятся в радиусе радиусом 1 км, 5 км и т. Д.?
Каким должен быть алгоритм? Мне нужен PHP-код для самого алгоритма.
Вам просто нужно использовать следующий запрос.
Например, у вас есть широта ввода и долгота 37 и -122 в градусах. И вы хотите искать пользователей в радиусе 25 миль от текущей заданной широты и долготы.
SELECT item1, item2, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance FROM geocodeTable HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;
Если вы хотите расстояние поиска в км, замените 3959 на 6371 в запросе выше.
Вы также можете сделать это, как:
Выберите все широту и долготу
Затем вычислите расстояние для каждой записи.
Вышеупомянутый процесс можно выполнить с помощью множественного перенаправления.
Для оптимизации запроса вы можете использовать хранимую процедуру.
И это также может помочь вам.
Вы должны выбрать базу данных, которая пространственно включена как mysql или postgresql, а затем вы можете использовать некоторые из готовых функций, которые они предоставляют. Иначе, если вы хотите сделать это вручную, проверьте это для головок.
Если вы ищете PHP-код для вычисления расстояния между двумя наборами координат, вот класс, который я адаптировал, который рассчитает расстояние в километрах. Однако, если вы используете базу данных, я бы посоветовал вам изучить, может ли ваша база данных работать с пространственными вычислениями (я знаю, что SQL Server и MySQL, с моей точки зрения).
Вот интересная ссылка для решения SQL, которое вы можете проверить. Оптимизация формулы haversine SQL-вызов в PHP
class Distance { /** * Mean raidus of the earth in kilometers. * @var double */ const RADIUS = 6372.797; /** * Pi divided by 180 degrees. Calculated with PHP Pi constant. * @var double */ const PI180 = 0.017453293; /** * Constant for converting kilometers into miles. * @var double */ const MILES = 0.621371192; /** * Calculate distance between two points of latitude and longitude. * @param double $lat1 The first point of latitude. * @param double $long1 The first point of longitude. * @param double $lat2 The second point of latitude. * @param double $long2 The second point of longitude. * @param bool $kilometers Set to false to return in miles. * @return double The distance in kilometers or miles, whichever selected. */ public static function getDistance($lat1, $long1, $lat2, $long2, $kilometers = true) { $lat1 *= self::PI180; $long1 *= self::PI180; $lat2 *= self::PI180; $long2 *= self::PI180; $dlat = $lat2 - $lat1; $dlong = $long2 - $long1; $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlong / 2) * sin($dlong / 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); $km = self::RADIUS * $c; if($kilometers) { return $km; } else { return $km * self::MILES; } } } //example echo Distance::getDistance(40.686748, -89.555054, 40.453078, -88.939819);