Finding your position with Geolocation

by .

The Geolocation API provides a method to locate the user’s exact (more or less – see below) position. This is useful in a number of ways ranging from providing a user with location specific information to providing route navigation.

Although it’s not actually part of the HTML5 specification, as it was developed as a separate specification by the W3C, rather than the WHATWG, if the esteemed HTML5 Doctors Remy Sharp and Bruce Lawson felt it was fitting enough to include in their book, then it’s perfectly ok to write about it here.

The API is actually remarkably simple to use and this article aims to introduce the API and show just how easy it is.

Browser Compatibility

Currently the W3C Geolocation API is supported by the following desktop browsers:

  • Firefox 3.5+
  • Chrome 5.0+
  • Safari 5.0+
  • Opera 10.60+
  • Internet Explorer 9.0+

There is also support for the W3C Geolocation API on mobile devices:

  • Android 2.0+
  • iPhone 3.0+
  • Opera Mobile 10.1+
  • Symbian (S60 3rd & 5th generation)
  • Blackberry OS 6
  • Maemo

Data Protection

The specification explicitly states that since the nature of the API also exposes the user’s location and therefore could compromise their privacy, the user’s permission to attempt to obtain the geolocation information must be sought before proceeding. The browser will take care of this, and a message will either appear as a popup box, or at the top of the browser (implementation is browser specific) requesting the user’s permission.

Screenshot of Safari's popup box asking for Geolocation permission
Safari asking the user for permission to obtain their Geolocation information

Geolocation sources

A number of different sources are used to attempt to obtain the user’s location, and each has their own varying degree of accuracy. A desktop browser is likely to use WiFi (accurate to 20m) or IP Geolocation which is only accurate to the city level and can provide false positives. Mobile devices tend to use triangulation techniques such as GPS (accurate to 10m and only works outside), WiFi and GSM/CDMA cell IDs (accurate to 1000m).

Using the API

Before you actually attempt to use the Geolocation API, you first need to check if the browser actually supports it. The API usefully provides a function for this which can be called as follows:

if (navigator.geolocation) {
  // do fancy stuff
}

Obviously if this returns false, you should optionally inform the user of the inferiority of their browser and laugh in their face (not really).

Through the API, there are two functions available to obtain a user’s location:

getCurrentPosition and watchPosition

Both of these methods return immediately, and then asynchronously attempt to obtain the current location. They take the same number of arguments, two of which are optional:

  1. successCallback – called if the method returns successfully
  2. [errorCallback] – called if the method returns with an error
  3. [options] – a number of options are available:
    • enableHighAccuracy – 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. Boolean with a default setting of false.
    • timeout – indicates the maximum length of time to wait for a response. In milliseconds with a default of 0 – infinite.
    • maximumAge – denotes the maximum age of a cached position that the application will be willing to accept. In milliseconds, with a default value of 0, which means that an attempt must be made to obtain a new position object immediately.

Before mentioning the differences between the two, another method needs to be introduced:

clearWatch

This method takes one argument, the watchID of the watch process to clear (which is returned by watchPosition)

Now, the main difference between getCurrentPosition and watchPosition is that watchPosition keeps informing your code should the position change, so basically it keeps updating the user’s position. This is very useful if they’re on the move and you want to keep track of their position, whereas getCurrentPosition is a once off. This method also returns a watchID which is required when you want to stop the position constantly being updated by calling clearWatch method is called.

When the user’s position is returned, it is contained within a Position object which contains a number of properties:

Property Details
coords.latitude Decimal degrees of the latitude
coords.longitude Decimal degress of the longitude
coords.altitude Height in metres of the position above the reference ellipsoid
coords.accuracy The accuracy in metres of the returned result. The value of this setting informs the application how useful the returned latitude/longitude value actually is. This can help in determining if the returned result is accurate enough for the purpose it is intended for, e.g. values for streetview locations will need to be more accurate than those for a country based location
coords.altitudeAccuracy The accuracy in metres of the returned altitude
coords.heading Direction of travel of the hosting device, clockwise from true north
coords.speed The current ground speed of the hosting device in metres per second
timestamp Timestamp of when the position was acquired

Amongst these only which is coords.latitude, coords.longitude and coords.accuracy are guaranteed to be returned (all others may be null), and the first two are by and large the most relevant, as it is from these that a position can be plotted on a Google Map, for example.

You can read more about the Position object and the coordinates interface on the W3 specification itself.

