HTML5 Tutorial – Geolocation

The HTML5 Geolocation API is used to get the geographical position of a user.

Geolocation API defines a high-level interface to location information associated only with the device hosting the implementation, such as latitude and longitude.

Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. No guarantee is given that the API returns the device’s actual location.

Since this can compromise user privacy, the position is not available unless the user approves it.

(I’m using localhost as the server to run run my samples.)

image

Geolocation is specified in Geolocation API Specification.

The API is designed to enable both “one-shot” position requests and repeated position update and query cached positions.

You use the Geolocation API to request a position, and if the user agrees, the browser returns the location information. The location information provided as a set of latitude and longitude coordinates.

The Geolocation API allows you to perform three operations:

  • Find user’s location.
  • Track user’s location as he moves from one place to another.
  • Stop tracking user’s location.

Geolocation is supported in Opera 10.6+, IE 9+, Firefox 3.5+, Chrome 5+, Safari 5.0+, and Windows Store apps. See Can I Use for details.

Use Cases

Here are some common use cases:

  • Find points of interest near the user.
  • Annotating content with location information.
  • Show the user position on a map
  • Turn-by-turn route navigation
  • Alerts when points of interest are near the user
  • Up-to-date local information
  • Location tagging in social networking applications

Longitude, Latitude

The coordinates are always provided in decimal format. The latitude and longitude coordinates are specified in decimal degrees. For example, the latitude and longitude values for Mumbai are 18.91667 and 72.9 respectively. The positive decimal numbers indicate north-east position whereas negative decimal numbers indicate south-west position.

The Geolocation’s position object also provides the accuracy of the location coordinates. Depending on the device, you may also get altitude, altitudeAccuracy, heading, and speed.

One-Shot Position Request

You get the location from the navigator object and pass it a function that will do something with the data.

You get the current position from the browser from inside a function passed to the getCurrentPosition().


navigator.geolocation.getCurrentPosition(function (position) {
var pos = "Latitude: " + position.coords.latitude +
" Longitude: " + position.coords.longitude;
});

The following example shows a basic Geolocation script, with no error handling.

  1. Checks to see if geolocation feature is supported.
  2. If supported, uses the getCurrentPosition() method of the navigator. If not, display a message to the user.
  3. If the getCurrentPosition() method is successful, it returns a coordinates object to the function specified in the parameter ( showPosition ).
  4. The showPosition() function gets the displays the Latitude and Longitude.


<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Get My Location</title>
<script>
window.addEventListener("load", function () {
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
loc.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
loc.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
getLocation();
}, false);
</script>
</head>
<body>
<p>Get the location.</p>
<div id="loc"></div>
</body>
</html>

Using Error Functions

In a production system, you should consider fallback so those users without Geolocation-enabled browsers can manually enter their location by inputting their postal code or choosing their position on a map.

Error codes that can be returned:

  • Permission denied – The user did not allow Geolocation
  • Position unavailable – It is not possible to get the current location
  • Timeout – The operation timed out

Here is a sample snippette that uses error function.


function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition,
errorFunction);
} else {
loc.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
loc.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
function errorFunction(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
loc.innerHTML = "User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
loc.innerHTML = "Location information is unavailable."
break;
case error.TIMEOUT:
loc.innerHTML = "The request to get user location timed out."
break;
case error.UNKNOWN_ERROR:
loc.innerHTML = "An unknown error occurred."
break;
}
}

Return Data for getCurrentPosition()

The getCurrentPosition() method returns an object if it is successful. The latitude, longitude and accuracy properties are always returned. The other properties are returned if available.

  • coords.latitude The latitude as a decimal number
  • coords.longitude The longitude as a decimal number
  • coords.accuracy The accuracy of position
  • coords.altitude The altitude in meters above the mean sea level
  • coords.altitudeAccuracy The altitude accuracy of position
  • coords.heading The heading as degrees clockwise from North
  • coords.speed The speed in meters per second
  • timestamp The date/time of the response

WatchPosition, ClearWatch

