Add Turn-by-Turn Navigation with Mapbox Directions API

Mapbox Directions API provides a variety of navigation features for driving, cycling and walking, including turn-by-turn directions, traffic-aware routing, and ETA calculation. And with Mapbox, all your functionality is overlayed on one of their many beautiful vector maps.

In this tutorial, we’ll use the Mapbox Directions BLOCK to implement turn-by-turn navigation to build directions into your realtime app. For example, if you’re building a taxi or ridesharing application, the BLOCK enables you to stream geolocation coordinates data between users (like a driver and passenger), then provide navigation to connect them. Or for a delivery app, you can send drop off locations to a fleet of trucks based on their current coordinates and guide them there.

Our simple direction demo will look like this:

Getting Started with Mapbox Direction API

First, you’ll need a Mapbox developer account to take advantage of the mapping APIs, including Directions.

Look at the “Access token” pane of the dashboard and make note of the credential to update the BLOCK below.

Overall, it’s a pretty quick process. And free to get started, which is a bonus!

Setting up the BLOCK

Next up is BLOCKS, which ties together your realtime functionality (via PubNub), with the Mapbox Directions API. In a nutshell, BLOCKS lets you execute functions on your data in-motion, in this case, tap the Mapbox API to calculate your directions and publish them to the end-user.

All in all, it doesn’t take a lot of code to add turn-by-turn directions to our application. Next is the UI.

Diving into the Code – the User Interface

You’ll want to grab these 110 lines of HTML & JavaScript and save them to a file called pubnub_mapbox_directions_ui.html.

The first thing you should do after saving the code is to replace two values in the JavaScript:

YOUR_PUB_KEY: with the PubNub publish key mentioned above.

YOUR_SUB_KEY: with the PubNub subscribe key mentioned above.

If you don’t, the UI will not be able to communicate with anything and probably clutter your console log with entirely too many errors. For your convenience, this code is also available as a Gist on GitHub, and a Codepen as well.

Dependencies

First up, we have the JavaScript code & CSS dependencies of our application.

Overall, we were pretty pleased that we could build a nifty UI with so few dependencies.

The User Interface

Here’s what we intend the UI to look like:

The UI is pretty straightforward – everything is inside a main-component tag that is managed by a single component that we’ll set up in the Angular2 code.

<body>
<main-component>
Loading...
</main-component>

Let’s skip forward and show that Angular2 component template. We provide a simple button to perform the publish() action which gets turn-by-turn directions via a structured data message that will be decorated by the BLOCK.

The component UI consists of a simple list of steps (in our case, the turn-by-turn directions). We iterate over the steps in the controller scope using a trusty ngFor. Each step includes a wealth of data from the Mapbox API. And that’s it – a functioning realtime UI in just a handful of code (thanks, Angular2)!

The Angular2 Code

Right on! Now we’re ready to dive into the Angular2 code. It’s not a ton of JavaScript, so this should hopefully be pretty straightforward.

The first lines we encounter set up our application (with a necessary dependency on the PubNub AngularJS service) and a single component (which we dub main-component).

The component has a constructor that takes care of initializing the PubNub and HTTP services, and configuring the channel name, client and destination lat/lng values, and directions profile name (walking, cycling or driving). NOTE: make sure the channel matches the channel specified by your BLOCK configuration and the BLOCK itself!

We subscribe to the relevant channel, create a dynamic attribute for the messages collection, and configure the event handler to set the self.steps attribute based on the JSON returned from the directions API.

Also, since Angular2 doesn’t have an $interval component, we use RxJS Observable to set up an interval timer for updating the client browser’s location. Every 3 seconds, we update the Angular2 component with the client’s latitude/longitude.

Now that we have a new component, we can create a main module for the Angular2 app that uses it. This is pretty standard boilerplate that configures dependencies on the Browser, Forms, and HTTP modules and the PubNubAngular service.

Not too shabby for about 110 lines of HTML & JavaScript! With that, we conclude this tutorial. You now have a functioning app that calculates turn-by-turn navigation, processed entire in the PubNub network and pushed in realtime to your end user.