HTML Geolocation

PeterLeow
3,234 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

Where on Earth am I?

Every one of us occupies a location on Earth. This location is specified by a geographic coordinate system of latitude, longitude, and altitude. With the proliferation of location-aware hardware and software, finding one’s location on the Earth has never been easier. There are many techniques available to identify the location of a user. A computer browser generally uses WIFI or IP based positioning techniques whereas a mobile browser may use cell triangulation that based on your relative proximity to the different cellular towers operated by the telcos, GPS, A-GPS, or WIFI. Today, location awareness is an ever-growing trend that finds its way into many applications like:

  • Showing one’s location on a map especially when you are in an unfamiliar area.

  • Providing turn-by-turn navigation while driving on unfamiliar journey.

  • Finding out points of interest in one’s vicinity.

  • Getting the latest weather or news of one’s area.

  • Tagging the location of picture.

  • Location tracking of a fleet of delivery trucks.

Thanks to HTML Geolocation API, you can now look up your own location on Earth using a browser. It is as easy as a piece of cake. Doing is believing.

Hit the Run button to execute the HTML code in the Finding Me code section below:

Finding Me
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Finding Me</title>
<script>
function getLocation()
{
// Check whether browser supports Geolocation API or not
if (navigator.geolocation) { // Supported
// To add PositionOptions
navigator.geolocation.getCurrentPosition(getPosition);
} else { // Not supported
alert("Oops! This browser does not support HTML Geolocation.");
}
}
function getPosition(position)
{
document.getElementById("location").innerHTML =
"Latitude: " + position.coords.latitude + "<br>" +
"Longitude: " + position.coords.longitude;
}
// To add catchError(positionError) function
</script>
</head>
<body>
<h1>Finding Me</h1>
<button onclick="getLocation()">Where am I?</button>
<p id="location"></p>
</body>
</html>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The output on the Viewer screen should look similar to the screenshot shown in Figure 1.

alt text Figure 1: finding_me.html in a Browser

Click on the Where am I? button, a dialog box similar to the screenshot shown in Figure 2 pops up seeking permission to share location, click on Share Location to grant.

alt text Figure 2: Seeking Permission to Share Location

Voila, your location is revealed on the screen similar to the screenshot shown in Figure 3.

alt text Figure 3: You are found!

Isn't that a piece of code cake?

How you wish you could show these location readings on a map so that you could view your location visually, don't you? You wish will come true if you read on...

Diving in...

The HTML Geolocation API has only one object — navigator.geolocation. You may liken the navigator.geolocation to a compass on the browser. As browser support for this API is still dubious, it is a de facto practice to check for browser support before proceeding with any geolocation code. To do this, simply wrap your code inside this if-else template as shown:

// Check whether browser supports Geolocation API or not
if (navigator.geolocation) // Supported
{
  // place the geolocation code here
}
else // Not supported
{
  alert("Oops! This browser does not support HTML Geolocation.");
}

The navigator.geolocation object exposes three methods — getCurrentPosition(), watchPosition(), and clearWatch(). Let's check them out one by one...

getCurrentPosition()

The getCurrentPosition() method is used to obtain the current location of the user's device. You have already used this method in the Finding Me code section in its simplest form as shown:

navigator.geolocation.getCurrentPosition(getPosition); where getPosition is a callback function.

Recall in Figure 2 where a dialog has popped up seeking your permission to share your location with the web page. This is what happens whenever the getCurrentPosition() method is called. Users are given the choice to opt-in in order to allow the method to proceed to retrieve your current position. In other words, your privacy is well-respected and protected.

In full syntax, the getCurrentPosition() method takes three parameters as follows:

navigator.geolocation.getCurrentPosition(callback_on_success [, callback_on_error] [, PositionOptions])

callback_on_success

