Let’s take a look at some samples of the different techniques, and a
multiplatform solution that will work for almost all devices. Table 1
analyzes browser compatibility with the different client
techniques.Table 1. Client geolocation API support list
Browser/platform | Client geolocation
support |
---|
Safari | W3C Geolocation API from
iOS 3.0 |
Android
browser | Gears from Android
1.5 W3C Geolocation API from Android
2.0 |
Symbian/S60 | No support (available in
widgets) |
Nokia Series
40 | No support |
webOS | No support (available in
offline applications) |
BlackBerry | BlackBerry Location since
4.1 Gears since 5.0 W3C Geolocation API
announced from 6.0 |
NetFront | No support |
Openwave
(Myriad) | No support |
Internet
Explorer | No support (Gears
optionally, if it’s installed) |
Motorola Internet
Browser | No support |
Opera Mobile | No support (Gears
optionally, if it’s installed) |
Opera Mini | No support |
1. W3C Geolocation API
The World Wide Web Consortium is working on a standard way
to query the user’s position from JavaScript, called the Geolocation
API. The API is still in draft at the time of this writing, but the
draft status has not stopped some providers from using it: it has been
implemented in Firefox since version 3.5, in mobile Safari since iOS
version 3.0, and in the Android browser since 2.0. We should expect it
to be implemented in more browsers in the future.
The Geolocation API doesn’t rely on one location technology.
Instead, it allows the browser to decide which method it will
use.
With this API implemented in a mobile browser, the navigator object in JavaScript will have a
read-only property called geolocation
that will allow us to interact with the API.
Note:
The Iris Browser (recently acquired by BlackBerry), the Bondi
Widgets 1.0 API, the Nokia JavaScript Platform 2.0, the webOS DoJo
framework, and Safari on iOS 3.0 are the mobile platforms currently
supporting the W3C Geolocation API.
Location querying is an asynchronous process. It can take some
time to get the user’s location (like in GPS); that’s why the API relies
on callback functions to give us the latitude and longitude.
The user will need to give the site permission to obtain the
geolocation data using the API, as shown in Figure 1.
1.1. Getting the position
The first way to use the Geolocation API is to get the user’s
location, using the getCurrentPosition function of the geolocation object. It receives two
callbacks: the function that will receive the position, and an
error-handling function. The latter is optional.
Optionally, it may also receive an object that configures some
additional properties; this third parameter will be discussed
shortly.
Let’s look at an example:
navigator.geolocation.getCurrentPosition(userLocated, locationError);
The first callback will receive one parameter as the position object with a coordinate property. The error callback will
receive an error code:
function userLocated(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var timeOfLocation = position.timestamp;
}
function locationError(error) {
alert(error.code);
}
The coords property has the
following attributes, defined in the W3C standard:
latitude
longitude
altitude
(optional)
accuracy
altitudeAccuracy
(optional)
heading (optional) in
degrees clockwise
speed (optional) in
meters per second
1.2. Handling error messages
The parameter received in the error handler is an object of
class PositionError having a
code and a message (useful for logging). The class also
has some constant values to be compared with the code property. The constants are shown in
Table 2.
Table 2. PositionError constants in the W3C Geolocation API
Error
constant | Description |
---|
UNKNOWN ERROR | The location couldn’t
be retrieved. |
PERMISION_DENIED | The user has denied
permission to the API to get the position. |
POSITION_UNAVAILABLE | The user’s position
couldn’t be determined due to a failure in the location
provider. |
TIMEOUT | The user’s position
couldn’t be determined before the timeout defined in the
options. |
To use these constants, we should make a switch for each
value:
function locationError(error) {
switch(error.code) {
case error.PERMISSION_DENIED:
// error handling
break;
case error.POSITION_UNAVAILABLE:
// error handling
break;
case error.TIMEOUT:
// error handling
break;
}
}
1.3. Tracking the location
The second way to use the W3C Geolocation API is to track the
user’s location. With tracking support, we can receive notifications
about location changes. For instance, we can make a sports website
that tracks the user’s steps, make speed and distance calculations,
and store this information either locally or on our server using
Ajax.
Warning:
For this to work, the user needs to keep the website open in
the browser. Many browsers also stop JavaScript execution when the
browser is in the background.
The tracking process involves the watchPosition method of the navigator.geolocation object, which receives
two handlers (for location detection and error management) and returns
a watchId. The handler function
will receive the same parameter as the getCurrentPosition function that we saw
earlier. To stop the location tracking we can call clearWatch, passing the previously received
watchId:
// Global variable to store the watch ID
var watchId = false;
// This function may be called by an HTML element
function trackingButtonClick() {
if (watchId==false) {
// Tracking is off, turn it on
var watchId = navigator.geolocation.watchPosition(userLocated,
locationError);
} else {
// Tracking is on, turn it off
navigator.geolocation.clearWatch(watchId);
watchId = false;
}
}
1.4. Detecting API availability
Detecting whether the W3C Geolocation API is available is as
simple as querying whether the navigator.geolocation object exists. For
example:
if (navigator.geolocation==undefined) {
alert("Geolocation API is not present");
}
1.5. Defining optional attributes
The third parameter of the getCurrentPosition and watchPosition functions can receive an
object with the optional properties outlined in Table 2.
Table 2. Optional properties for getCurrentPosition and
watchPosition
Property | Type | Default
value |
---|
enableHighAccuracy | Boolean | false |
timeout | Long (in
milliseconds) | Infinity |
maximumAge | Long (in
milliseconds) | 0 |
If the enableHighAccuracy
property is defined as true, the
provider should force the best accuracy in determining the user’s
location.
The maximumAge attribute is
useful for using location data cached on the device. If the device has
recently acquired a location, we can get that location using this
property, defined as the maximum milliseconds we want. If the property
is defined as 0 (the default
value), the device must acquire a new location. A typical usage might
look like this:
navigator.geolocation.getCurrentPosition(userLocated, locationError,
{timeout:10000, maximumAge: 30000, enableHighAccuracy:false});