Calculate distances and sort them
I wrote a function that can calculate the distance between two addresses using the Google Maps API.
The addresses are obtained from the database. What I want to do is calculate the distance using the function I wrote and sort the places according to the distance. Just like "Locate Store Near You" feature in online stores.
I'm going to specify what I want to do with an example:
So, lets say we have 10 addresses in database. And we have a va开发者_如何学Criable $currentlocation. And I have a function called calcdist(), so that I can calculate the distances between 10 addresses and $currentlocation, and sort them. Here is how I do it:
$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>";
}
}
But this doesn't work very well. It doesn't sort the numbers.
Another challenge: How can I do this in an efficient way? Imagine there are infinite numbers of addresses; how can I sort these addresses and page them?
$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>';
}
In your example you calculate the distance to one address at the time:
$distance = array(calcdist($currentlocation, $write["address"]));
And when you do this
sort($distance);
you only have one item in your array. Basically you are printing the values exactly in the same order they are coming from the db, before the distance calculation.
You could:
1) Calculate all the addresses and put them into an array
2) Sort the array
3) Print out the results
About the another challenge you mentioned. This is a bit more tricky and I'm sure there are plenty of options. I would start by thinking how many addresses you really need to compare with each other? Is it really infinite? :)
Is this inside one country or world wide? In your db addresses, you most likely have the postal code. You can use this to narrow the search. Use only the postal codes near by and make the calculations only for those addresses.
But rule of thumb usually is that we worry about the performance too soon. Before it's even a problem.
I think you got some nice answers about your first question.
Concerning the second problem, it depends little bit how your database looks like. Do you store just a string with an address? I assume that you use some geocoding service to convert the address to a (lat,lon) position and then you calculate the distance, is this right?
In case you do something like this, you could start saving the coordinates for each geocoded address in your dataabse. In this way you would geocode the address only once (maybe you later will be willing to update this information now and then, but this is another issue).
Once you have in your table "Address,lat,lon" you can use SQL to narrow down your search imposing some conditions on (lat,lon) or you may even try to make SQL do the whole job for you, defining a new column (in the result set) like for example distance = sqrt((lat-x)^2 + (lon-y)^2))
where (x,y) is the point you start from (the point where the user is) and later return the first N results sorted by distance
精彩评论