Получить ближайшие места на Google Maps, используя пространственные данные MySQL - PullRequest
8 голосов
/ 10 января 2011

У меня есть база данных со списком магазинов с широтой и долготой каждого.Исходя из текущего (широта, долгота) местоположения, которое я ввожу, я хотел бы получить список предметов из тех, которые находятся в радиусе, например, 1 км, 5 км и т. Д.

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

Ответы [ 3 ]

31 голосов
/ 12 февраля 2011

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

Например, у вас есть введенные широта и долгота 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. Вышеупомянутый процесс может быть выполнен с многократным перенаправлением.

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

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

6 голосов
/ 11 февраля 2011

Если вы ищете 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);
6 голосов
/ 10 января 2011

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

...