Monday 4 February 2013

UK Post Code Distance Calculator using PHP/MySQ


UK Post Code Distance Calculator using PHP/MySQL

March 30th, 2008
Ever wondered how websites can tell you how far it is from one UK post code to another? This tutorial will tell you everything you need to know about adding this cool feature to your website using PHP and MySQL. Warning - although there is complex maths involved, no clever maths knowledge is required.

How it Works

The theory is simple - you need a database of post codes (only the first part of the post code) and their corresponding longitude/latitude values. When calculating the distance we are actually calculating the distance from one long/lat value to another (using rather clever maths).
To see a demo of the UK post code distance calculator in action please visit www.wroes.co.uk/about/stores.php.

Setting up the Database

Firstly, you require a database of post codes with their corresponding longitude/latitude values. Thankfully, this has already been compiled by easypeasy!which can be downloaded in CSV or SQL format. We’ve provided the files here for your convenience.
Download the UK post codes database in CSV/SQL: uk-postcodes.zip (95KB)
Create your database table using these files and your ready to begin. You will see that the database contains the following fields:
  • Post code (first part)
  • Postal town (Uk-Postcodes-Towns.csv file only)
  • X-coordinate (metres)
  • Y-coordinate (metres)
  • Latitude
  • Longitude

Getting the Latitude and Longitude Values

We’re assuming you have 2 full post codes to calculate the distance between. We only need the first part of the post code so we must trim them accordingly. The second part of the post code is always 3 characters (first part can either be 2, 3, or even 4 characters). So, we need to remove all spaces and then trim 3 characters off the end to give us the first part:
<?php

#Convert the post code to upper case and trim the variable
$postcode = strtoupper(trim($postcode));

#Remove any spaces
$postcode = str_replace(" ","",$postcode);

#Trim the last 3 characters off the end
$postcode_first = substr($postcode,0,strlen($postcode)-3);

?>
We have our 2 post codes now ready to compare. We need to query our database to obtain the latitude and longitude values for each post code. Use the following query, replacing with correct field/table names where appropriate:
“SELECT * FROM tblPostCode WHERE fldPostCode = ‘$postcode_first’ LIMIT 1″;
Check to ensure a post code was found and then assign the variables. You may wish to use something like this: (repeating the code for the second post code)
<?php

Does the post code exist?
if ($myrow["fldPostCode"] != ""){

#Assign variables
$code1_lat = $myrow["fldLatitude"];
$code1_long = $myrow["fldLongitude"];

}else{

#post code not found

}

?>

Calculating the Distance

This is where the complex mathematics starts. Don’t worry if you don’t understand this (we certainly don’t)! All you need for this to work is the latitude and longitude values for your 2 post codes (obtained from your database - above).
We’re going to create a function called getDistance() which takes all 4 lat/long values to return the distance in miles. If you’re after kilometres you can either perform the conversion from miles afterwards or modify the function slightly (see first comment below). This function does take into account the curvature of the Earth. Here’s the function:
<?php

function getDistance($lat1, $long1, $lat2, $long2){

#$earth = 6371; #km change accordingly
$earth = 3960; #miles

#Point 1 cords
$lat1 = deg2rad($lat1);
$long1= deg2rad($long1);

#Point 2 cords
$lat2 = deg2rad($lat2);
$long2= deg2rad($long2);

#Haversine Formula
$dlong=$long2-$long1;
$dlat=$lat2-$lat1;

$sinlat=sin($dlat/2);
$sinlong=sin($dlong/2);

$a=($sinlat*$sinlat)+cos($lat1)*cos($lat2)*($sinlong*$sinlong);

$c=2*asin(min(1,sqrt($a)));

$d=round($earth*$c);

return $d;

}

?>
We call the function with the following code:
<?php

#Returns the distance in miles
$distance = getDistance($code1_lat, $code1_long, $code2_lat, $code2_long);

?>

Limitations

The distance calculated is not the real distance if travelling on roads. It calculates a direct route as the crow flies. This is ideal for an approximate calculation, however, if you want more detailed calculations then you may wish to explore available mapping and route calculation software and APIs.
The exact same theory and code can be used when calculating distances from US Zip codes.

Note:

Assuming you are looking for the geographic distance, first you need to get the latitude and longitude of your two postcodes with the Google Maps server-side geocoding services as in the following example:
$url = 'http://maps.google.com/maps/geo?q=EC3M,+UK&output=csv&sensor=false';

$data = @file_get_contents($url);

$result = explode(",", $data);

echo $result[0]; // status code
echo $result[1]; // accuracy
echo $result[2]; // latitude
echo $result[3]; // longitude