kewl132 Posted April 10, 2006 Share Posted April 10, 2006 I am in the process of hacking a dealer/zipcode locator script and have ran into a roadblock. I need the script to display the returned results sorted by the distance.you can view the demo I have up at www.jonstober.com/demo.phpI think I just need to sort the array returned by get_zips_in_range function before I display it but I am not sure how to do this?Here is the code that I am using[code]<?class zipcode_class { var $last_error = ""; // last error message set by this class var $last_time = 0; // last function execution time (debug info) var $units = "m"; // m = miles, k = kilometers var $decimals = 2; // decimal places for returned distance function get_zip_details($zip) { // This function pulls the details from the database for a // given zip code. $sql = "SELECT lattitude, longitude, city, state.state_prefix, state_name, zip_class, station from zip_code, state WHERE zip_code=$zip AND zip_code.state_prefix=state.state_prefix"; $r = mysql_query($sql); if (!$r) { $this->last_error = mysql_error(); return; } else { $row = mysql_fetch_array($r, MYSQL_ASSOC); mysql_free_result($r); return $row; } } function get_zip_point($zip) { // This function pulls just the lattitude and longitude from the // database for a given zip code. $sql = "SELECT lattitude, longitude from zip_code WHERE zip_code=$zip"; $r = mysql_query($sql); if (!$r) { $this->last_error = mysql_error(); return; } else { $row = mysql_fetch_array($r); mysql_free_result($r); return $row; } } function calculate_mileageA($lat1, $lat2, $lon1, $lon2) { // This function is not used right now. This is based on code found // all over the internet such as 4guysfromrolla.com. It's not clear // who the original author was. $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)); $dist = $dist+cos(deg2rad($lat1))*cos(deg2rad($lat2))*cos(deg2rad($lon1 - $lon2)); $dist = acos($dist); $dist = rad2deg($dist); return $dist * 60 * 1.1515; } function calculate_mileage($lat1, $lat2, $lon1, $lon2) { // used internally, this function actually performs that calculation to // determine the mileage between 2 points defined by lattitude and // longitude coordinates. This calculation is based on the code found // at http://www.cryptnet.net/fsp/zipdy/ // Convert lattitude/longitude (degrees) to radians for calculations $lat1 = deg2rad($lat1); $lon1 = deg2rad($lon1); $lat2 = deg2rad($lat2); $lon2 = deg2rad($lon2); // Find the deltas $delta_lat = $lat2 - $lat1; $delta_lon = $lon2 - $lon1; // Find the Great Circle distance $temp = pow(sin($delta_lat/2.0),2) + cos($lat1) * cos($lat2) * pow(sin($delta_lon/2.0),2); $distance = 3956 * 2 * atan2(sqrt($temp),sqrt(1-$temp)); return $distance; } function get_zips_in_range($zip, $range) { // returns an array of the zip codes within $range of $zip. Returns // an array with keys as zip codes and values as the distance from // the zipcode defined in $zip. $details = $this->get_zip_point($zip); // base zip details if (empty($details)) return; // This portion of the routine calculates the minimum and maximum lat and // long within a given range. This portion of the code was written // by Jeff Bearer (http://www.jeffbearer.com). This significanly decreases // the time it takes to execute a query. My demo took 3.2 seconds in // v1.0.0 and now executes in 0.4 seconds! Greate job Jeff! // Find Max - Min Lat / Long for Radius and zero point and query // only zips in that range. $lat_range = $range/69.172; $lon_range = abs($range/(cos($details[0]) * 69.172)); $min_lat = number_format($details[0] - $lat_range, "4", ".", ""); $max_lat = number_format($details[0] + $lat_range, "4", ".", ""); $min_lon = number_format($details[1] - $lon_range, "4", ".", ""); $max_lon = number_format($details[1] + $lon_range, "4", ".", ""); $return = array(); // declared here for scope $sql = "SELECT * FROM zip_code WHERE szip = zip_code AND lattitude BETWEEN '$min_lat' AND '$max_lat' AND longitude BETWEEN '$min_lon' AND '$max_lon' LIMIT 3"; $r = mysql_query($sql); if (!$r) { // sql error $this->last_error = mysql_error(); return; } else { while ($row = mysql_fetch_row($r)) { // loop through all 40 some thousand zip codes and determine whether // or not it's within the specified range. $dist = $this->calculate_mileage($details[0],$row[1],$details[1],$row[2]); if ($this->units == 'k') $dist = $dist * 1.609344; if ($dist <= $range) { $return[str_pad($row[0], 5, "0", STR_PAD_LEFT)] = round($dist, $this->decimals); } } mysql_free_result($r); } return $return; } function chronometer() { // chronometer function taken from the php manual. This is used primarily // for debugging and anlyzing the functions while developing this class. $now = microtime(TRUE); // float, in _seconds_ $now = $now + time(); $malt = 1; $round = 7; if ($this->last_time > 0) { /* Stop the chronometer : return the amount of time since it was started, in ms with a precision of 3 decimal places, and reset the start time. We could factor the multiplication by 1000 (which converts seconds into milliseconds) to save memory, but considering that floats can reach e+308 but only carry 14 decimals, this is certainly more precise */ $retElapsed = round($now * $malt - $this->last_time * $malt, $round); $this->last_time = $now; return $retElapsed; } else { // Start the chronometer : save the starting time $this->last_time = $now; return 0; }}} [/code] Quote Link to comment Share on other sites More sharing options...
ober Posted April 10, 2006 Share Posted April 10, 2006 It may be as simple as using an ORDER BY clause to your SQL statement. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.