Digital Developer Conference on Data and AI: Essential data science, machine learning, and AI skills and certification Register for free

Create mobile web applications with HTML5 and geolocation APIs

HTML5 is a popular technology since its early days and for a very good reason. It brought desktop application-like capabilities to the web browser — not just on the desktop but also on mobile devices.

In this five-part series, we will take a look at some of the popular features that are part of HTML5. In each part, we will also write some code to showcase these features and see how they work on both desktop and mobile browsers.

In this tutorial, you will tap into one of the most popular new technologies available to mobile Web applications: geolocation. High-end smartphones all have GPS built-in to them, and now you will learn how it can be used by a Web application. In this article you will learn how to use the various aspects of the geolocation standard and how to use it with some popular Web services to create an interesting mobile mashup.

Prerequisites

In this tutorial, you will develop a web application to showcase the geolocation API. The code uses core web technologies like HTML, Cascading Style Sheets (CSS), and JavaScript. To test the sample application on both desktop and mobile, we recommend using the latest web browser versions.

The basics: Getting a fix

The geolocation API provides a standardized interface for users to share their locations with trusted websites. It allows a website to retrieve the geographical location information of a user, like latitude and longitude. This information can be used to display location-aware content. For example, a business can use this information to point a user to their nearest store based on the user’s location, or display different content based on a user’s country.

In this example, we will use the geolocation API to display the current temperature at the user’s location.

Listing 1. Finding a user: getCurrentPosition

navigator.geolocation.getCurrentPosition(successCallback,
errorCallback, options);

As you can see, the geolocation object is part of the standard navigator object. The most commonly used function offered by the geolocation API is getCurrentPosition. The getCurrentPosition function can be used to retrieve a user’s position; it requires the consent of the user, and it’s an asynchronous operation.

The function takes three parameters: The first is a callback for success; the second is a callback for error; and the third is to pass options like accuracy, timeout, and cache max age. The last two parameters are optional.

The success callback function takes a single parameter of type Position. The Position object has two properties: coords and timestamp. Here, coords is of type Coordinates, which represents the current location, and the timestamp represents the time at which the location was retrieved. We are mainly interested in the coords, so let’s examine the coordinates object in detail, which has the following properties:

  • latitude
  • longitude
  • altitude
  • accuracy
  • altitudeAccuracy
  • heading
  • speed

It is worth mentioning that not all of these properties will be available on all devices, except for latitude, longitude, and accuracy.

In case of an error, the error callback is called with a single parameter of type PositionError. The PositionError object has two properties: code and message. The message is device-specific and is useful for debugging. The code can have one of the three values:

  • PERMISSION_DENIED (1)
  • POSITION_UNAVAILABLE (2)
  • TIMEOUT (3)

Our application can use these error codes to display a meaning full error to the user.

And the options parameter takes a PositionOptions object, which has the following properties:

  • maximumAge: maximum age of the cached position
  • timeout: amount of time before the error callback is invoked
  • enableHighAccuracy: used if a highly accurate position is requested

Now that we have looked at the API in details, let’s look at a simple example that shows how to use this function.

Integrating with Open Weather Map API

Let’s create a simple web app where we will use the geolocation API to get a user’s location and use their location to show some location-aware content, which in this case will be the temperature.

For this example, we will use the current weather API provided by Open Weather Map. We will start by creating a free account and generating an API key, which will be required for calling Open Weather Map APIs. The free account is limited, but should be enough for our simple application.

Listing 2. Current weather

<!DOCTYPE html>
<html>
  <head>
    <title>Local Weather</title>
    <script type="text/javascript">
      const initialize = () => {
        navigator.geolocation.getCurrentPosition(
          getWeatherInfoByLocation,
          handleError
        );
      };

      const handleError = error => {
        alert(`Unable to retrieve location: ${error.message}`);
      };

      const getWeatherInfoByLocation = position => {
        const xhr = new XMLHttpRequest();
        const lat = position.coords.latitude;
        const long = position.coords.longitude;
        const url = `https://api.openweathermap.org/data/2.5/weather?APPID=<APP_ID>⪫=${lat}&lon=${long}`;
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 4) {
            showTemperature(JSON.parse(xhr.response));
          }
        };

        xhr.open("get", url, true);
        xhr.send();
      };

      const showTemperature = weatherInfo => {
        const location = weatherInfo.name;
        const temperature = Math.round(
          ((weatherInfo.main.temp - 273.15) * 9) / 5 + 32
        );
        document.getElementById(
          "weatherInfo"
        ).innerHTML = `Current temperature in ${location} is ${temperature}°Fahrenheit `;
      };
    </script>
  </head>
  <body onload="initialize()">
    <div>
      <h1 id="weatherInfo">Retriving local weather information...</h1>
    </div>
  </body>
</html>

As you can see, the page loads the initialize function, which is invoked and will call the geolocation API getCurrentPosition function.

