Two very simple functions that work together to calculate the distance between two different Canadian postal codes.
Alternatively you could pay $600 for a database of all Canadian postal codes with longitudes and latitudes, but I don't think that's why your reading this page. This method is easy to implement, connects to a constantly updated database, and did I mention--it's free?
How it works
The one function, "getCoord", uses Google Maps API's XML feed to fetch the longitude and latitude of each postal code, the second, "calcDistance", does some freaky math to calculate the distance in kilometers.
DON'T FORGET: You'll need to signup to use the Google Maps API at http://www.google.com/apis/maps/signup.html before you can use the getCoord function. Take the key Google gives you and store it in the constant 'KEY'.
Drawbacks
I used to use GeoCoder do the same calculations which only allowed for 100 lookups a day. Now with Google we have a 50,000 lookup limit. Which I doubt you'll ever surpass.
<?php
/**
* GETCOORD
* Uses Google Maps to resolve the coordinates of a postal code
*
* @param String $postal Postal code to lookup
* @return Array Returns array with latitude and longitude
* @return Boolean False if an error occurred
*/
// ---- | REQUIRED GOOGLE MAPS KEY | --------
// Get yours here: http://www.google.com/apis/maps/signup.html
define('KEY', '---fill me in---');
function getCoord($postal)
{
$d = file_get_contents('http://maps.google.com/maps/geo?q=' . $postal . '&output=xml&key=' . KEY);
if (!$d)
return false; // Failed to open connection
$coord = new SimpleXMLElement($d);
if ((string) $coord->Response->Status->code != '200')
return false; // Invalid status code
list($lng, $lat) = explode(',', (string) $coord->Response->Placemark->Point->coordinates);
return array('Lat' => (float) $lat, 'Lng' => (float) $lng);
}
/**
* CALCDISTANCE
* Calculates the distance between to postal codes
*
* @param String $postal1 Starting postal code
* @param String $postal2 Ending postal code
* @return Float Returns distance in kilometers
* @return Boolean False if an error occurred
*/
function calcDistance($postal1, $postal2)
{
$dst1 = getCoord($postal1);
$dst2 = getCoord($postal2);
if (!$dst1 or !$dst2)
return false; // Invalid postal codes
$kms = rad2deg(acos(sin(deg2rad($dst1['Lat'])) * sin(deg2rad($dst2['Lat'])) +
cos(deg2rad($dst1['Lat'])) * cos(deg2rad($dst2['Lat'])) *
cos(deg2rad($dst1['Lng'] - $dst2['Lng'])))) * 60 * 1.1515 * 1.609344;
return $kms;
}
echo calcDistance('r3g3j6', 'r0c3e0') . ' kms'; // prints 37.... kms
?>
No comments:
Post a Comment