The Comprehensive Beginner’s Guide to JavaScript Geolocation Tracking

Written by joehanson | Published 2018/03/20
Tech Story Tags: javascript | geolocation-tracking | google-maps | weekly-sponsor | javascript-geo-tracking

TLDRvia the TL;DR App

Combining the Google Maps JavaScript API and PubNub for realtime tracking of device location (with the bells and whistles)

Disclosure: PubNub, which provides realtime APIs and global messaging infrastructure, has previously sponsored Hacker Noon.

Geolocation and tracking functionality continues to make leaps and bounds. We’ve transcended beyond the static map to interactive and dynamic mapping technology. With that, we’ve seen how vital realtime geolocation tracking has become to apps in every industry, from the on-demand economy to the Internet of Things.

  • Watch your Uber or Lyft move towards you
  • Observe and highlight high-risk areas to fight disease
  • Monitor a fleet of drones
  • Track animals in a protected national park

Realtime tracking casts quite a wide net, eh?

Tutorial Overview

This is a 4-part tutorial on building realtime maps for web and mobile web using the Google Maps JavaScript API and PubNub. We’ll begin with basics to get your app set up, then add realtime geolocation functionality in Parts 2–4.

  • Part One: Google Maps API and PubNub Setup
  • Part Two: Live Map Markers
  • Part Three: Live Location Tracking
  • Part Four: Flight Paths

In the end, you’ll have a basic JavaScript location tracking app with map markers, device location-tracking, and flight paths, powered by the JavaScript Google Maps API and PubNub.

Tutorial Assets

For this tutorial, we presume you are working with a recent evergreen browser on a desktop or mobile device.

The code for the examples used in this tutorial series are available in our CodePen collection. This allows the examples to be easily forked into your own project and updated with your own API keys and custom application functionality.

We suggest you create a free CodePen user profile here so you can easily fork, modify and save the pens. If you’re comfortable downloading the HTML and serving it through another mechanism (like Python SimpleHttpServer or a cloud-based HTTP-accessible file service), that’s great too! Nothing about the code relies on CodePen itself.

Part One: JavaScript, Google Maps API and PubNub Setup

Getting our environment set up, and signed up for the Google Maps and PubNub services.

PubNub Setup

To get started, you’ll first need your PubNub publish and subscribe keys. If you don’t have an account, you can sign up here, and your pub/sub keys are available in the Admin Dashboard.

The keys look like UUIDs and start with “pub-c-” and “sub-c-” prefixes respectively.

Once you have your pub/sub keys, create a new PubNub application to represent your Android application (and any other systems that communicate using the same channels). The PubNub application will include publish and subscribe keys that applications can use for those specified features.

Google Maps API Setup

To integrate with Google Maps, you’ll need to create a Google Maps API key. We recommend doing that using the getting started guide here. This creates an unique API key that can be locked down to whatever web apps you like.

Once you’ve started to create a bunch of projects, you can manage your credentials in the Google API console here.

PubNub Overview

In this HTML5 and JavaScript sample application, PubNub provides the realtime communication capability that lets our web application receive incoming events as the position of a remote object (latitude and longitude) changes.

The core PubNub functionality that we use is Realtime Messaging. Our application uses a PubNub channel to send and receive position changed events. In this example, the same application both sends and receives the position events, so we say it is both the publisher and subscriber. In your application, the publisher (sender) system(s) may be different from the subscriber (receiving) system(s).

Google Maps Overview

We’ll use the JavaScript Google Maps API and the HTML5 Map Widget for this tutorial. The HTML5 map widget displays a map of the vicinity you configure. The map size, map center latitude and longitude, zoom level, map style and other options may be configured to your initial preferences and updated on the fly.

The Google Maps JavaScript API provides an initialization callback option that calls a function you specify when the map is loading.

In addition, we’ll use features like Map Markers and Polylines which allow you to place friendly map markers and flight paths on the map at the location(s) you specify (Parts 2, 3 and 4). All the points are user-specified and may be updated in real time as updates arrive.

Working with the Code

So, let’s jump into the code.

To work with the code, you’ll want to fork it into your own project using CodePen, or download the HTML code into a file and run it using your favorite HTTP server.

Once you’re in the IDE, you’ll be able to perform the minor code changes to get the app running quickly.

Application Setup and Configuration