Putting it all together

Putting this altogether, the following code will attempt to obtain a user’s location, calling the method displayPosition on success which simply pops up an alert box with the captured latitude and longitude:

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

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

The code above also calls the displayError method when attempt to fetch the user’s location data. This function simple converts the returned error code to an appropriate message:

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

A final word

This is just a simple introduction to using the Geolocation API and one of it’s uses.

Of course the API can be used for more than simply plotting a position on a map (although that in itself is quite useful). The specification itself offers a list of potential use cases for the API such as:

  • Finding and plotting points of interest in the user’s area
  • Annotating content with location informationShowing a user’s position on a map (helping with directions of course!)
  • Turn-by-turn route navigation – using watchPosition
  • Up-to-date local information – updates as you move

Examples

To see geolocation in action, I’ve put together a couple of quick examples in which I encourage you to view source and then go and try it out for yourself.

40 Responses on the article “Finding your position with Geolocation”

Paul Irish says

Chrome seems to prioritize a more rough result first, whereas Saf/FF deliver a first result a touch slower, though it’s more accurate.

Therefore, for best results in Chrome and other browsers that deliver results as they get them, I’d suggest watchPosition with a 10s timeout or so, instead of gCP.

Gonzo says

The accuracy of the initial result from getCurrentPosition() or watchPostion() depend highly on the WiFi networks in the area. In my experience Firefox, Opera and Chrome will first use WiFi information to get the position, and sometimes it gives 100m accuracy, which is pretty good. In most cases the accuracy will be much worse – 700 or more than 1000 meters.

I use the following technique to get good enough position: call watchPosition() and in the success callback observe the accuracy and if it is less than 500 in my case, clearWatch() and use the position information.

Matt says

Mobile devices don’t use “triangulation,” they use “trilateration.” Triangulation (as its name implies) uses angles from a variable point to known fixed points. Trilateration uses distances from a variable point to known fixed points. This is an incredibly common misnomer.

Oli Studholme says

Great intro Ian! Just one thing to add that I’ve personally noticed: GPS accuracy can be significantly decreased by the canyoning effect in built-up areas.

Ian Devlin says

Thanks for all your comments which only enhance the article. Personal experiences are always quite valuable.

gilles faessler says

Great article, have to make some test to see if accuracy improved because this is the main issue with these methods

Craig McPheat says

Has anyone written a privacy policy pertaining to geolocation?

Mickey Mouse says

Good article, but you need better proofing.

Also, what is this? var timeoutVal = 10 * 1000 * 1000;
Seems a bit too long if it’s miliseconds.

James says