When the user’s position is retrieved successfully, the geolocation coordinate (latitude and longitude), will be used to get the current weather information using the Open Weather Map API. Once you get the response back from the API, use the location name and temperature to display the information to the user. Our code also handles the error scenario, displaying an alert if there is an error while retrieving the user’s position.

This is a simple example, but you can see that with just a few lines of code, you can get the user’s location information.

Figure 1. Current Weather Web App on iPhone

In our location-aware application, you only need to get the user’s location once to display some location-specific data. However, what if you need to keep track of a user’s location as they move? For this, you can use the watchPosition and clearPosition functions, which are also part of the geolocation API.

More advanced: Tracking

The geolocation API watchPosition function takes the same parameters as the getCurrentPosition function, such as success callback, error callback, and position options. However, in this case, the success callback function is called each time the user’s position changes. When watchPosition is called, it returns a watch ID, which can be used to unregister the success callback by using the geolocation clearWatch method.

Integrating with Google Maps

To demonstrate the user-tracking feature, we will use Google Maps APIs. We will develop an app to show the user’s location on a map and update the map each time the user’s location changes. Listing 3 shows the mapping code.

Listing 3. Mapping application with geolocation

<html>
  <head>
    <meta name="viewport" content="initial‑scale=1.0, user‑scalable=no" />
    <meta http‑equiv="content‑type" content="text/html; charset=UTF‑8" />
    <title>Track me!</title>

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

    <script type="text/javascript">
      let trackerId = 0;
      let geocoder;
      let map;
      let userMarker;
      const initialize = () => {
        geocoder = new google.maps.Geocoder();

        navigator.geolocation.getCurrentPosition(function(pos) {
          const latLng = new google.maps.LatLng(
            pos.coords.latitude,
            pos.coords.longitude
          );
          const options = {
            zoom: 12,
            center: latLng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
          map = new google.maps.Map(
            document.getElementById("map_canvas"),
            options
          );
          userMarker = new google.maps.Marker({
            position: latLng,
            map: map,
            title: "You!"
          });
          showLocation(pos);
        });
        trackerId = navigator.geolocation.watchPosition(function(pos) {
          var latLng = new google.maps.LatLng(
            pos.coords.latitude,
            pos.coords.longitude
          );
          map.setCenter(latLng);
          userMarker.setPosition(latLng);
          showLocation(pos);
        });
      };

      const showLocation = pos => {
        const latLng = new google.maps.LatLng(
          pos.coords.latitude,
          pos.coords.longitude
        );
        if (geocoder) {
          geocoder.geocode({ latLng: latLng }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
              if (results[1]) {
                $("location").innerHTML = results[1].formatted_address;
              }
            }
          });
        }
      };

      const stopTracking = () => {
        if (trackerId) {
          navigator.geolocation.clearWatch(trackerId);
        }
      };
    </script>
  </head>
  <body style="margin:0px; padding:0px;" onload="initialize()">
    <div style="margin:25px;">
      <input type="button" value="Stop tracking me!" onclick="stopTracking()" />
    </div>
    <div id="map_canvas" style="width:100%; height:90%; float:left;"></div>
  </body>
</html>

Similar to the previous example, once the body of the document loads, the initialize function is invoked. This function uses the getCurrentPosition method to retrieve the user’s location. When it gets the location, it creates a map using the Google Maps API. Notice how the latitude and longitude are used to create an instance of google.maps.LatLng. This object is used to center the map. Create a marker on the map to represent the current location of the user. The marker once again uses the latitude and longitude we received from the geolocation API.

After creating the map and putting a marker on it, we start tracking the user. We capture the ID returned from watchPosition. Whenever a new position is received, we re-center the map on the new location and move the marker to that location.

The showLocation function is called when the map is initially drawn and an update to the user’s location is received. It uses an instance of google.maps.Geocoder (created at the beginning of the initialize function in Listing 3.) This API allows you to perform geocoding, or taking an address and turning it into mapping coordinates (latitude and longitude). It also performs reverse-geocoding, taking mapping coordinates and returning a physical address. In this case, take the coordinates produced by the geolocation API and use the Google Maps API to reverse-geocode them. The results are then displayed on the screen.

The last function in Listing 3 is the stopTracking function. This is called when the user clicks on the button created in the HTML. Here you use the trackerId obtained when you first called the watchPositionfunction. Simply pass this to the clearWatch function, and the browser/device will stop getting the user’s location and will also stop calling the success callback function. Figure 2 shows the tracker app in use.

Figure 2. Tracking application

Summary

This tutorial has shown how to use the geolocation APIs to develop a web application to get a user’s location and track that location over time. Using these APIs, you can easily get the user’s position and use this information to build location-aware applications.

In Part 2 of this series on HTML5 and mobile web applications, we look at how to take advantage of local storage to improve the performance of mobile web applications.

Acknowledgements

This article was originally written by Michael Galpin and published on May 5, 2010.