Notice: As a few people have pointed out, this announcement from Google means Geocoding is now built in. Yet as more people have pointed out – it kinda sucks accuracy wise (think over a mile off on some postcodes!), whereas my method continues to be accurate.
Google Maps API provides a geocoding feature, for finding the latitude and longitude of places or addresses; but it does not work for UK postcodes. This is thanks to Royal Mail who have a copyright on the data, and are very restrictive with their (expensive) licenses for it.
There are various solutions out there for using 3rd party services and importing the data to be used with Google Maps, or for using community built databases for the info. However, I’ve had a few people ask me about doing it just though Google.
It is possible — Google AJAX Search API does provide geocoding for UK postcodes. We need to use the two APIs in harmony to achieve our result.
So here it is.
Step by step
I’ll assume you already know how to use Google Maps API, and you came here just looking how to add geocoding for the UK.
Step 1.
Grab a two API keys, if you already have your Google Maps API key, just grab an AJAX search key. You can get them here:
http://www.google.com/apis/maps/signup.html
http://code.google.com/apis/ajaxsearch/signup.html
Step 2.
Google will give you a sample page, you need to stick your two API keys at the top of the page, followed by a reference to your Javascript file:
<script src="http://maps.google.com/maps?file=api&v=2&key=*KEY*" type="text/javascript"></script> <script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key=*KEY*" type="text/javascript"></script> <script src="gmap.js" type="text/javascript"></script>
Ensure the reference to your Javascript file comes after the two API keys.
Step 3.
In addition to the Google Maps API stuff, you need to stick a reference to Google local search at the top of your Javascript file:
var localSearch = new GlocalSearch();
You can grab my Javascript file right here, but remember you’ll need to change the API keys.
Step 4.
The key to this Geocoder is only a single function:
function usePointFromPostcode(postcode, callbackFunction) { localSearch.setSearchCompleteCallback(null, function() { if (localSearch.results[0]) { var resultLat = localSearch.results[0].lat; var resultLng = localSearch.results[0].lng; var point = new GLatLng(resultLat,resultLng); callbackFunction(point); }else{ alert("Postcode not found!"); } }); localSearch.execute(postcode + ", UK"); }
It takes 2 arguments; postcode
is the postcode you want to look for, and callbackFunction
is the function you wish to run on the results.
Why is it necessary to do it this way? It is the way AJAX, and thus Google AJAX Search API, works – the request is sent, and a callback function is designated to handle the results returned, when they are ready.
In our case, the callback function can do whatever you want with the results, which will come in the format of a GLatLng
(often just called a point); I’ve supplied 2 sample functions, placeMarkerAtPoint
and setCenterToPoint
which do pretty much what they sound like they do.
Step 5.
Putting aside accessibility and graceful degradation for the sake of simplicity in this tutorial, the last step we need is just to add some hooks into our Javascript:
<input type="text" id="postcode" size="10" /> <input type="submit" value="Place Marker" onclick="javascript: usePointFromPostcode(document.getElementById('postcode').value, placeMarkerAtPoint)" />
We have a field for inputting a postcode, and I’ve added a button for placing a marker there. Where I have placeMarkerAtPoint
you can put a reference to your own function, or you can even add a function right in there, like this:
<input type="submit" value="Do whatever" onclick="javascript: usePointFromPostcode(document.getElementById('postcode').value, function (point) { alert('Latitude: ' + point.lat() + '\nLongitude: ' + point.lng()); })" />
Demo
If you are coming in from an RSS reader, either visit this blog post on the site, or see the demo page.
Postcode:
Conclusion
Until Royal Mail sort get their act together, and relax the licensing agreement, hopefully this will help people who want a ‘pure’ Google solution and hadn’t come across this option. Please use the comments section to let me know if you are using this, or if you have any improvements or suggestions.
378 responses to “Geocoding UK Postcodes with Google Map API”
Thanks dude, spent a while trying to get the lat lng for a postcode to go to a festival. Your website helped me!!
Hi Tom,
I have been trying to implement your google maps api on a page load so that a postcode I have passed it displays in the map.
Problem is I get an error saying the map object is not defined. I beleive this is down to a scope issue, but there is not in your example. So I am very confused as to why there is a problem when not calling it from a form.
In firebug I get
map is undefined
[Break on this error] map.addOverlay(marker);
Now what can I do to get this working?
Thanks for submitting such good work open source, I really hope we can squash this bug and get it working for my application
Thanks again
super
Its not accurate. Both mine and my partners houses are approx 200 meters away according to your scripting, however if I use google directly its perfectly accurate.
Tom whitbread said, September 2, 2008 @ 8:09 pm
map is undefined
[Break on this error] map.addOverlay(marker);
I encountered this same problem. In my case it was beacuse i was calling the
usePointFromPostcode(‘postcode’, placeMarkerAtPoint);
in the body tag onload of the document. With gmap.js it checks to see if onload has been set to a function. however if you put the onload in the body tags then it the typeof is not a function and it runs
window.onload = func;
Which calls the mapLoad(). However this gets overridden by the body tags onload and so mapLoad() does not get called and doesnt get instatiated. That is why you get map is undefined.
Basically you have to be careful where you call usePointFromPostcode from. You must make sure that mapLoad() gets called prior to usePointFromPostcode.
so i simply removed the
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != ‘function’) {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
addLoadEvent(mapLoad);
in map.js
and added in my code instead:
window.onload = function() {
mapLoad();
usePointFromPostcode(‘postcode’, placeMarkerAtPoint);
}
as i say this only happens when there is a conflict of the onload is defined in the body tags, or if you do use window.onload = function() in your file to load other scripts you have to change in addLoadEvent
else {
window.onload = function() {
oldonload();
func();
}
}
to
else {
window.onload = function() {
func();
oldonload();
}
}
You see in the orginal script it calls your onload function first rather than the func() (which is the call to mapLoad() which initialise the map varibale) and so the map variable is not defined.
I hope that clears things up….
Eric
caribbean diving holidays
Excellent tutorial! One thing…. any way to stop the map bouncing you to San Francisco when you enter a random string (ie. not a UK postcode) into the search?? Getting this fixed would definitely stop the headaches!!
Additional bit… try searching for ‘yb’….
Hi Tom,
I’m a complete novice at this and I have some developers building a site for me. I wanted to contact you directly to ask you a few queries, but I couldn’t see any way to do this. Would this be ok?
Tim
Brilliant. Just what I’ve been looking for. Saved me hours of work.
Top tips, many thanks. I’ve been banging my head against this for a while!
Excellent tutorial! very nice guys..
Can anyone tell me if this solution is still accurate. I read that Google were downgrading the AJAX local search due to legal reasons and that it would therefore become less accurate.
Is there any truth in this rumour?
i’ve replicated the tutorial exactly but the map doesn’t get created? Has noone else had this problem? I think its to do with the onload business but i’ve tried several ways of calling mapLoad();
It all seems so straight forward and its really frustrating that its just not working! Any help much appreciated!
/// the error;
GlocalSearch is not defined
gmap.js()()gmap.js (line 2)
[Break on this error] var localSearch = new GlocalSearch();
???
Lovely tutorial. Never seen any tutorial like this on the web. easy to use.
Hi Tom, Your tutorial is exactly what i have been looking for in my Honours Project but unfortunatley I cant get it working, I dont even get an error to give me a clue, the map appears on the screen center to where I set but if i search the postcode the page refreshes and the textbox is emptied. Any ideas what could be the problem?
Steven
Dan – have you got both the Google header files included? One for maps and one for local search?
Steven – In the spirit of ‘teach a man to fish’… Install the “Web Developer” Firefox extension and then try this. It has a popup box which provides Javascript errors and is exactly what you need for debugging problems like this. 🙂
Yeah I have the web developer toolbar for firefox and unfortunatley for me it has found no errors with my code. I dont think its the syntax as I have copied your tutorial step for step, it’s not the keys either since i can see the map. the problem has me stumped lol
Thanks tom, I finally got it, I have been developing this in asp.net and with a little trial and error I discovered I can wrap the map and its elements inside an element that has the attribute runat=server.
Great tutorial. Helped alot.
Any idea how to narrow the search to a particular house number?
Steven
Hi
I have a quick query on Google Maps. Is the following statement correct, if so what is the solution to get around this? I.E. How do the likes of http://www.globrix.com/property/buy/edinburgh?ns=true&rd=1&br=buy&qt=edinburgh use googlemaps to plot the accurate placement of homes on the map?
“Google is now capping the number of searches you can do using geocoding which is what is used to convert addresses to long/lat points on the map.
They are doing this to force people to use the actual long/lat code when generating maps”
Hi Tom,
I have one query, there is a requirement to display the alternative of city will displayed suppose some one has entered elton as city name then api will display alternative of elton as ELTON- CHESTER- CHESHIRE,ELTON- LUDLOW- SHROPSHIRE,ELTON- MATLOCK- DERBYSHIRE. can we do this with use of this api.