JUMP START HTML5 (2014)
Chapter 28 APIs: The Geolocation API
The Geolocation API provides an easy way to retrieve the exact position of your users. For example, you can create an app that gives personalized suggestions to the users based on their current location. You may also plot their position on the map to show navigation details.
In this chapter, I will give you an overview of the Geolocation API and show how you can use it to create magical location-based HTML5 apps.
Hitting the Surface
Before using the API, let’s just make sure the browser supports it:
if (navigator.geolocation) {
// do something awesome
}
else {
// provide alternative content
}
The same check can be achieved through Modernizr:
if (Modernizr.geolocation) {
//do something awesome
}
else {
//provide alternative content
}
Use the following code for the actual position of the user:
navigator.geolocation.getCurrentPosition
↵(success_callback,error_callback);
function success_callback(position) {
console.log("Hey, there you are at Longitude:"
↵+position.coords.longitude+"and latitude:"
↵+position.coords.latitude);
}
function error_callback(error) {
var msg="";
switch(error.code){
case 1:
msg="Permission denied by user";
break;
case 2:
msg="Position unavailable";
break;
case 3:
msg="Request Timed out";
break;
}
console.log("Oh snap!! Error logged: "+msg);
}
The function getCurrentPosition() is asynchronous in nature. It means the function returns immediately, and tries to obtain the location of the user asynchronously. As soon as location information is retrieved, the success callback is executed. A position object is also passed to the callback. All the data related to the user'scurrent position is encapsulated in that object.
The following properties are available inside the position object:
· coords.latitude: latitude of the position
· coords.longitude: longitude of the position
· coords.accuracy: informs the developer how accurate the location information is (this result is in meters)
· coords.altitude: the current altitude in meters
· coords.altitudeAccuracy: used to establish the accuracy of the altitude given (previous point)
· coords.heading: the direction in which the user is heading
· coords.speed: the speed of the end user (device) in meters per second
· timestamp: the timestamp indicating when the position is recorded
You may not need all the information contained in the position object. In most cases, all you’ll ever need are the first three properties, as those are sufficient to plot a user’s position on the map.
The next point to note is that you should handle any error gracefully. When your app tries to retrieve the location, the browser asks the user if the requesting page should be allowed to access the user’s location. If the user denies permission, the error callback (see the previous piece of code) is called and an error object is passed. The code property indicates the type of error that has occurred. There could also be an error because the request timed out.
Now let’s see what else you can do with getCurrentPosition(). This function takes an optional third parameter, PositionOptions, which is a JavaScript object representing additional options. The available properties are:
1. enableHighAccuracy: If this is set true, it will instruct the hosting device to provide the best possible location details. If the device is a smartphone, it may use GPS to provide highly accurate information.
2. timeout: This essentially indicates how many milliseconds you want to wait to obtain a position. For example, if you set the value to 5,000 milliseconds and the app is unable to detect the current position of the user within that interval, it will fail with an error.
3. maximumAge: This property indicates if you want the device to cache the last known location. Let’s assume the device detects the current location of the user at 5.00 p.m. One minute later (at 5.01 p.m.), your app again calls getCurrentPosition() with maximumAge of 100,000 (means 100 seconds). Since the device knows where the user was 60 seconds ago and this is less than the maximumAge property, it will answer back with that last known location. This is useful if you’re satisfied with a previously known location rather than firing a new request for the current position (conserving battery life in many cases). It’s like saying “hey device, give me your current position, and I don’t mind if that position is x milliseconds old.” Note that a value of 0 indicates no caching should be done.
The following snippet demonstrates using PositionOptions:
navigator.geolocation.getCurrentPosition(
success_callback,
error_callback,
{enableHighAccuracy: true, timeout: 35000, maximumAge: 60000}
);
Continuously Monitoring Position
If you want to monitor the user’s position continuously, getCurrentPosition() will fail to work for you; instead, you should use watchPosition(). Both functions have the same signatures but they differ in the way they work.
In the case of watchPosition(), the success callback is called every time the user’s position changes. Yes, it’s that good! If your app needs to plot the user’s location on the map as the user moves, this is the best way to do it. You don’t even have to bother about when the position changes. The API takes care of that for you and executes your callback at the appropriate time.
The following code demonstrates the use of watchPosition():
var watchId;
function startWatchingPosition() {
watchId=navigator.geolocation.watchPosition(plotPosition);
}
function plotPosition(position){
console.log(
'got position: Latitude='+
position.coords.latitude+
', longitude='+
position.coords.longitude
);
// your code to update the position on map
}
function stopWatchingPosition(){
navigator.geolocation.clearPosition(watchId);
}
Here, the callback plotPosition() will be called every time a new location is retrieved. Note that the watchPosition() function returns a number that you can store and later use with clearPosition() to stop monitoring; it works much like setInterval() and clearInterval().
Tip: Fast-moving Users
If the user is moving very fast, the callback may execute frequently and slow down the system. Some event throttling may be necessary to reduce the number of times our callback runs. There is a small JavaScript library designed by Jonatan Heyman that reduces the number of callbacks we receive from watchPosition().
Accuracy of Geolocation
Geolocation accuracy may be important to your app. As discussed, you can always choose to enable high location accuracy using PositionOptions.enableHighAccuracy. But that’s just hinting to the device to use a little more power so as to return a more accurate position. The device may silently disregard it. In many situations, the location retrieved may not be accurate enough or even be wrong. And sometimes the user may have no interest in the retrieved location. In those cases, you may want to allow the users to override the location.
Conclusion
The Geolocation API is a great tool for the developer who wants to build cool location-based applications that give real-time feedback to the users; however, you should remember that the user always has a choice. As mentioned, the user has to explicitly grant permission to your application for you to actually access the location. In those cases, you should be ready with alternative content.
Here are a few small projects you can try to implement on your own:
· Detect your position and plot it on a Google Map.
· Continuously monitor your own position and plot them on the map.
· Detect the position of a user and show them theaters nearby.
· Let your users check in at different places and plot these on a map to later show them the places they visited that day.