Your app can get updates as the user is moving around using watchPosition and clearWatch functions.

  • watchPosition() : This method is similar to the getCurrentPosition() method but keeps monitoring the user location periodically unless the clearWatch() method is called. This method is suited for tracking the user movements as the user moves from one place to another.
  • clearWatch() : This method is used to stop monitoring the user location triggered using the watchPosition() method.

The first time a document calls the watchPosition function, the client requests permission to access the geographic location of the browser, unless the user has previously chosen to always allow or always deny permission for the website to determine location. If the user denies permission, the function declared by the errorCallback is called and the code attribute of the error parameter of that function is set to PositionError.PERMISSION_DENIED.

The code is similar to getCurrentPosition, in that you pass a function that will do the work you need to watchPosition(). Theyn you call clearWatch to stop the repeated updates.


navigator.geolocation.watchtPosition(function (position) {
var pos = "Latitude: " + position.coords.latitude +
" Longitude: " + position.coords.longitude;
});
function buttonClickHandler() {
// Cancel the updates when the user clicks a button.
navigator.geolocation.clearWatch(watchId);
}

Here is an example app that uses watchPosition with clearWatch and error handling.


<!DOCTYPE html>
<html>
<head>
<title>Location Test with Buttons</title>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<script type="text/javascript">
window.addEventListener("load", function () {
var nav = null;
var watchID;
startWatching.addEventListener("click", function () {
if (nav == null) {
nav = window.navigator;
}
if (nav != null) {
var geoloc = nav.geolocation;
if (geoloc != null) {
watchID = geoloc.watchPosition(successCallback, errorCallback);
}
else {
console.log("Geolocation not supported");
}
}
else {
console.log("Navigator not found");
}
});
function successCallback(position) {
loc.innerHTML = "Latitude: " + position.coords.latitude +
" Longitude: " + position.coords.longitude;
}
function errorCallback(error) {
var message = "";
// Check for known errors
switch (error.code) {
case error.PERMISSION_DENIED:
message = "This website does not have permission to use " +
"the Geolocation API";
break;
case error.POSITION_UNAVAILABLE:
message = "The current position could not be determined.";
break;
case error.PERMISSION_DENIED_TIMEOUT:
message = "The current position could not be determined " +
"within the specified timeout period.";
break;
}
// If it's an unknown error, build a message that includes
// information that helps identify the situation so that
// the error handler can be updated.
if (message == "") {
var strErrorCode = error.code.toString();
message = "The position could not be determined due to " +
"an unknown error (Code: " + strErrorCode + ").";
}
console.log(message);
}
clearWatching.addEventListener("click", function () {
window.navigator.geolocation.clearWatch(watchID);
});
});
</script>
</head>
<body>
<div id="loc"></div>
<input id="startWatching" type="button" value="Watch Latitude and Longitude" />
<input id="clearWatching" type="button" value="Clear watch" />
</body>
</html>

Cached Positions

The Geolocation API also supports getting cached positions. Cached positions are available on both getCurrentPosition and watchPosition.

For example:


// Request a position. We accept positions whose age is not
// greater than 10 minutes. If the user agent does not have a
// fresh enough cached position object, it will automatically
// acquire a new one.
navigator.geolocation.getCurrentPosition(successCallback,
errorCallback,
{maximumAge:600000});
function successCallback(position) {
// By using the 'maximumAge' option above, the position
// object is guaranteed to be at most 10 minutes old.
}
function errorCallback(error) {
// Update a div element with error.message.
}

The maximumAge attribute indicates that the application is willing to accept a cached position whose age is no greater than the specified time in milliseconds. If maximumAge is set to 0, the implementation must immediately attempt to acquire a new position object. Setting the maximumAge to Infinity must determine the implementation to return a cached position regardless of its age. If an implementation does not have a cached position available whose age is no greater than the specified maximumAge, then it must acquire a new position object.

References

Sample Code

Sample code is available in the DevDays GitHub repository. See https://github.com/devdays/html5-tutorials