The Geolocation API is one of the most exciting new features of HTML5 for us GIS folk. In this section we’re going to look at how geolocation works, what capabilities it offers us and show how easy it is to build an application to retrieve the users location.
What is the Geolocation API?
So what is the Geolocation API? Well, the first thing to note is that Geolocation is not actually part of the HTML5 spec, but it’s mentioned so often in conjunction with HTML5 you could easily be fooled into thinking so. In a nutshell, the Geolocation API provides simple but powerful methods of both acquiring and using location data in web pages. That is, making web pages ‘location aware’.
The user’s location can be derived from a number of different sources depending on the technology they are using. For obvious reasons, this is mainly targeted at mobile devices – for the simple reason that they tend to change location frequently – but still works on the desktop.
The methods used for determining a user’s location include:
Geolocation is Device Dependent
Obviously this makes geolocation very device dependent.
The web browser or device works out what methods are open to it for determining location and then – importantly from a security perspective – the user is required to opt-in to start sharing their location data. What they opt in to is dependent upon the type of device they are using – whether it supports GPS, wi-fi, etc.
Because of these security considerations, most browsers will not let you run geolocation code on a local file system – it has to be delivered by a web server. So you will need to have access to a web server like IIS or Apache to start working with the Geolocation API.
Working with the Geolocation API
The Geolocation API is very simple to use. First, you need to make sure that the browser you are targeting supports Geolocation. You could go to a website like caniuse.com but clearly a more robust solution is to check programmatically at runtime. If geolocation is not supported you can fail gracefully or consider alternatives as previously discussed.
If geolocation is supported, you need to access the navigator.geolocation object which provides the methods that will determine the user’s location. Which method you call on the geolocation object will depend on whether you want to just grab the location as a one-off or monitor it continuously.
Whichever method you choose you will need to create callback functions to handle the results whether they be successes or failures. A callback function is a function that you pass by reference into a method. When the method completes it can then call back that function, passing in any required data.
Then, you need to do something with that data. And, being GIS folks we may just want to put it on a map!
Let’s build a simple geolocation application. We’ll start by building a simple HTML page.
As you can see from the above, my page consists simply of a heading and a blank paragraph element. I’ve given this element an ID of ‘myLocation’ so I can write information to it.
Within my body tag I am capturing the onLoad event. I want to make sure that all the DOM elements are loaded before any script I write attempt to interact with them. The event handler for this is the init() function in my script tags, which simply reports that the event has been fired and captured.
So the first thing we need to do is determine whether the browser supports the Geolocation API.
Within my init() function (code below) I have written some code to check for the existence of the navigator.geolocation object. If this object is null, the if statement will return false and write a message to the myLocation paragraph saying that Geolocation is not supported. But if the object exists, we can continue to work with the Geolocation API and we’ll write a message out to the user telling them so.
The next thing we need to do is call a method on our navigator.geolocation object and attempt to gauge the user’s current location.
There are two methods we can call to achieve this: getCurrentPosition() and watchPosition(). We’ll look at getCurrentPosition() first.
getCurrentPosition() is a one-shot: it retrieves the user’s location details once and that’s it. You might want to use this method if you are trying to locate the user’s nearest doctor or retail location.
watchPosition() is for tracking the user. It gets called continuously and returns new results every time the user changes position.
We’ll start off by using getCurrentPosition(). As you can see in the code below, I’ve created a local variable to store a reference to the navigator.geolocation object and specified two callback functions in the call to getCurrentPosition – one for success and one for failure.
I’ve stubbed out those functions with just an alert box to show us which function gets called. You’ll notice that both are passed an object as a parameter. These contain the results – in the case of successful location retrieval – or error details if otherwise. We’ll implement them in a bit.
First of all, let’s see what happens when we run this. I’m going to copy this html file to my web server – which I need to do for security reasons – and then launch it from that location in my browser.
I’m running Google Chrome, but your experience should be similar with any Geolocation-compliant browser.
The first thing I see is a notification that my web server (localhost) wants to track my physical location. If I press deny, my error handler gets called and I get a message saying that there is an error.
If I press Allow, then I get a message saying that there have been some results – in other words, the browser has managed to guess my position based on one of the device-specific options available to it.
Let’s now unpack those results and see what it came up with. If I analyze the object that gets passed through to my callback function I learn that it is an object of type GeoPosition and I can see how to unpack its coords collection and display my current position which is what I’ve done in the code example.
You’ll also observe that there are other entries there for heading, speed, etc which are not relevant to getCurrentPosition() but do make sense when we’re doing continuous monitoring using watchPosition(). The other main property on the Geoposition object is the timestamp. We can parse this to ascertain when location retrieval occurred.
Let’s see how accurate that result is, by plotting it on a map. At the time of writing I’m sitting with my laptop with wireless disabled in a town called Bicester (pronounced ‘Bista’) in the UK. Geolocation however, thinks I’m right in the center of the city of Oxford, about 12 miles away! It must be using my IP address in its calculations – not terribly accurate as you can see.
Now if I turn on Wireless, I get much better results. This time geolocation has positioned me about 20 meters away from my actual position.
However, if I connect my laptop to a GPS unit via Bluetooth I get much better results – bang on, in fact!
Tracking with watchPosition()
As mentioned earlier, the other method you can use to retrieve location details is watchPosition(). The syntax for watchPosition() is very similar to getCurrentPosition(). It requires callback functions for success and failure but also lets you specify an options object. This options object gives you access to three settings:
Timeout: the amount of time (in milliseconds) your application should wait to retrieve location details before raising an error
enableHighAccuracy: this setting is false by default. When set to true, geolocation will use every means at its disposal to retrieve the most accurate results. As a general rule, if you’re doing tracking with a mobile device (and it’s fairly unlikely you will be – think about it for a moment!) you should set this to ‘true’. Otherwise any GPS capability on your device may not be enabled and you’ll get sub-standard results.
maximumAge: This is the longest a current location value should remain cached before forcing retrieval of a new value.
Note that when we call the watchPosition() method we’re storing the return value in a variable called WatchID. WatchID contains a unique ID we can use to turn off tracking. We just call clearWatch() and pass in that ID to do this.
In our last post we introduced the topic of HTML5 for GIS web and mobile developers. This post is a continuation of our HTML5 series of posts.
HTML5 introduces the new concept of ‘semantic markup’.
HTML5 introduces new semantically rich elements that can convey the purpose of the element to both developers and browsers.
In order to arrive at these, the W3C undertook a huge mining operation of billions of pages to see which Ids and Class attributes page developers were using to provide meaning to their <div> tags. After throwing out the nonsensical ones, they saw various usage patterns repeated over and over again and implemented these as brand new elements within HTML5.
These new tags help to provide both structure AND meaning to our web pages as can be seen in the markup sample below.
When to Use Semantic Tags
So do these new elements replace the <div> tag? No, they don’t. But they can provide more meaning than a <div> tag if used correctly – both to developers and browsers.
Bear in mind when using the new HTML5 tags that you are not obliged to use them to make your document valid HTML. In fact, often it won’t make sense to use them. For instance, we probably don’t want to re-purpose our map control, so we can still carry on using <div>s with appropriate ID and class names to define their meaning.
However, these semantic tags are very useful for common page elements such as those in the typical web page structure shown on the left in the image below. Let’s look at some of these in more detail and then we’ll show them in action in a demo.
The <header> and <hgroup> Tags
From the HTML5 spec, the <header> element (not to be confused with the <head> element) refers to :
“a group of introductory or navigational aids. A header element typically contains the section’s heading (an h1–h6 element or an hgroup element), but can also contain other content, such as a table of contents, a search form, or any relevant logos.”
A good place to include a header is at the beginning of your page as shown in the first piece of markup below. But you are not limited to just one header element per page. You can use multiple headers, each of which will then become the <header> for a new section of the document. This is semantic markup in action. Your browser understands how your content is organized and other user agents could re-purpose that content if required.
If you have only got a simple title with a single heading element (<h1>–<h6>), you do not need an <hgroup>.
If you have a title with subtitle(s) or tag lines (i.e., more than one consecutive <h1>–<h6>), group them in an <hgroup>.
If you have a title with subtitle(s) and other metadata associated with the section or article, place both the <hgroup> and the metadata within a single <header> element.
The <footer> Tag
The <footer> tag is similar to the <header> tag in that it can be used in the whole page or in individual sections. However, the footer tag denotes the end of the page or section. (Actually, the <footer> tag does not have to be at the end of the page or section, but it usually is.)
The footer tag can be used to give information about who wrote the section, copyright information and perhaps even links to related resources. Note how we’ve used another new semantic tag in HTML5 – the <address> tag – to include contact information.
The <nav> Tag
Use the <nav> tag to define an area of your page containing major links to other areas of your site.
Not all links need to be hosted within your <nav> tag. For instance, the <footer> element discussed earlier is often used for links to key parts of a site
I think it’s fair to say that there is still a bit of confusion around when to use the <nav> tag. Perhaps a useful test would be this: If you were building your page in HTML4, would you consider including a <div> with an id of ‘nav’ or similar? If so, you probably need a <nav> tag!
The <section> Tag
It’s tempting to use the section element to wrap content to style it, or to somehow distinguish your main content from the other areas of your page such as the <header>, <nav>, <footer> and so on. However this is wrong! You could (and should) use a <div> instead.
In general, a section is just a piece of content which you could store as an individual record in a Content Management System. Not all content lends itself to being a section, so if in doubt just use a <div>.
Here are some rules of thumb for using the <section> element:
Don’t use it just as hook for styling or scripting; that should be a <div>
Don’t use it unless there is a natural heading at the start of a section
Don’t use it if another tag like <article> or <aside> would be a better fit
The <article> Tag
The <article> tag is one of the easiest ones to get your head around. Basically, it’s just a self-contained piece of prose that would still make sense if you took it out of the page and, say, copied it into Notepad. And that’s the whole idea behind the <article> tag, that it could be used to repurpose content.
Think in terms of news stories, blog posts, etc.
The <aside> Tag
The <aside> tag defines content related to but not included in the content that surrounds it.
So to use the <aside> tag correctly, you need to consider what element on the page it is providing more information about.
The W3c recommends the following usage pattern:
When the <aside> tag is used within an article element, it needs to be related to the article.
And when it is used outside an article it needs to relate to the site as a whole.
For more information on the use of semantic tags and other HTML5 topics for GIS web and mobile developers please consider our HTML5 and CSS3 for GIS Web Developers course.
2010 – HTML5 Takes Off
Google, Microsoft and Apple have all been shouting from the rooftops about HTML5 since around 2010 and have already started implementing HTML5 features in the latest versions of their browsers even though the standard won’t be complete for several years yet. You can test support within your current browser at www.html5test.com. Whether HTML5 will be the saving grace of the web remains to be seen. What is certain though is that the public interest in HTML5 is huge and growing all the time.
2015 – Final Specification Due
HTML5 is an evolving standard which is not expected to be finalized until 2015. For an amusing countdown visit http://www.ishtml5readyyet.com. With browser manufacturers competing to adopt HTML5 features right away, this means that there is likely to be a fair bit of discrepancy around how HTML5 is implemented. Nevertheless, HTML5 is here. Whether it will really achieve as much as is claimed remains to be seen, but as Web GIS developers we need to know about this stuff!
So What Exactly is HTML5?
HTML5 is not exactly a new standard, because it really is just a loose collection of enhancements that have or will be made to the HTML 4.01 spec. It’s just easier to refer to these collectively as HTML5.
It’s not like the internet needs to upgrade. Everything that was coded in HTML4 continues to work quite happily without modification. However, as browsers continue to adopt new features offered by HTML5, web developers will be more inclined to use them – either to take advantage of new functionality, or to make it easier to accomplish what they could already do in HTML4.
Key New Features of HTML5
Let’s cover some of the core enhancements offered by HTML5 which developers can start to use right away in supported browsers.
First of all, HTML5 introduces a whole bunch of new tags. Some of these are what are known as ‘semantic’ tags which allow other computers to discover not just what a page element is but what it means which makes it easier to re-purpose content. We’ll cover semantic tags in the next post in this series.
There are new tags for embedding audio and video in a web page without relying on plugins like Flash and Quicktime.
There is improved support for forms such as auto-completion as the user types and automatic focusing on fields to make data entry easier.
There are new APIs, or Application Programming Interfaces too which encapsulate brand new functionality.
The Canvas API allows you to draw rich graphics natively within the browser and apply gradients, fills and other effects.
The Geolocation API can provide the location of a connected device via its IP address, by triangulation with local wi-fi hotspots or GPS (if supported)
Local Storage improves on the current idea of using ‘cookies’ – small data files that are stored on the user’s hard drive to persist session information, user preferences and so on. In HTML5 you can store up to 5MBdata locally, making it possible to improve performance by caching. For example, you could store a document locally as the user edits it before submitting the changed version to the server.
Offline Web Applications – as demonstrated in the past by Google Gears – let users run our web applications without being connected to the Internet. HTML5 coordinates the download of all the data they need and its subsequent upload when they are back online.
In the next post in this series we’ll cover semantic markup in HTML5.