This first parameter of the getCurrentPosition() method is a callback function to be called when the call to getCurrentPosition() method is successful. The callback function is called with a Position object passed from the getCurrentPosition() method. This Position object consists of two properties: coords and timestamp. In the Finding Me code section, the callback function is getPosition(position) which takes a Position object parameter and outputs the latitude and longitude through the coords property of this parameter. This is illustrated in the following code:

function getPosition(position)
{
  document.getElementById("location").innerHTML =
      "Latitude: " + position.coords.latitude + "<br>" +
      "Longitude: " + position.coords.longitude;    
}

The various properties of the Position object are described in Table 1.

Table 1: Position Object
PropertyDescription
coords.latitudeThe coords.latitude property returns the latitude of the user's current position in decimal degrees.
coords.longitudeThe coords.longitude property returns the longitude of the user's current position in decimal degrees.
coords.altitudeThe coords.altitude property returns the height of the user's current position in meters above the sea level. It will returns null if this information is not available.
coords.accuracyThe coords.accuracy property returns the accuracy level of the latitude and longitude coordinates in meters.
coords.altitudeAccuracyThe coords.altitudeAccuracy property returns the accuracy level of the altitude in meters.
coords.headingThe coords.heading property returns the direction of travel of the location-aware device in degrees, where 0° starts from the north and counting clockwise. It will returns null if this information is not available.
coords.speedThe coords.speed property returns the speed of the location-aware device in meters per second. It will returns null if this information is not available.
timestampThe timestamp property returns the time when the position object was acquired.

callback_on_error

The second parameter of the getCurrentPosition() method is an optional error handling callback function to be invoked when the call to getCurrentPosition() method encounters any one of the following circumstances:

  • Request timed out
  • Location information not available
  • User has denied permission to share the location information

The callback function is invoked with a PositionError object parameter passed from the getCurrentPosition() method. This PositionError object consists of one property — code. This code property takes one of three values corresponding to the error types as shown in Table 2.

Table 2: code Property of PositionError object
Error TypeDescription
TIMEOUTRequest for location information exceeds the timeout property set in the position options object (discussed later).
POSITION_UNAVAILABLEThe position of the location-aware device cannot be determined.
PERMISSION_DENIEDUser has denied permission to share the location information.

Replace the comment // To add catchError(positionError) function in the Finding Me code section with a second callback function called catchError(positionError)as shown:

function catchError(positionError) {
  switch(positionError.code)
  {
	case positionError.TIMEOUT:
	  alert("The request to get user location has aborted as it has taken too long.");
	  break;
	case positionError.POSITION_UNAVAILABLE:
	  alert("Location information is not available.");
	  break;
	case positionError.PERMISSION_DENIED:
	  alert("Permission to share location information has been denied!");
	  break;
	default:
	  alert("An unknown error occurred.");
  }
}

Then, bind this catchError(positionError) function to the getCurrentPosition() method as the second parameter as shown:

navigator.geolocation.getCurrentPosition(getPosition, catchError);

When you are ready, run the code, unplug your network cable or turn off the wireless connection of your computer to simulate the no network connection situation, grant the permission for sharing location information (Figure 2), and then click on the Where am I? button.

Oops! A message box pops up saying "Location information is not available." similar to the screenshot shown in Figure 4.

alt text Figure 4: Simulating an Error Situation

If you look into the code in the catchError() function, you would notice that this is the error message specified under the case of positionError.POSITION_UNAVAILABLE. The cause is obviously due to the network cable being unplugged and wireless being switched off. The catchError() function was invoked by the getCurrentPosition() method as it is not able to obtained any location information due to the broken network connection. (You may recover the network connection to your computer now.) Although this error handling parameter is optional, you should always include it as part of any geolocation code. This is one of the best practices to allow the program to fail gracefully as well as to keep the users informed of any run-time errors.

PositionOptions

The third parameter of the getCurrentPosition() method is an optional PositionOptions object that can be used to fine tune the Position object returned by the getCurrentPosition() method programmatically. It has three properties as shown in Table 3.

