twitter rss feed

html5 laboratory

Using the Geolocation API to find a users location on a Google map

The experiment

Although it's not part of the HTML5 specification, the Geolocation API is cool enough to be included here. I think so anyway, and so do Remy Sharp and Bruce Lawson who wrote Introducing HTML5, and if it's good enough for them, it's good enough for me.

The Geolocation API provides a very simple way of attempting to determine a users location. It's incredibly easy to use, and in this experiment I will show you how to use the API to find a users location and to mark it on a Google map.

The process

The first thing to do is to check if the browser actually supports Geolocation. As usual, some do and some don't, and some claim to, but actually don't (I'm looking at you latest Firefox - there's a bug in your JavaScript code).

This simple check is performed as follows:

if (navigator.geolocation) {
   // try to get the users location
}

The API

Getting, or at least attempting to get, the users location is incredibly easy. All you need to do is to call one of two functions:

Function Arguments Description
getCurrentPosition successCallback [errorCallback],[options] This function returns immediately, and then asynchronously attempts to obtain the current location of the device. If this attempt is successful successCallback is called with a new Position object indicating the current location of the device. If the attempt fails, errorCallback is called with a new PositionError object indicating the reason for the failure. The options are discussed below.
watchPosition successCallback [errorCallback],[options] This function mimics the behaviour of getCurrentPosition exactly, except that it also informs your code should the position of the device change, thus re-calling either successCallback or errorCallback.
This will continue to be watched until the clearWatch function is called on the watch ID for this particular watch.

The options mentioned above can be as follows:

Option Values Description
enableHighAccuracy True or False This provides a hint that the application would like the best possible results. This may cause a slower response time and in the case of a mobile device, greater power consumption as it may use GPS.
timeout Milliseconds Indicates the maximum length of time to wait for a response. The default is 0 - infinite.
maximumAge Milliseconds Denotes the maximum age of a cached position that the application will be willing to accept.

Putting this together, the code now reads as follows:

if (navigator.geolocation) {
   var timeoutVal = 10 * 1000 * 1000;
   navigator.geolocation.watchPosition(showPositionOnMap, errorMessage,
   { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 });
}
else {
   alert("Geolocation is not supported by this browser");
}

Where showPositionOnMap is the function that is to be called on the successful obtaining of a position, and errorMessage is the callback function when a position is not obtained.

Google Maps

Before we go any further, I'll now talk about displaying a Google map on your web page. First of all you need to signup for Google maps in order to obtain a key. This is a very simple process, and easily done. Once the key is obtained, you need to insert it into the head of your document as follows:

<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=abcdef"></script>

where abcdef is your key.

In order to load the map into your document, you need to first of all create a <div> in which to place the map:

<div id="map" style="width:100%;height:800px;"></div>

And then, when the document is loaded, the map is created by performing the following:

var map = null;
function loadMap() {
   map = new GMap2(document.getElementById("map"));
   map.setCenter(new GLatLng(52.2021, 0.1346 ), 12); // (sets the map centre to Cambridge UK)
   map.setUIToDefault();
}

This means that you either need to use jQuery to call this code when the document is ready, or to declare your body element as follows:

<body onload="loadMap()" onunload="GUnload()">

GUnload() is a Google function that is designed to prevent memory leaks.

The showPositionOnMap function that was mentioned above can now be explained. The purpose of this function is to display the users position on the map itself with a marker. Again this is very easy to do and so the function is defined as follows:

function showPositionOnMap(position) {
   var geoCoords = new GLatLng(position.coords.latitude, position.coords.longitude);
   map.addOverlay(new GMarker(geoCoords));
}

You can read more on the Google Maps API which shows you a lot more than I have here.

The error function, errorMessage, simply translates the returned error codes into a message and calls a simple alert box to inform the user:

function errorMessage(error) {
   var errors = { 
      1: 'Permission denied',
      2: 'Position unavailable',
      3: 'Request timeout'
   };
   alert("Error: " + errors[error.code]);
}

The complete code

As always I've provided a Geolocation API example which uses all the code above to attempt to pinpoint your location on a Google map. I've used getCurrentPosition rather than watchPosition so it will only attempt to get your position once. I have tested it with watchPosition on my Android phone and as I moved about, it added different markers on the map each time, which is rather nifty (if you want to test that one, Geolocation API example 2 uses watchPosition).

I've only managed to get this to work on my Android phone, although I suspect that it will also work on the iPhone. Every browser I've tried as given me a “position unavailable” error, except for Firefox which throws a JavaScript error within it's own NetworkGeolocationProvider.js file, so basically it doesn't work.

The results

All in all the Geolocation API provides a very simple method of locating a user's position and potentially providing them with location specific information based on that. It's easy to use and looks after itself.

For further information, check out using Geolocation over on the Mozilla developer centre, or take a look at the Geolocation API specification itself over at the W3C.