Tuesday 12 June 2012

HTML5 - Geolocation

After my last blog post, I thought I'd take a look and see what this geolocation melarky is all about.

As it goes the API is extremely simple and easy to use which makes blogging about it pretty straightforward.

The aim of the API is to get the longitude and latitude of the device that is accessing your website. This information can then be fed into another application to make it more user friendly. For example, a common use for this information is to put it into Google Maps to show exactly where your user is.

So, how do we use this API?

First off we need to make sure that the browser supports geolocation. To do that, we simply need to check that the navigator.geolocation object exists. That can be achieved with the following:


if(navigator.geolocation){
   // Do Geolocation Stuff
}


All straightforward so far. So now it's time to grab the longitude and lattitude. There are two methods available within the API to accomplish this: getCurrentPosition and watchPosition. getCurrentPosition runs once and gives you the users location. watchPosition will continually run, allowing you to track the user as they move. Both run asynchronously. There is one final method included in the API, clearWatch. This method allows you to stop tracking the users position after you've called watchPosition.

Now let's have a look at these methods in a bit more detail.

getCurrentPosition

The function definition:

getCurrentPosition(successCallback, errorCallback, options)


The success and error callback parameters explain themselves. The options parameter allows the developer to specify the timeout value, the maximum age of a position call (basically, how long it lives in a cache) and how accurate the position call will be.

To determine how accurate the position call will be you need to understand how geolocation works. There are a variety of ways in which a users location can be worked out, as listed below.

  • WiFi - Accurate to 20 metres. The MAC address of any and all WiFi access points detected by the users device is sent across the web and mapped against a database of wifi access points and locations. From what I can find out, different browsers use different databases. For example, Chrome and Firefox use a database created by Google. Safari however uses Skyhook's Wireless service.
  • IP - Accuracy varies greatly and can give false information. In this instance, an IP address, or a range of IP addresses are mapped to locations within a database. Unfortunately, due to the nature of IP, addresses and locations change and occasionally IP addresses can get mapped to a completely wrong location.
  • GPS - Accurate to 10 metres. This method only works outside so is only ever an option with a mobile device. GPS is quite an advanced system, if you're interested in the gritty details of how it works, have a read of this. This method unfortunately can take a bit of time and can use more power which may be important if you're target device is a mobile phone/tablet. It is however, the most accurate out of all of the geolocation methods.
  • GSM/CDMA IDs - Accurate to 1km. This will take unique ID of your mobile device and will use it against the local mobile phone towers to triangulate your position. Accuracy will significantly improve where there are more towers, so, if you're in an urban area, accuracy will be far greater than if you're in a rural area.
Ok, so, here's an example of using the getCurrentPosition method:


var success = function(position){ 
    alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude); 
};

var error = function(error){
    alert("Error. Cannot find your position");
};

navigator.geolocation.getCurrentPosition(success, error, { enableHighAccuracy: true });


The enableHighAccuracy option essentially means that the method of determining the users position that provides the highest accuracy will be used. This only really matters when your user is using a mobile device with GPS. GPS uses more battery power than the other methods and can take a couple of minutes to return so may be something you want to avoid where possible.

watchPosition
The function definition:

watchPosition(successCallback, errorCallback, options)


Look familiar? It should do. It's exactly the same as the getCurrentPosition method, with one small difference. This method will return a watch ID. The watch id is then passed into the clearWatch method to stop tracking the users position, but more on that in a bit.

So, like I said, the purpose of this method is to track the users position. When they move, assuming that no errors are thrown, your successCallback will be called. This callback takes the exact same parameters as the getCurrentPosition successCallback function did so, you can grab the new longitude and latitude co-ordinates and use them for whatever you need.

Just as a very quick example of the use of this:


var success = function(position){ 
    alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude); 
};

var error = function(error){
    alert("Error. Cannot find your position");
};

watchId = navigator.geolocation.watchPosition(success, error, { enableHighAccuracy: true });


clearWatch
The function definition:

clearWatch(watchId)


Pretty simple eh? This effectively cancels your watchPosition call made earlier. So, as an example, you could have something like this:


var success = function(position){ 
    alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude); 
};

var error = function(error){
    alert("Error. Cannot find your position");
};

watchId = navigator.geolocation.watchPosition(success, error, { enableHighAccuracy: true });


function stopTracking(){
  if(watchId != null){
    navigator.geolocation.stopWatch(watchId);
  }
}


You can then call the stopTracking function from wherever you want.

And that's about it for the API. If I'm honest, its simplicity surprised me. I personally think that location based services will really take off in the next year (if they haven't already) as HTML5 becomes the standard on more and more browsers. Location information opens up a world of possibilities, from helping you to find your friends in a crowd to providing more relevant information to you when you're performing web searches. Now that the technology is there, it's up to us developers to use it to give our users the best possible experience.

Before I sign off though, I should mention one thing regarding location services and it involves one of the 'keywords' being spoken about all the time at the moment.... privacy.


Google Chrome prompting the user.
Obviously, tracking a user's current position does come with a few privacy concerns. Web browsers have done what they can to address this by ensuring that when you request a users position, either via the getCurrentPosition or the watchPosition method, that the user is notified and they are then given the option of denying you access to that data. (If this occurs, your error callback will fire rather than your success callback.) However, this in my eyes isn't enough. I think websites should take a bit of responsibility too!

Ok, here comes a bit of a rant so feel free to stop reading here but a pet peeve of mine is sites that do request my location information and then use it for something that isn't stated on the tin. Take for example Facebook: Now and again I may want to publish where I am in the world so my friends can see for whatever reason. So, when I go to publish my location the website prompts me that Facebook wants to access my location data. Not a problem, how else are they going to publish my current location? What I do not then expect is for my location to be posted on everything afterwards. Especially when I've gone to the pub instead of heading home! Facebook doesn't just do it after you've published your location - it updates your location whenever you make a comment or a status update and as far as I'm aware, there's no easy way stopping that from occurring.

Now I'm sure Facebook has some setting somewhere that lets me turn it off for posts but I shouldn't have to. I agreed to let Facebook access my data to do a specific task that could not be accomplished without that data. I did not agree to let Facebook plaster it over every post/comment I subsequently make. I'm sure Facebook isn't the only culprit here and I understand that if you throw up a configuration option for each and every action then it's going to become pretty tedious. But, if I had been notified of their intentions at the start then I may not be ranting.

Ok, rant over. In conclusion to that little out-burst... just make sure your users know why you need their location data and exactly what you're doing with it. If not for your users benefit, then do it for your own as I'm sure someone will be ranting about your website if you don't.

No comments:

Post a Comment