Table 3: PositionOptions Object
PropertyDescription
timeoutThe timeout property denotes the number of milliseconds an application will wait for a position information to become available. The default value is infinity.
maximumAgeThe maximumAge property denotes the number of milliseconds an application can keep using the cached (previously obtained) location data before trying to obtain new location data. A zero value indicates that the application must not use the cached location data while infinity value indicates that the cached location data must be used by the application. The default value is zero.
enableHighAccuracyThe enableHighAccuracy property denotes the condition of true or false. If it is true, the application will try to provide the most accurate position. However, this would result in slower response time and higher power consumption. The default value is false.

Replace the comment // To add PositionOptions in the Finding Me code section with a PositionOptions object variable called positionOptions as shown:

var positionOptions = {
  timeout : Infinity,
  maximumAge : 0,
  enableHighAccuracy : true
}

Then, add this positionOptions variable to the getCurrentPosition() method as the third parameter as shown:

navigator.geolocation.getCurrentPosition(getPosition, catchError, positionOptions);

In designing your location-aware application, you should choose the degree of accuracy as well as the retention period of old location data that are most appropriate for the purpose of the application by setting the enableHighAccuracy and the maximumAge properties of the PositionOptions object accordingly. For example, if your application is mainly for finding points of interest in your vicinity, you probably do not need high accuracy and the location information do not have to be updated so often. On the other hand, if your application is to provide turn by turn navigation direction for drivers, then high accuracy and constant update of location become necessary.

The getCurrentPosition() method is most suitable for obtaining a one-off location information. However, for finding location information that is changing continuously, such as the turn by turn navigation while driving on unfamiliar journey, you will have to call the getCurrentPosition() method repeatedly which is obviously very cumbersome and inefficient. Fret not! HTML Geolocation API has provided another method to handle this kind of situation — watchPosition().

watchPosition()

The watchPosition() method is almost identical to the getCurrentPosition() method. They both return the current location information and have the same method signature - one success callback function, one error callback function, and one PositionOptions object. The only difference lies in that the getCurrentPosition() method only returns location information once upon activation such as a button click, whereas The watchPosition() method continues to obtain location information every time the location of the user's device changes after the initial activation.

The watchPosition() method returns a watch ID that can be used to stop obtaining location information by passing it to the third method of the navigator.geolocation object —  clearWatch(), such as when a car that uses it for navigation has arrived at the destination.

clearWatch()

The clearWatch() method takes the watch ID of a watchPosition() method as a parameter and stops the execution of that watchPosition() method.

Location Tracking

As the watchPosition() method is similar to the getCurrentPosition() method, if you are familiar with the later, creating the watchPosition() method will be much easier — it is mostly a matter of, believe it or not, "copy and paste".

The Watching Me code section below contains all the code that we have discussed in the getCurrentPosition() method above.

Watching Me
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Watching Me</title>
<script>
function getLocation()
{
// Check whether browser supports Geolocation API or not
if (navigator.geolocation) { // Supported
var positionOptions = {
timeout : Infinity,
maximumAge : 0,
enableHighAccuracy : true
}
navigator.geolocation.getCurrentPosition(getPosition, catchError, positionOptions);
// watchID = navigator.geolocation.watchPosition(getPosition, catchError, positionOptions);
} else { // Not supported
alert("Oops! This browser does not support HTML Geolocation.");
}
}
function getPosition(position)
{
document.getElementById("location").innerHTML =
"Latitude: " + position.coords.latitude + "<br>" +
"Longitude: " + position.coords.longitude;
}
function catchError(positionError) {
switch(positionError.code)
{
case positionError.TIMEOUT:
alert("The request to get user location has aborted as it has taken too long.");
break;
case positionError.POSITION_UNAVAILABLE:
alert("Location information is not available.");
break;
case positionError.PERMISSION_DENIED:
alert("Permission to share location information has been denied!");
break;
default:
alert("An unknown error occurred.");
}
}
// To add stopWatch() function
</script>
</head>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