The web page structure should be familiar if you’ve worked with web applications in the past. We start with a plain HTML5 + JavaScript application that has a DIV tag for the map display. We include the PubNub library for realtime communications in the HEAD of the HTML page.

You’ll also want to include the Google Maps API using a SCRIPT tag at the bottom of the HTML page.

At the time of writing, the relevant version is 3.exp.

Note that you’ll need to replace the placeholder maps API key in the SCRIPT SRC attribute accordingly above.

It’s worth mentioning that for HTML5 location to work, you’ll be relying on the user to explicitly allow location access to your app on their device. Handling graceful fallback for cases where location permission is denied is beyond the scope of this tutorial.

The PubNub settings are included within a simple JavaScript map. You can update them with your own values as follows:

Running the Code

You don’t need to do anything special to run the app in CodePen — it runs automatically from the online editor.

Depending on where you are viewing the app (geolocation), and the capabilities of your connection (WiFi or LTE), you may see different locations reported (IP to geo versus GPS location). We’ve found that different devices, as well as different browsers, have their own location accuracy characteristics, some more accurate than others.

Part Two: Map Markers

Implementing map markers to identify where a device is located on a map.

What are Map Markers?

In this part, we’ll add map markers to our web or mobile web map.

Map markers are used to identify the location of a user or device on the map. To get started with the functionality, we’ll place a single map marker on our map and update its location randomly.

This code structure should be familiar if you’ve worked with HTML5 applications in the past.

We start with a plain HTML5 application and include the PubNub library for realtime communications and Bootstrap CSS for minimal styling.

If you’re wondering where the Google Maps API is included, it’s at the very end of the HTML5 page. This ensures the entire DOM is available to the maps code.

Next up, we create a DIV for the application, and inside that, a DIV to hold the map. In our case, we use inline CSS for the width and height.

In a real production-class application, you’d likely define this styling elsewhere. This is what we were talking about when we said we wanted to include the Google Maps script after the Map canvas DOM element was defined.

Now, we have a bunch of JavaScript to get through. Let’s take it one step at a time.

Latitude/Longitude

First, we set up an initial latitude and longitude in the general vicinity of San Francisco. Then, we define a function that gives a point on a circle based on the current time. We define a radius (in degrees lat/lng). We take in a time (in epoch seconds).

Through the magic of trigonometry, the point on the circle is given by x = “initial longitude plus cosine of the input times the radius”, and y = “initial latitude plus sine of the input times the radius”. For convenience, we return a JavaScript object containing those values as latitude and longitude.

Moving Map Marker Position

Now that we have the math out of the way, let’s get to the good stuff. We define map and mark variables to hold our map and marker objects so we can manipulate them on the fly as PubNub events will be coming in.

Then, we define the initialize callback that the Google Maps JavaScript API can call when it’s ready to load, and ensure it’s a member of the window object so it’s accessible to the API.

Next up, we define a redraw event handler which we’ll call whenever we get a new position changed event on the fly.

In the first part of the function, we set the latitude and longitude to the new values from the message. Then, we invoke the appropriate methods on the map and marker objects to update the position and recenter the map.

Connecting the Map to PubNub

Now that we’ve defined our callbacks, we have all the necessary machinery so we can move on to initializing the PubNub realtime data streaming functionality.

First up, we decide the channel name that we’ll expect new position updates to arrive on. Then, we initialize the PubNub library using the publish and subscribe keys we set up earlier in part one.

Finally, we tell the PubNub library to subscribe to the appropriate channel, and attach the redraw function as a listener to the incoming events.

What creates those events, you might ask?

For this simple tutorial, we set up a basic JavaScript interval timer to publish new positions based on the current time. Every 500 milliseconds, we invoke the anonymous callback function which publishes a new latitude/longitude object (created by the circlePoint() call) to the specified PubNub channel.

Initializing Google Maps

Last but not least, we initialize the Google Maps API at the very end to ensure the DOM elements and JavaScript prerequisites are satisfied.

With that, we now have our JavaScript application and we’re able to plot map markers.

Part Three: Live Location Tracking

Making map markers move in realtime based on device location.

What is Geolocation Tracking?

In this part, we’ll live-update our JavaScript map markers we built in part two with live geolocation capabilities.

We’ll use the HTML5 location API to collect the user’s location from their device, and stream and publish location changes (based on the device’s self-reported location) to the map using PubNub Realtime Messaging.

