This common problem has stumped many programmers in the past, so I thought I would add in my little part. Whilst doing research for this I managed to find a site called www.streetmap.co.uk which has a nice little PostCode to geographical reference tool. Using a simple URL parameter I was able to give the site a PostCode and strip the longitude and latitude from the resulting HTML. Here is the function I came up with.
function postCode2Geog($code){
$code = strtolower(str_replace(' ','',$code));
$uri = "http://www.streetmap.co.uk/streetmap.dll?GridConvert?name=".$code."&type=Postcode";
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
preg_match('#long \(wgs84\)\s*?\<\/td\>\s*?\\S{2,3}:\S{2}:\S{2} \( (.*?) \)#i',$output,$longMatch);
preg_match('#lat \(wgs84\)\s*?\<\/td\>\s*?\\S{2,3}:\S{2}:\S{2} \( (.*?) \)#i',$output,$latMatch);
$long = $longMatch[1];
$lat = $latMatch[1];
return array($lat,$long);
}
To use the function use the following, in this case I am looking at the BBC studio in London.
This produces the result of 51.518561 latitude and -0.143800 longitude, which seems to check out.
$geog = postCode2Geog('W1A 1AA');
Initial results from using this method seem promising, but the Streetmap site seems not to have been updated since 2004. I found this method after a few minutes searching, and I only needed to convert 20 or so postcodes into geographical coordinates. An alternative is to use a method that I have talked about previously in the post find longitude and latitude of PostCode or ZipCode using Google Maps And PHP, but that requires you to have a valid, working Google maps API key. This method is an alternative if you don't want to go down that route.
Comments
11 years on and thanks to very little progress being made by Streetmaps this little beauty is still working like a dream. I swapped out
preg_match('#long \(wgs84\)\s*?\\s*?\\S{2,3}:\S{2}:\S{2} \( (.*?) \)#i',$output,$longMatch);
preg_match('#lat \(wgs84\)\s*?\\s*?\\S{2,3}:\S{2}:\S{2} \( (.*?) \)#i',$output,$latMatch);
for...
$long_pattern = '/x=[0-9]*/';
$lat_pattern = '/&y=[0-9]*/';
preg_match($long_pattern,$output,$longMatch);
preg_match($lat_pattern,$output,$latMatch);
otherwise this is still a brilliant snippet, thanks for sharing :)