As I see it, the IF statement in the conversion function puts the kibosh on using the entire calculation in an order by statement. It has been a while since I've fooled around with spherical trig, but if the fellow that wrote this routine thinks he can get a distance less than 0, so be it.
So, there are two ways to approach. First, we ignore the IF statement and simply convert all the steps in the calculation to one long expression that fits in an order by statement.
Let us assume that $lat1 and $lon1 are the values of the user making the query. Let us also assume that the values are already doubles since that is how they are defined in the mysql database. Then, we could write a routine like so:
// build a query with a calculation in it
$query = "SELECT filename, annotation, pageno, thumbid,
6371.2 * (acos(sin($lat1*$rad) * sin($lat2*$rad) + cos($lat1*$rad) * cos($lat2*$rad) * cos(($lon2-$lon1)*$rad)))
AS dist
FROM thumbs
ORDER BY 6371.2 * (acos(sin($lat1*$rad) * sin($lat2*$rad) + cos($lat1*$rad) * cos($lat2*$rad) * cos(($lon2-$lon1)*$rad)))";
So... all I have done here is combine multiple statements into one.
The other way is to sort the query result array. To do this, you create a "fake" calculation so that you have a field to fill in later with a real distance calculation.
// build a query with a fake calculation in it
$query = "SELECT filename, annotation, pageno, thumbid,
$lat2 * 5 AS dist
FROM thumbs
ORDER BY $lat2 * 5 AS dist ;
Now you have a result with a meaningless dist field in it. Use the mathematical functions you described to compute a real value for the dist field. You can cycle through this array with the mysql array commands.
Finally, after you have created a true distance in the dist column, you sort the array with a routine that would look something like this.
function array_distsort($thearray, $field)
{
foreach ($thearray as $row) {
$sortarr[] = $row[$field];
}
array_multisort($sortarr, $thearray);
return $thearray;
}
I've tested none of this. But, methinks one of the two methods will work.