2011-01-31 4 views
0

Я написал функцию, которая может рассчитать расстояние между двумя адресами, используя API Карт Google.Вычислить расстояния и отсортировать их

Адреса получены из базы данных. Я хочу рассчитать расстояние, используя функцию, которую я написал, и отсортировать места в соответствии с расстоянием. Также как функция «Найти магазин рядом с вами» в интернет-магазинах.

Я собираюсь указать, что я хочу сделать с примером:

Итак, предположим, что у нас есть 10 адресов в базе данных. И у нас есть переменная $ currentlocation. И у меня есть функция calcdist(), поэтому я могу рассчитать расстояния между 10 адресами и $ currentlocation и отсортировать их. Вот как я это делаю:

$query = mysql_query("SELECT name, address FROM table"); 
while ($write = mysql_fetch_array($query)) { 
    $distance = array(calcdist($currentlocation, $write["address"])); 
    sort($distance); 
    for ($i=0; $i<1; $i++) { 
     echo "<tr><td><strong>".$distance[$i]." kms</strong></td><td>".$write['name']."</td></tr>"; 
    } 
} 

Но это не очень хорошо работает. Он не сортирует числа.

Другая проблема: Как я могу сделать это эффективным способом? Представьте, что существует бесконечное количество адресов; как я могу отсортировать эти адреса и перечислить их?

+0

Имеет ли база данных есть широта и долгота в нем? – Jason

+0

Вы связаны с MySQL? [PostgreSQL] (http://www.postgresql.org/) + [PostGIS] (http://postgis.refractions.net/) обеспечит гораздо лучшую основу для эффективного запроса данных. – outis

+0

Как работает функция calcdist()? Не могли бы вы сделать это на стороне базы данных? Это значительно облегчило бы запрос, сортировку, разбиение на страницы. –

ответ

1
$query = mysql_query("SELECT name, address FROM table"); 
$rows = array(); 
while ($row = mysql_fetch_array($query)) { 
    $row['distance'] = array(calcdist($currentlocation, $row['address'])); 
    $rows[$row['name']] = $row; 
} 

function cmp_distances($a, $b) { 
    if($a['distance'] > $b['distance']) return 1; 
    elseif($a['distance'] < $b['distance']) return -1; 
    else return 0; 
} 

// sort distances while preserving key=>value associations 
uasort($rows, 'cmp_distances'); 

// iterate over the sortest list and displaythe entries 
foreach($rows as $name => $row) { 
    echo '<tr><td><strong>'.$row['distance'].' km</strong></td><td>'.$name.'</td></tr>'; 
} 
+0

Благодарим вас за ответ. Это работает очень хорошо, за исключением случаев, когда мне нужно получить несколько столбцов из базы данных. Например, как я могу сортировать информацию, если я хочу получить столбцы имен, городов и стран из базы данных? – Dave

+0

Используйте функцию сравнения вместо strnatcmp: «Функция сравнения должна возвращать целое число меньше, равно или больше нуля, если первый аргумент считается меньше, чем или больше второго». --- Добавить, хранить $ distance в строке $ row и положить $ row в $ distance – ThiefMaster

+0

Как я могу сохранить $ distance в $ row, $ row извлекает данные из базы данных? – Dave

0

В вашем примере вы вычислить расстояние до одного адреса в то время:

$distance = array(calcdist($currentlocation, $write["address"])); 

И когда вы сделаете это

sort($distance); 

у вас есть только один элемент в массиве. В основном вы печатаете значения точно в том же порядке, что и они, начиная с db, до вычисления расстояния.

Вы могли:

1) Вычислить все адреса и поместить их в массив

2) Сортировка массива

3) распечатать результаты

О другой вызов, который вы упомянули. Это немного сложнее, и я уверен, что есть много вариантов. Я бы подумал, сколько адресов вам действительно нужно сравнивать друг с другом? Неужели это бесконечно? :)

Это внутри одной страны или всего мира? На ваших адресах db у вас, скорее всего, есть почтовый индекс. Вы можете использовать это, чтобы сузить поиск. Используйте только почтовые коды рядом и делайте вычисления только для этих адресов.

Но эмпирическое правило обычно заключается в том, что мы слишком быстро беспокоимся о производительности. Прежде, чем это даже проблема.

+0

Вы правы, на самом деле я храню почтовые индексы в поле адреса базы данных. И тогда эти почтовые коды изменяются на широты и долготы с функцией calcdist, после чего функция вычисляет расстояние между двумя местами. Адреса могут увеличиваться по времени, так как пользователи могут добавлять новые. Итак, считайте это бесконечным :) – Dave

0

Я думаю, что у вас есть хорошие ответы на ваш первый вопрос.

Что касается второй проблемы, это немного зависит от того, как выглядит ваша база данных. Вы сохраняете только строку с адресом? Я предполагаю, что вы используете некоторую услугу геокодирования для преобразования адреса в позицию (lat, lon), а затем вы вычисляете расстояние, верно ли это?

Если вы сделаете что-то подобное, вы можете начать сохранять координаты для каждого геокодированного адреса в вашем dataabse. Таким образом, вы будете геокодировать адрес только один раз (возможно, позже вы захотите обновлять эту информацию время от времени, но это еще одна проблема).

Как только у вас есть в таблице «Адрес, lat, lon», вы можете использовать SQL, чтобы сузить свой поиск, накладывая некоторые условия на (lat, lon), или вы даже можете попытаться заставить SQL выполнить всю работу за вас, определяя новый столбец (в результирующем наборе), например, distance = sqrt((lat-x)^2 + (lon-y)^2)), где (x, y) - это точка, с которой вы начинаете (точка, где находится пользователь), а затем возвращает первые результаты N, отсортированные по расстоянию

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