Busted! Both apps say, “Permission denied” and won’t run. :-(

Ian Devlin says

@James, on which browser/device is this happening? Some mobile devices don’t ask for permission automatically and have settings that need to be changed in whatever menu they offer.

Kristof Van den Branden says

Hi,
We are doing some tests with HTML 5 geolocation and our code already works really well on Android and iPhone browsers: we get a continuous update of our precise position on Google maps. You can check our code here: http://93.113.255.166/testHTML5.htm

We also want to make this code work on a Blackberry device, the 9780 Bold with Blackberry 6.0 O.S., but it doesn’t work as we would like. The position you get is a rough one, probably calculated through cell triangulation, and there is no precise position displayed. The position is most of the time some 300-400m wrong.

It’s clear that the GPS positioning of the phone isn’t used, because when you try the native Blackberry positioning apps, you get a very precise position.

We also use the enableHighAccuracy: true attribute in the code: this helps for the iPhone and Android browsers, but not for Blackberry browsers.

So it seems that we are unable to force the device to use the GPS. Is there anybody who could help us? Thanks!

Kristof

Alin says

moncler ist auf der Parzelle, von der Fury in langen unten Wallace Jacke Marke, kalte Winter, und dann für Ihre warme und kalte Dinge ausgewählt.

Jason Curby says

I certainly believe geolocation will become entwined with everything we do online in a way that will enhance user experience (or location-based spam), but I worry about the privacy implications of such integration. Even though you have the option to disable it, sooner or later users will not be able to say no to its sheer usefulness!

Thanks for the write-up, am still getting my head around geolocation code!

Mike says

It working on FF, Chrome, Opera BUT

Safari 5.1.1 it’s not !-(

And this happens with all location based websites, not just yours.

It amazes me that Chrome (also Webkit like Safari) works and Safari don’t…

Ian says

Hi Mike, thanks for your comment.

You’re right, it doesn’t currently work on Safari, although it used to! I’ll have to look into it.

Kangbud says

I tested the example using Firefox 9 and latest Chrome, but both don’t detect my location. I give permission to the browsers to Share Location but it say “error: Position unavailable”. Do you know what’s the problem ?

Barani says

Hi , me also have the same problem “Position unavailable”. Why it’s happened and what is the solution for this? My browser supports Geolocation.

Mat says

I started using “navigator.geolocation.getCurrentPosition()” a few months ago with great success. However, I’ve just noticed that both Firefox and Chrome are returning “Position Unavailable” for all requests, unless I use a WiFi enabled machine.

IE9 returns a location, but it’s wildly inaccurate (out by over 50 miles… based on IP address I guess).

Does anyone know if there are long-term problems with Google’s service (which is shared by Firefox, I believe).

Gonzo says

Mat, if you are trying to get the location of a device without wireless – WiFi or GSM – the only way to get it is by it’s IP, which at best returns the city.

Mat says

Gonzo… that’s kind of my point: “IE9 returns a location, but it’s wildly inaccurate (out by over 50 miles… based on IP address I guess).”

…but at least IE9 is coming up with something. Firefox and Chrome are simply returning nothing. Last time I checked on a non-wireless machine they did return a location.

So what’s changed at Google? Location to within 50 miles is pretty useless, but it’s better than nothing (maybe).

Joseph Elfelt, the Gmap4 guy says

I just tried my geolocate code on my non-wireless desktop. It works just like it always has. The geolocate codes runs fine and my app displays: Location accuracy = 26.10 miles, 42.00 km
We actually live ~4 miles from the latlng determined by the geolocate feature.

FF10 and Chrome gave identical results. My IE8 does not support geolocate.

You can try my code if you wish:
http://www.mappingsupport.com/p/gmap4.php
and then Menu (upper right corner) ==> Find me

Mat says

Joseph,

That’s strange. I’ve just tried your link using Chrome and FF10 on my laptop (after disabling wireless) and both give the same result: position unavailable (with wireless on the result is very accurate).

Using Chrome on a desktop at the same location also gives the same result: position unavailable.

I then tried from a desktop (actually a terminal server) at one of our other offices 40 miles away and got a decent result.

I can’t figure out the criteria that determines when a location will be returned — but there are definitely a whole bunch of desktops here that don’t work.

Joseph Elfelt, the Gmap4 guy says

Matt,

I should have mentioned that my browser app (Gmap4) uses the Google Map API. In order for the app to work, the browser has to be online. You likely took your laptop offline when you disabled its wireless.

Mat says

Hi Joseph,

Nope… that’s not it. My laptop is connected by Ethernet and wireless — I just dropped the wireless.

Besides, that wouldn’t explain why all the other desktops at this site don’t work with Chrome or FF.

It can’t be a firewall issue because the access points are behind the same firewall as the desktops.

It’s bizarre, but I’m determined to get to the bottom of it. I’m going to run some more tests, but as it stands, it looks like you can’t assume anything about geolocation.

Robbiegod says

I noticed that when i use geolocation it will find me the first time i go to the page. I’m using Chrome v17.0.963.56 m. Latest version of Chrome.

So i go to a page that uses geolocation in Chrome and it works the first time i visit, meaning i get the prompt and i say ok to giving my location to the browser. But, if i refresh this same page, then the geolocation no longer works.

I can close the browser and re-open it and its still not able to find me.

What I have to do to get it to work is clear the geolocation settings in the browser….So, I’m wondering is there a way to clear the geolocation settings when a person exits my page?

And, I also plan to write some fallback content so a person can choose there location if i can’t detect it via a drop down menu.

My guess is this is probably what is happening to all of you. You are returning to the page after giving permission to be geolocated. Then when you return it doesn’t work anymore.

try clearing the geolocation settings and then going to the page again, my guess is it will all of a sudden work.

Tawheed says

Nice tuts, Ian. I was wondering where I could find the link to the code for the working example.

Rick Corbit says

navigator.geolocation.getCurrentPosition works great for me in chrome and firefox as well as all mobile clients, but for some reason safari on the desktop returns my last location all the time no matter what I set the maximumAge (cache settings) to.

For example:
- If I’m in city a,b,c,d,e,f etc. and at each location I run the script
- while in city b i get the location of city a and while in city c I get b and so on.

this seems kind of weird especially since it only happens in safari 5 on os x.

my timeout is set to 20000 and I also tried wrapping the call in a setTimeout (as suggested on stack overflow) to no avail.

anyone have similar experiences?

thanks all!

eewrwe says

dfsdfsfsd

austin says

Nice script and it works very well. But i’am trying to add some markers from klm file or array. I don’t write javascript, so every attempt for putting such lines into your script, it does not work.

Where can i put the following lines to add some personal markers?
And these additional markers should be clickable too, for opening another web page!!!


var coords = [
[54.97784, -1.612916],
[55.378051, -3.435973]
// and additional coordinates, just add a new item
];

// iterate over your coords array
for (var i = 0; i < coords.length; i++) {
// create a closure for your latitude/longitude pair
(function(coord) {
// set the location...
var latLng = new google.maps.LatLng(coord[0], coord[1]);
// ...and add the Marker to your map
var marker = new google.maps.Marker({
position: latLng,
map: map
});
})(coords[i]);

I tried it as function too, but don’t know how to initiate it – but when i tried, the whole script does not work any more. I am sorry, please, can you help me?

thank you
Austin

Kinergy says

In my mobile (iPhone/Android) HTML5 app I require the user location for certain functionality. I know how to detect if I can’t get the location, however, if the user has previously clicked Deny, is there a way to ask iOS/Android to ask the user for permission to share geo location again? The alternative I guess is to start writing up tedious instructions and explain to the user how to reset the previous deny decision.

blat says

accuracy units? Its meters, or another units? For example I have accuracy 56.. It is 56m?

David says

Hi.

In safari 5.1.5 doesn’t work (you say is compatible Safari 5.0+).

But why I don’t get position:

function initiate_geolocation() {
alert(“initiate_geolocation()”);
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_errors);
}
else
{
alert(“!navigator.geolocation”);
//yqlgeo.get(‘visitor’, normalize_yql_response);
}
}

Thanks´

Salam says

I tried the code ,but I am getting error ,errors are

1) In desktop (used windows 7,firefox8) Null Vallu
2)In Mobile (Android,firefox,gps was on) timeout error