Code Walkthrough

We’ve got our DIV for the application, and the DIV to hold that map already set up from our previous part. So now it’s time to use the HTML5 location API for updating our location in realtime.

HTML5 Location API

Let’s take it one step at a time.

First we set up an initial latitude and longitude in the general vicinity of San Francisco.

Then, we create functions for getting device location using the HTML5 location API and updating the browser location variables. We set an interval timer for periodically obtaining the device location. For convenience, we create return a JavaScript object containing those values as latitude and longitude.

OK, now that we have the HTML5 location stuff out of the way, let’s get to the good stuff.

Live Location

We define map and mark variables to hold our map and marker objects so we can manipulate them on the fly as PubNub events will be coming in.

Then, we define the initialize callback that the Google Maps JavaScript API can call when it’s ready to load, and ensure it’s a member of the window object so it’s accessible to the API.

Next up, we define a redraw event handler which we’ll call whenever we get a new position changed event on the fly. In the first part of the function, we set the latitude and longitude to the new values from the message.

Then, we invoke the appropriate methods on the map and marker objects to update the position and recenter the map.

Now that we’ve defined our callbacks, we have all the necessary machinery so we can move on to initializing the PubNub realtime data streaming functionality.

First up, we decide the channel name that we’ll expect new position updates to arrive on. Then, we initialize the PubNub library using the publish and subscribe keys we set up earlier in the tutorial.

Finally, we tell the PubNub library to subscribe to the appropriate channel, and attach the redraw function as a listener to the incoming events. What creates those events, you might ask? Stay tuned!

Publishing Lat/Long

For this simple tutorial, we set up a basic JavaScript interval timer to publish new positions based on the current time. Every 5000 milliseconds, we invoke the anonymous callback function which publishes a new latitude/longitude object (created by the currentLocation() call) to the specified PubNub channel.

Last but not least, we initialize the Google Maps API at the very end to ensure the DOM elements and JavaScript prerequisites are satisfied.

Part Four: Flight Paths

Show what route our device has taken by drawing a trail behind the map marker.

What are Flight Paths?

In this tutorial, we’ll add flightpaths using Polylines, which allow you to dynamically draw an updated path through user-specified points on the map hosted in your web or mobile web browser.

To demo the capabilities, we place a single polyline and update its endpoint on the fly based on random positions within a bounding box.

Code Walkthrough

We’ve got our DIV for the application, and the DIV to hold that map already set up from our previous tutorial. So now lets add flight paths.

OK, now let’s get to the good stuff.

We define map, mark, and lineCoords variables to hold our map, marker, and polyline coordinates objects so we can manipulate them on the fly as PubNub events will be coming in.

Then, we define the initialize callback that the Google Maps JavaScript API can call when it’s ready to load, and ensure it’s a member of the window object so it’s accessible to the API.

Lat/Long

Next up, we define a redraw event handler which we’ll call whenever we get a new position changed event on the fly.

In the first part of the function, we set the latitude and longitude to the new values from the message.

Then, we invoke the appropriate methods on the map, marker, and polyline objects to update the position, add it to the end of the line and recenter the map.

Initialize PubNub

Now that we’ve defined our callbacks, we have all the necessary machinery so we can move on to initializing the PubNub realtime data streaming functionality.

First up, we decide the channel name that we’ll expect new position updates to arrive on.

Then, we initialize the PubNub library using the publish and subscribe keys we set up earlier in the tutorial.

Finally, we tell the PubNub library to subscribe to the appropriate channel, and attach the redraw function as a listener to the incoming events. What creates those events, you might ask? Stay tuned!

Publishing Lat/Long

For this simple tutorial, we set up a basic JavaScript interval timer to publish new positions based on the current time.

Every 500 milliseconds, we invoke the anonymous callback function which publishes a new latitude/longitude object (with Northeast-moving coordinates) to the specified PubNub channel.

In your app, you’ll likely be getting the position from a live device position or user-reported location.

Last but not least, we initialize the Google Maps API at the very end to ensure the DOM elements and JavaScript prerequisites are satisfied.

Pat yourself on the back, we are done!

PubNub and the Google Maps API work wonderfully well together, Google Maps delivering powerful mapping features and functionality, and PubNub connecting them to devices in realtime.

Originally published at www.pubnub.com.


Published by HackerNoon on 2018/03/20