Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

Using Location Data with PhoneGap

Save for later
  • 11 min read
  • 30 Oct 2013

article-image

(For more resources related to this topic, see here.)

An introduction to Geolocation

The term geolocation is used in order to refer to the identification process of the real-world geographic location of an object. Devices that are able to detect the user's position are becoming more common each day and we are now used to getting content based on our location ( geo targeting ).

Using the Global Positioning System (GPS )—a space-based satellite navigation system that provides location and time information consistently across the globe—you can now get the accurate location of a device. During the early 1970s, the US military created Navstar, a defense navigation satellite system. Navstar was the system that created the basis for the GPS infrastructure used today by billions of devices. Since 1978 more than 60 GPS satellites have been successfully placed in the orbit around the Earth (refer to http://en.wikipedia.org/wiki/List_of_GPS_satellite_launches for a detailed report about the past and planned launches).

The location of a device is represented through a point. This point is comprised of two components: latitude and longitude. There are many methods for modern devices to determine the location information, these include:

  • Global Positioning System (GPS)
  • IP address
  • GSM/CDMA cell IDs
  • Wi-Fi and Bluetooth MAC address

Each approach delivers the same information; what changes is the accuracy of the device's position. The GPS satellites continuously transmit information that can parse, for example, the general health of the GPS array, roughly, where all of the satellites are in orbit, information on the precise orbit or path of the transmitting satellite, and the time of the transmission. The receiver calculates its own position by timing the signals sent by any of the satellites in the array that are visible.

using-location-data-phonegap-img-0

The process of measuring the distance from a point to a group of satellites to locate a position is known as trilateration . The distance is determined using the speed of light as a constant along with the time that the signal left the satellites.

The emerging trend in mobile development is GPS-based "people discovery" apps such as Highlight, Sonar, Banjo, and Foursquare. Each app has different features and has been built for different purposes, but all of them share the same killer feature: using location as a piece of metadata in order to filter information according to the user's needs.

The PhoneGap Geolocation API

The Geolocation API is not a part of the HTML5 specification but it is tightly integrated with mobile development. The PhoneGap Geolocation API and the W3C Geolocation API mirror each other; both define the same methods and relative arguments. There are several devices that already implement the W3C Geolocation API; for those devices you can use native support instead of the PhoneGap API.

As per the HTML specification, the user has to explicitly allow the website or the app to use the device's current position.

The Geolocation API is exposed through the geolocation object child of the navigator object and consists of the following three methods:

  • getCurrentPosition() returns the device position.
  • watchPosition() watches for changes in the device position.
  • clearWatch() stops the watcher for the device's position changes.

The watchPosition() and clearWatch() methods work in the same way that the setInterval() and clearInterval() methods work; in fact the first one returns an identifier that is passed in to the second one. The getCurrentPosition() and watchPosition() methods mirror each other and take the same arguments: a success and a failure callback function and an optional configuration object. The configuration object is used in order to specify the maximum age of a cached value of the device's position, to set a timeout after which the method will fail and to specify whether the application requires only accurate results.

var options = {maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }; navigator.geolocation.watchPosition(onSuccess, onFailure, options);

Only the first argument is mandatory; but it's recommended to handle always the failure use case.

The success handler function receives as argument, a Position object. Accessing its properties you can read the device's coordinates and the creation timestamp of the object that stores the coordinates.

function onSuccess(position) { console.log('Coordinates: ' + position.coords); console.log('Timestamp: ' + position.timestamp); }

The coords property of the Position object contains a Coordinates object; so far the most important properties of this object are longitude and latitude. Using those properties it's possible to start to integrate positioning information as relevant metadata in your app.

The failure handler receives as argument, a PositionError object. Using the code and the message property of this object you can gracefully handle every possible error.

function onError(error) { console.log('message: ' + error.message); console.log ('code: ' + error.code); }

The message property returns a detailed description of the error, the code property returns an integer; the possible values are represented through the following pseudo constants:

  • PositionError.PERMISSION_DENIED, the user denies the app to use the device's current position
  • PositionError.POSITION_UNAVAILABLE, the position of the device cannot be determined

    If you want to recover the last available position when the POSITION_UNAVAILABLE error is returned, you have to write a custom plugin that uses the platform-specific API. Android and iOS have this feature. You can find a detailed example at http://stackoverflow.com/questions/10897081/retrieving-last-known-geolocation-phonegap.

  • PositionError.TIMEOUT, the specified timeout has elapsed before the implementation could successfully acquire a new Position object

    JavaScript doesn't support constants such as Java and other object-oriented programming languages. With the term "pseudo constants", I refer to those values that should never change in a JavaScript app.

One of the most common tasks to perform with the device position information is to show the device location on a map. You can quickly perform this task by integrating Google Maps in your app; the only requirement is a valid API key. To get the key, use the following steps:

  1. Visit the APIs console at https://code.google.com/apis/console and log in with your Google account.
  2. Click the Services link on the left-hand menu.
  3. Activate the Google Maps API v3 service.

Time for action – showing device position with Google Maps

Get ready to add a map renderer to the PhoneGap default app template. Refer to the following steps:

  1. Open the command-line tool and create a new PhoneGap project named MapSample.

    $ cordova create ~/the/path/to/your/source/ mapmample com.gnstudio.pg.MapSample MapSample

  2. Add the Geolocation API plugin using the command line.

    $ cordova plugins add https: //git-wip-us.apache.org /repos/asf/cordova-plugin-geolocation.git

    Unlock access to the largest independent learning library in Tech for FREE!
    Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
    Renews at R$50/month. Cancel anytime
  3. Go to the www folder, open the index.html file, and add a div element with the id value #map inside the main div of the app below the #deviceready one.

    <div id='map'></div>

  4. Add a new script tag to include the Google Maps JavaScript library.

    <script type="text/javascript" src ="https: //maps.googleapis.com/maps/api/js?key= YOUR_API_KEY &sensor=true"> </script>

  5. Go to the css folder and define a new rule inside the index.css file to give to the div element and its content an appropriate size.

    #map{ width: 280px; height: 230px; display: block; margin: 5px auto; position: relative; }

  6. Go to the js folder, open the index.js file, and define a new function named initMap.

    initMap: function(lat, long){ // The code needed to show the map and the // device position will be added here }

  7. In the body of the function, define an options object in order to specify how the map has to be rendered.

    var options = { zoom: 8, center: new google.maps.LatLng(lat, long), mapTypeId: google.maps.MapTypeId.ROADMAP };

  8. Add to the body of the initMap function the code to initialize the rendering of the map, and to show a marker representing the current device's position over it.

    var map = new google.maps.Map(document.getElementById('map'), options); var markerPoint = new google.maps.LatLng(lat, long); var marker = new google.maps.Marker({ position: markerPoint, map: map, title: 'Device's Location' });

  9. Define a function to use as the success handler and call from its body the initMap function previously defined.

    onSuccess: function(position){ var coords = position.coords; app.initMap(coords.latitude, coords.longitude); }

  10. Define another function in order to have a failure handler able to notify the user that something went wrong.

    onFailure: function(error){ navigator.notification.alert(error.message, null); }

  11. Go into the deviceready function and add as the last statement the call to the Geolocation API needed to recover the device's position.

    navigator.geolocation.getCurrentPosition(app.onSuccess, app.onError, {timeout: 5000, enableAccuracy: false});

  12. Open the command-line tool, build the app, and then run it on your testing devices.

    $ cordova build $ cordova run android

What just happened?

You integrated Google Maps inside an app. The map is an interactive map most users are familiar with—the most common gestures are already working and the Google Street View controls are already enabled.

To successfully load the Google Maps API on iOS, it's mandatory to whitelist the googleapis.com and gstatic.com domains. Open the .plist file of the project as source code (right-click on the file and then Open As | Source Code ) and add the following array of domains:

<key>ExternalHosts</key> <array> <string>*.googleapis.com</string> <string>*.gstatic.com</string> </array>

using-location-data-phonegap-img-1

Other Geolocation data

In the previous example, you only used the latitude and longitude properties of the position object that you received. There are other attributes that can be accessed as properties of the Coordinates object:

  • altitude, the height of the device, in meters, above the sea level.
  • accuracy, the accuracy level of the latitude and longitude, in meters; it can be used to show a radius of accuracy when mapping the device's position.
  • altitudeAccuracy, the accuracy of the altitude in meters.
  • heading, the direction of the device in degrees clockwise from true north.
  • speed, the current ground speed of the device in meters per second.

Latitude and longitude are the best supported of these properties, and the ones that will be most useful when communicating with remote APIs. The other properties are mainly useful if you're developing an application for which Geolocation is a core component of its standard functionality, such as apps that make use of this data to create a flow of information contextualized to the geolocation data. The accuracy property is the most important of these additional features, because as an application developer, you typically won't know which particular sensor is giving you the location and you can use the accuracy property as a range in your queries to external services.

There are several APIs that allow you to discover interesting data related to a place; among these the most interesting are the Google Places API and the Foursquare API.

The Google Places and Foursquare online documentation is very well organized and it's the right place to start if you want to dig deeper into these topics. You can access the Google Places docs at https://developers.google.com/maps/documentation/javascript/places and Foursquare at https://developer.foursquare.com/.

The itinero reference app for this article implements both the APIs. In the next example, you will look at how to integrate Google Places inside the RequireJS app.

In order to include the Google Places API inside an app, all you have to do is add the libraries parameter to the Google Maps API call. The resulting URL should look similar to http://maps.google.com/maps/api/js?key=SECRET_KEY&sensor=true&libraries=places.

The itinero app lets users create and plan a trip with friends. Once the user provides the name of the trip, the name of the country to be visited, and the trip mates and dates, it's time to start selecting the travel, eat, and sleep options.

using-location-data-phonegap-img-2

When the user selects the Eat option, the Google Places data provider will return bakeries, take-out places, groceries, and so on, close to the trip's destination. The app will show on the screen a list of possible places the user can select to plan the trip.

For a complete list of the types of place searches supported by the Google API, refer to the online documentation at https://developers.google.com/places/documentation/supported_types.