2011-01-10 2 views
8

У меня есть база данных со списком магазинов с широтами и долготами каждого. Поэтому, основываясь на текущем (lat, lng) месте, которое я вводил, я хотел бы получить список предметов из тех, которые находятся в радиусе радиусом 1 км, 5 км и т. Д.?Получить ближайшие места на Картах Google, используя пространственные данные MySQL

Какой должен быть алгоритм? Мне нужен PHP-код для самого алгоритма.

ответ

26

Вам просто нужно использовать следующий запрос.

Например, у вас есть широта и долгота ввода 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 в запросе выше.

Вы также можете сделать это, как:

  1. Выбрать все широты и долготы

  2. Затем вычислить расстояние для каждой записи.

  3. Вышеупомянутый процесс может быть выполнен с использованием нескольких перенаправлений.

Для оптимизации запроса вы можете использовать хранимую процедуру.

И this также может вам помочь.

+1

ура для этого помощника –

+0

Небольшое предупреждение, так как это выйдет из-под контроля, если таблица с точками увеличится в размере. Вы будете делать вычисления для каждой точки таблицы для каждого запроса. –

+0

Для этого может использоваться хранимая процедура. – Gaurav

6

Вы должны выбрать базу данных, которая пространственно включена, например mysql или postgresql, а затем вы можете использовать некоторые из готовых функций, которые они предоставляют. Иначе, если вы хотите сделать это вручную, проверьте this на голову.

+0

Я бы порекомендовал postgresql с расширением postgis. Его путь быстрее, чем MySQL. – 23tux

+0

@ 23tux Это быстрее и намного более полно, но mysql - это то, что большинство людей знакомо, а пространственные расширения mysql очень удобны –

6

Если вы ищете PHP-код для вычисления расстояния между двумя наборами координат, вот класс, который я адаптировал, который рассчитает расстояние в километрах. Однако, если вы используете базу данных, я бы посоветовал вам изучить, может ли ваша база данных работать с пространственными вычислениями (я знаю, что SQL Server и MySQL, с моей точки зрения).

Вот интересная ссылка для решения SQL, которое вы можете проверить. Optimising a haversine formula SQL call in 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); 
+0

, так что мне нужна база данных для поддержки некоторых специальных функций? Не могу ли это сделать непосредственно с помощью PHP? если я сохраню координаты lat/lng как 2 поля в БД –

+0

Код, который я разместил, даст вам расстояние между двумя координатами. –

Смежные вопросы