У меня есть рабочий скрипт PHP, который получает значения долготы и широты, а затем вводит их в запрос MySQL. Я хотел бы сделать это исключительно MySQL. Вот мой текущий код PHP:
if ($distance != "Any" && $customer_zip != "") { //get the great circle distance
//get the origin zip code info
$zip_sql = "SELECT * FROM zip_code WHERE zip_code = '$customer_zip'";
$result = mysql_query($zip_sql);
$row = mysql_fetch_array($result);
$origin_lat = $row['lat'];
$origin_lon = $row['lon'];
//get the range
$lat_range = $distance/69.172;
$lon_range = abs($distance/(cos($details[0]) * 69.172));
$min_lat = number_format($origin_lat - $lat_range, "4", ".", "");
$max_lat = number_format($origin_lat + $lat_range, "4", ".", "");
$min_lon = number_format($origin_lon - $lon_range, "4", ".", "");
$max_lon = number_format($origin_lon + $lon_range, "4", ".", "");
$sql .= "lat BETWEEN '$min_lat' AND '$max_lat' AND lon BETWEEN '$min_lon' AND '$max_lon' AND ";
}
Кто-нибудь знает, как сделать это полностью MySQL? Я немного просмотрел Интернет, но большая часть литературы о нем довольно запутанная.
php
mysql
great-circle
Ник Вудхэмс
источник
источник
Ответы:
Из Google Code FAQ - Создание локатора магазина с помощью PHP, MySQL и Google Maps :
источник
markers
таблица с полями id, lan и lng.$greatCircleDistance = acos( cos($latitude0) * cos($latitude1) * cos($longitude0 - $longitude1) + sin($latitude0) * sin($latitude1));
с широтой и долготой в радианах.
так
ваш запрос SQL
чтобы получить результаты в км или милях, умножьте результат на средний радиус Земли (
3959
миль,6371
км или3440
морских миль)То, что вы рассчитываете в своем примере, это ограничивающий прямоугольник. Если вы поместите свои данные координат в столбец MySQL с пространственной поддержкой , вы можете использовать встроенную функциональность MySQL для запроса данных.
источник
Если вы добавите вспомогательные поля в таблицу координат, вы сможете улучшить время ответа на запрос.
Как это:
Если вы используете TokuDB, вы получите еще большую производительность, если добавите кластеризованные индексы к любому из предикатов, например, так:
Вам понадобятся базовые значения lat и lon в градусах, а также sin (lat) в радианах, cos (lat) * cos (lon) в радианах и cos (lat) * sin (lon) в радианах для каждой точки. Затем вы создаете функцию mysql, что-то вроде этого:
Это дает вам расстояние.
Не забудьте добавить индекс по широте / долготе, чтобы ограничивающий бокс мог помочь в поиске, а не замедлять его (индекс уже добавлен в запросе CREATE TABLE выше).
Учитывая старую таблицу только с координатами широта / долгота, вы можете настроить скрипт для ее обновления следующим образом: (php используя meekrodb)
Затем вы оптимизируете фактический запрос, чтобы вычисление расстояния выполнялось только тогда, когда это действительно необходимо, например, путем ограничения круга (ну, овала) изнутри и снаружи. Для этого вам нужно предварительно рассчитать несколько показателей для самого запроса:
Учитывая эти приготовления, запрос выглядит примерно так (php):
EXPLAIN в приведенном выше запросе может сказать, что он не использует индекс, если нет достаточно результатов для его запуска. Индекс будет использоваться, когда в таблице координат будет достаточно данных. Вы можете добавить FORCE INDEX (lat_lon_idx) в SELECT, чтобы он использовал индекс безотносительно к размеру таблицы, поэтому вы можете проверить с помощью EXPLAIN, что он работает правильно.
С приведенными выше примерами кода у вас должна быть работающая и масштабируемая реализация поиска объектов по расстоянию с минимальной ошибкой.
источник
Я должен был разобраться с этим в некоторых деталях, поэтому я поделюсь своим результатом. Это использует
zip
таблицу сlatitude
иlongitude
таблицами. Это не зависит от Google Maps; скорее вы можете адаптировать его к любой таблице, содержащей lat / long.Посмотрите на эту строку в середине этого запроса:
Это ищет 30 ближайших записей в
zip
таблице в пределах 50.0 миль от широты / длинной точки 42.81 / -70.81. Когда вы встраиваете это в приложение, здесь вы указываете свою точку и радиус поиска.Если вы хотите работать в километрах, а не в милях, измените
69
на111.045
и измените3963.17
на6378.10
в запросе.Вот подробное описание. Надеюсь, это кому-нибудь поможет. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/
источник
Я написал процедуру, которая может рассчитать то же самое, но вы должны ввести широту и долготу в соответствующей таблице.
источник
Я не могу комментировать приведенный выше ответ, но будьте осторожны с ответом @Pavel Chuchuva. Эта формула не вернет результат, если обе координаты совпадают. В этом случае расстояние равно нулю, поэтому строка не будет возвращена с этой формулой как есть.
Я не эксперт по MySQL, но мне кажется, что это работает:
источник
ACOS(1)
0). Вы могли бы видеть проблемы округления с xaxis * xaxis + yaxis * yaxis + zaxis * zaxis, выходящие за пределы диапазона для ACOS, но вы, кажется, не защищаете это?на расстояние 25 км
источник
Я думал, что моя реализация javascript будет хорошей ссылкой на:
источник
рассчитать расстояние в Mysql
Таким образом, значение расстояния будет рассчитано, и любой может подать заявку, как требуется.
источник