PHP/MySQL:Выберите местоположения, близкие к данному местоположению, из БД.

StackOverflow https://stackoverflow.com/questions/894713

Вопрос

В PHP у меня есть следующий код для расчета расстояния между двумя местоположениями:

<?php
function distance($lat1, $long1, $lat2, $long2) {
    // DEGREE TO RADIAN
    $latitude1 = $lat1/180*pi();
    $longitude1 = $long1/180*pi();
    $latitude2 = $lat2/180*pi();
    $longitude2 = $long2/180*pi();
    // FORMULA: e = ARCCOS ( SIN(Latitude1) * SIN(Latitude2) + COS(Latitude1) * COS(Latitude2) * COS(Longitude2-Longitude1) ) * EARTH_RADIUS
    $distance = acos(sin($latitude1)*sin($latitude2)+cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6371;
    return $distance;
}
echo distance(9.9921962, 53.5534074, 9.1807688, 48.7771056); // Hamburg, DE - Stuttgart, DE
?>

Но теперь я хочу выбрать местоположения, близкие к заданному местоположению, через PHP из моей базы данных MySQL:

  • Пользователь вводит свой родной город
  • Мой скрипт получает значения широты и долготы через API Google.
  • В моей базе данных есть около 200 местоположений с полем для значения широты и полем для значения долготы.
  • Мне нужен код для PHP и MySQL, чтобы выбрать 10 мест, ближайших к родному городу пользователя.

Я надеюсь, что вы можете мне помочь.Заранее спасибо!

Это было полезно?

Решение

Расстояние по большому кругу MySQL (формула Хаверсина) делает именно то, что вам нужно.

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

Расчет расстояния между почтовыми индексами в PHP есть несколько реализаций этого алгоритма на PHP.

Гео-поиск близости это почти та же проблема, что и у вас.

Другие советы

Может быть, что-то вроде

SELECT field1, field2, ...,
    ACOS(SIN(latitude / 180 * PI()) * SIN(:1) + COS(latitude / 180 * PI()) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

или

SELECT field1, field2, ...,
    ACOS(SIN(RADIANS(latitude)) * SIN(:1) + COS(RADIANS(latitude)) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

(непосредственный перевод из кода PHP)

:1 и :2 является $lat2/180*pi() и $long2/180*pi() соответственно.

Это формула Хаверсина.Вы можете перевести PHP непосредственно в SQL, чтобы иметь возможность пространственно запрашивать базу данных (альтернативой является извлечение каждой записи из БД и запуск данных через PHP).MySQL предоставляет все необходимые математические функции.

Я сделал это для коммерческого веб-сайта, который обеспечивал дистанционный поиск по почте/почтовому индексу, так что это, безусловно, возможно без специальных функций ГИС.

Для этого существуют функции MySQL.

http://dev.mysql.com/doc/refman/5.0/en/gis-introduction.html

MySQL имеет возможность индексировать строки геопространственно.Возможно, вам не придется выполнять эту математическую операцию самостоятельно (вы можете просто попросить MySQL вычислить расстояние между двумя геообъектами и выполнить сортировку по этому значению...).

Видеть: http://forums.mysql.com/read.php?23,159205,159205

Просто наткнулся на эту тему.Возможно, кого-то заинтересует вот эта функция, проверенная в MySql 5.7:

    create function GetDistance(lat1 real, lng1 real, lat2 real, lng2 real) returns real no sql
    return ATAN2(SQRT(POW(COS(RADIANS(lat2)) * SIN(RADIANS(lng1 - lng2)), 2) + 
                POW(COS(RADIANS(lat1)) * SIN(RADIANS(lat2)) - SIN(RADIANS(lat1)) *
                COS(RADIANS(lat2)) *  COS(RADIANS(lng1 - lng2)), 2)), 
                (SIN(RADIANS(lat1)) * SIN(RADIANS(lat2)) + COS(RADIANS(lat1)) *
                COS(RADIANS(lat2)) * COS(RADIANS(lng1 - lng2)))) * 6372.795;

Звонок:

select GetDistance(your_latitude, your_longitude, table_field_lat,
                   table_field_lng) as dist from [your_table] limit 5;

Почему бы вам не использовать геопространственные функции MySQL...?Нет, просто прикалываюсь.

Если 200 записей представляют собой реальные места, такие как города и т. д., то в качестве альтернативы вы могли бы использовать API GeoNames?

Следующий веб-сервис предоставит 10 ближайших к указанным широте и долготе местоположений:

http://ws.geonames.org/findNearby?lat=47.3&lng=9

Источник: http://www.geonames.org/export/web-services.html#findNearbyPlaceName

Полный список: http://www.geonames.org/export/ws-overview.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top