To turn this into a location tracking app, you need to modify the code in the Watching Me code section as follows:

  • Change the method name from getCurrentPosition to watchPosition; and

  • Store the watch ID returned from the watchPosition() method to a variable called watchID.

The resulting code is this:

watchID = navigator.geolocation.watchPosition(getPosition, catchError, positionOptions);

That's all that you need to create a web page that constantly monitors and updates the location of its displaying browser.

However, to stop the monitoring and updating at some point in time, you need additional code. In the Watching Me code section:

  • Replace the comment // To add stopWatch() function in the <script> section with a JavaScript function called stopWatch() that calls the clearWatch() method by passing it the watchID of the watchPosition() method as shown:
function stopWatch() 
{
  navigator.geolocation.clearWatch(watchID);
}
  • Replace the HTML code in the <body> section with:
<h1>Watching Me</h1>
<button onclick="getLocation()">Start Watching</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button onclick="stopWatch()">Stop Watching</button>
<p id="location"></p>

When you are ready, run the code in the Watching Me code section, click the Start Watching button, grant the permission to share location, then move around with the WIFI connected laptop. You should see your position being updated on the browser at a regular interval.

If you copy and paste the latitude and longitude generated in the Viewer screen to the search box of a Google Map on your browser, Google Map will mark your approximate location with a marker. The location is approximate and may differ on different browsers and devices as the accuracy of which is dependent on a number of factors, such as your public IP address, the nearer cellular towers, GPS availability, WIFI access points, and the type of browser that you are using.

Getting on a Map

You are now ready to show and track your location on a map as shown in this screenshot in Figure 5.

alt text Figure 5: Watching Me on Google Map

The code that does this is given in Watching Me on Map code section below:

Watching Me on Map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Watching Me on Map</title>
<style>
html,body {
height: 100%;
margin: 0;
padding: 0;
}
#map-holder {
height: 350px;
width: 500px;
}
</style>
<!--
To use this code on your website, get a free API key from
https://console.developers.google.com and include it in the API link
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
-->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzlpe08xQ9P9PTCtCD3BQOXJNmiaJ0JlU"></script>
<script>
var watchID;
function getLocation()
{
// Obtain the initial location one-off
navigator.geolocation.getCurrentPosition(getPosition);
}
function watchLocation()
{
// Obtain the location at regularly interval
watchID = navigator.geolocation.watchPosition(getPosition);
}
function stopWatch()
{
// Discontinue watch
navigator.geolocation.clearWatch(watchID);
}
function getPosition(position)
{
var location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
zoom : 12,
center : location,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-holder'), mapOptions);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

To avoid clouding the gist of the code, I have omitted the error handling callback function and the PositionOptions parameters from the getCurrentPosition() and the watchPosition() methods from the code.

The logic of the code works as follows:

  • When the page is loaded, the onload event is triggered and calls the getLocation() function which in turn calls the getCurrentPosition() method of the navigator.geolocation object to obtain the user's location.
  • If the call to the getCurrentPosition() method is successful, it triggers the callback function getPosition() passing it a Position object.
  • What the getPosition() function does is to render a Google Map that is centered on the user's location shown as marker.
  • Clicking the Start Watching button calls the watchLocation() function which in turn calls the watchPosition() method of the navigator.geolocation object to obtain the user's location at a regular interval.
  • If the call to the watchPosition() method is successful, it triggers the callback function getPosition() passing it a Position object.
  • What the getPosition() function does has been described above.
  • Clicking the Stop Watching button will stop the watch activity.

To use this code on your website, you need to get a free API key from Google APIs and include it in the JavaScript API link: <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>

If you move around with your WIFI connected laptop while keeping this web page opened, you should see your location being updated on the browser regularly as you move. Have fun!

The article HTML Geolocation appeared first on Peter Leow's Code Blog.

Open Source Your Knowledge: become a Contributor and help others learn. Create New Content