Please let me know why i am getting these errors and what are the software and hardware requirement (for mobile and pc) for testing these code .

Thanks in advance

Abdul Salam K.A

William E. Beers says

Geolocation + IE 10 puts me in Washington DC (as does Gmap4) but I am really 40+ miles out. Geolocation + Chrome puts me in Haymarket, VA on the correct street (as does Gmap4 using Chrome). Why does IE return such erroneous lat/lng? (just wifi here)

Archie says

HI there,

this works fine on a desktop, returns an approximate location location based on IP.

In my Samsung Galaxy II Note phone, accurate position is found, but the browser keeps updating itself many times per second in an uncontrolled manner – and eventually the browser crashes in one minute or so. I am using Chrome.

I have tried to play with the timeout value but nothing helps..

I appreciate your advice. Any ideas?

cheers Archie

Naim says

Is it better to have a higher coords.accuracy value or a lower one?

Jim says

Looks like the newest iterations of Firefox have problems with this code. It was working fine on my site until a recent upgrade to FF26. Now, the code still works great in Chrome, IE and Safari, but I’m going to have to find a work-around for FF. (I did some research on the Mozilla site and it looks like they “fixed a bug” in version 24 or 25).

If anyone reading this has a suggestion, I’d love to hear it!

Ian, thanks for the awesome tutorial!

Ian Devlin says

@Jim, I just tested the code in Firefox 26 and it worked fine for me so I’m not sure what you’re seeing (or not seeing!) :-/

Rients Dijkstra says

The code seems to work on my laptop, with one little problem: I live (and work) in Amsterdam, however it puts me in Helmond in the south of the country, more than 100km away!

Patrick Sardinha says

Hi,

Anyone has a solution for Android Mobile phones?

I have tested the example http://93.113.255.166/testHTML5.htm and it’s not detecting the position in any Android Phone that I have tested, with default browser or Chrome.

Thanks.

Join the discussion.

Some HTML is ok

You can use these tags:
<a href="" title="">
<abbr title="">
<b>
<blockquote cite="">
<cite>
<del datetime="">
<em>
<i>
<q cite="">
<strong>

You can also use <code>, and remember to use &lt; and &gt; for brackets.