Sunday 30 October 2011

html5 Geolocation

I'm quite fascinated by the geolocation API that is contained within html5. One thing I love about my iPhone is that I can find things around me quickly, even if I don't where I am. I've used the Google Maps API a couple of times for Contact Us pages. I love that I can make a JavaScript call to produce an interactive map and insert it into a containing div, and have a static image of the area so that if the user doesn't have JavaScript (or has it disabled) they can still have an experience comparable to the JavaScript user. I thought it would be quite cool to use the JavaScript API to produce a map based the user's current location. Take a look at the finished result here. Details after the jump.


First, you need to include the Google Maps JavaScript API in your head element.

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=true"></script>

The sensor parameter lets Google know whether or not the user will be using some kind of device to determine their location. As this page is going to show the user where they are on a map they will be required to us some kind of sensor, probably GPS. When I've written Contact Us pages I've set it to false as I knew the coordinates for the only marker required, and so hard coded them.

I'm using the jQuery library to navigate the DOM. I don't really need to for this example, but it does help to shorten the code line lengths. I always use the Google copy of the library so that the browser doesn't have to download multiple copies of the same document. There are lots of blogs out there that detail the pros and cons of this method, but I try to save bandwidth wherever possible. I'm primarily a mobile user and try to save data costs as much as possible (and wish other developers did too).

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

The HTML document is pretty basic, as the JavaScript injects the map.

<!DOCTYPE html>
<html>
<head><!--Scripts here-->
</head>
<body>
<p id="support"></p>
<!--The width and height must be set for this container div, otherwise it will be 0x0 and hide the display of the contained map-->
<div id="map_canvas" style="width: 500px; height: 500px;"></div>
</body>
</html>


The first thing that my own JavaScript does is to check whether or not the user has the geolocation functionality enabled. If not, it populates the contents of p#support with a warning to the user.

$(document).ready(function() {
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(updateLocation, locationError, {enableHighAccuracy: true});
} else {
$("#support").html("HTML5 Geolocation is not supported in your browser.");
}
});


If the user does have geolocation enabled then it sends a call out to get the details of where the user is. The function navigator.geolocation.getCurrentPosition() has three parameters. The first is mandatory, and is the function that will be called when the position has been successfully acquired. The second is optional and is the function to be called when the position has not been successfully acquired. The third is also optional. This is a notation of options to provide the browser with to clarify how you want it to behave. I've set enableHighAccuracy so that the browser uses the most accurate position it has available. This value defaults to false.

When the call is unsuccessful, I put an error message into p#support, depending on the error that is returned.

function locationError(error){
$("#support").html("HTML5 Geolocation is not supported in your browser.");
switch(error.code){
case 0:
$("#support").html("There was an error retrieving your location: " + error.message);
break;
case 1:
$("#support").html("User permission for location is denied: " + error.message);
break;
case 2:
$("#support").html("The browser is unable to determine your location: " + error.message);
break;
case 3:
$("#support").html("Timeout: " + error.message);
break;
default:
$("#support").html("Unknown error: " + error.message);
break;
}
}


I've included a default so that if there are more error codes in the future then we will still receive feedback as to what went wrong. Hopefully though, we'll never need to use this function at all. If the user grants us permission and the browser can find a location of some kind it will call the success function instead.

function updateLocation(position){
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: "You are here!"
});
}

This is where I use the Google Maps API. First of all I take the latitude and longitude from the browser and create a Google Maps LatLng variable. I create an array of options to provide Google with in order to create the map. The zoom level is something I decided on by choosing a level, viewing it, and then trying another. I wanted to use a road map type as that produces smaller images for mobile users to download, and provides a clearer impression of where the user is.

These details are sent using the API to place the map in the given container element. I tried using jQuery to navigate the DOM and send it, but it threw an error. Changing it the standard JavaScript method worked a charm. After the map has been created I added a marker to it. The map was already centered on the user's location, but the marker makes it obvious.

No comments:

Post a Comment