Расстояние поиска между 2 точками CakePHP

Я пытаюсь создать небольшой веб-сайт CakePHP, у которого есть широта и долгота в БД. Пользователь выполняет поисковый запрос к местоположениям (с указанием своего адреса), и результаты должны быть упорядочены по расстоянию от пользователя до местоположения. Я уже могу получить lat en lng при предоставлении адреса (используя API Карт Google). Я не знаю, как построить находку CakePHP с дистанционным заказом. Любые идеи?

Я использую CakePHP 2.3.


person Marco Veenendaal    schedule 16.03.2013    source источник
comment
если вы используете карты Google, вы можете использовать матрицу расстояний.   -  person Kishor Kundan    schedule 16.03.2013


Ответы (2)


Я предпочитаю использовать для этой цели виртуальные поля. Реализация зависит от используемой вами БД. Для Postgres это будет выглядеть следующим образом:

MyModel.php

public function findSortedByDistanse($long, $lat){
    $distanceValue = "calc_distance($lat, $long, MyModel.lat, MyModel.lon)";
    $this->virtualFields['distance'] = $distanceValue;
    return $this->find('all', array('conditions' => array(
        'order' => 'MyModel.distance ASC'
    )));
}

где calc_distance — хранимая процедура для Postgres

Параметры: IN source_lat числовое, IN source_lon числовое, IN target_lat числовое, IN target_lon числовое

Код:

SELECT ( 3956 * 2 * 
   ASIN ( 
      SQRT ( 
        POWER ( SIN ( ( $1 - abs($3) ) * pi()/180/2 ),2 ) + 
        COS ( $1 * pi()/180 ) * 
    COS ( abs($3) * pi()/180 ) * 
    POWER ( SIN ( ( $2 - $4 ) * pi()/180 / 2 ), 2 ) 
      ) 
   )
)

Если вы предпочитаете необработанный запрос, используйте следующее:

$distanceValue = "3956 * 2 * ASIN(SQRT(POWER(SIN(({$lat}-abs(MyModel.lat))*pi()/180/2),2)+COS({$lat} * pi()/180)*COS(abs(MyModel.lat) *  pi()/180)*POWER(SIN(({$long} - MyModel.lon)*pi()/180 / 2), 2)))";
person Karisters    schedule 16.03.2013
comment
Ну спасибо, это для меня лучший вариант, я поставил его в поведении! Отлично, работает! - person Marco Veenendaal; 16.03.2013
comment
Каристерс, не могли бы вы уточнить, какая формула расстояния здесь используется? Большой круг? Винсент? - person swiecki; 16.03.2013
comment
Его формула Хаверсина - person Karisters; 17.03.2013

Rangeable можно использовать для поиска поблизости на основе выбранной пользователем геолокации. Однако этот плагин устарел, потому что он создан для поддержки CakePHP 1.x и может не работать с CakePHP 2.x.

Возможно, вам придется преобразовать его.

person Karma    schedule 16.03.2013
comment
Спасибо, я попробую это! - person Marco Veenendaal; 16.03.2013