Hands on

Who wants ice cream!? — A HERE Maps API for JavaScript Tutorial (Part 7: Traffic)

By Richard Süselbeck | 22 November 2016

Who wants ice cream?! — In this series of blog posts we are going to develop a small web application called "Gelary" using HERE maps and services. Gelary aims to disrupt the ice-cream market by enabling ice-cream producers to deliver their sweet goods directly to their customers, wherever they are.

The final application will resemble a mobile dashboard view for the employees of our little start-up which they can either take on the road or use at Gelary HQ to plan their work.
It will consist of a map and a floating control panel behind a menu button. The map is used to visualise a route, starting from the user's current position along a series of customers, and the traffic situation along the route. The control panel will enable our delivery drivers to search for nearby ice cream shops, display turn-by-turn directions as well as to calculate the best pick-up location for a group of selected customers.
The app will also be able to handle order changes: e.g. if a customer cancels or updates his or her position, the route will automatically be recalculated.

To keep things simple our application will use plain Javascript (ES5) and front-end technologies and will target mobile and desktop browsers alike.

What will we learn in this tutorial?

In the previous post we learnt how to react to outside influences, if you haven't read it yet, you might want to take a look at it first before going on.

In order to give our drivers more accurate delivery times, we need to know if there are any issues along their route that might affect their delivery. For this, we will have a look at traffic and incident data, create a new class HERETrafficPanel to encapsulate it and then introduce layers to show the issues on the map.
Sounds cool? — It is! Let's find those problem areas!

Traffic API

Due to our earlier hard work, displaying traffic and incidents on our map is going to be really easy. Actually, we already have all the required pieces for displaying the data! With the HERE Traffic API we treat these visualizations as layers on the map, so all we have to do is to retrieve those layers and insert them on the map, easy right?

Our map tiles already come from a default layer instance, the instance that we previously received from the platform object. Default layers also contain traffic and incident tiles, so we can simply get them from there. Simple!

  var defaultLayers = platform.createDefaultLayers();
   
  var trafficLayer = defaultLayers.normal.traffic;
  var incidentsLayer = defaultLayers.incidents;
view raw gelary-part7-1.js hosted with ❤ by GitHub

All that we need to do is place these layers on our map. For adding and removing layers the map instance provides methods addLayer and removeLayer.

For adding layers:

  this.map.addLayer(trafficLayer);
  this.map.addLayer(incidentsLayer);
view raw gelary-part7-2.js hosted with ❤ by GitHub

And for removing them:

  this.map.removeLayer(trafficLayer);
  this.map.removeLayer(incidentsLayer);
view raw gelary-part7-3.js hosted with ❤ by GitHub

You can read up more about the Traffic API in the documentation.

Traffic panel

Now we have learned the fundamentals for handling traffic and incident data layers. That's all good, but next we have to think how we want our users to interact with these layers. We also want to encapsulate the logic somehow so that our code stays clean and doesn't get too bloated.

To solve both of these issues let's create a new class which renders buttons for the user interaction and holds the state of the displayed layers. Let's call it HERETrafficPanel.

Let's start by creating a constructor for HERETrafficPanel. It takes the traffic and incident layers and also a placeholder DOM element where we will insert the panel.

  function HERETrafficPanel (element, map, options) {
  this.element = element;
  this.map = map;
  this.trafficLayer = options.trafficLayer;
  this.incidentsLayer = options.incidentsLayer;
   
  this.state = {
  showTraffic: false,
  showIncidents: false
  };
   
  this.updatePanel();
  }
view raw gelary-part7-4.js hosted with ❤ by GitHub

The HERETrafficPanel panel also takes care of rendering the panel with toggle buttons for both layers. Then we only have to hook the buttons to call the addLayer/removeLayer methods.

Let's write a simple click handler for toggling the traffic and incident data:

  HERETrafficPanel.prototype.toggleTrafficData = function() {
  if (this.state.showTraffic) {
  this.map.removeLayer(this.trafficLayer);
  } else {
  this.map.addLayer(this.trafficLayer);
  }
   
  this.state.showTraffic = !this.state.showTraffic;
  this.updatePanel();
  };
view raw gelary-part7-5.js hosted with ❤ by GitHub

We can apply the same logic with the incidents layer. 

Next we are going to instantiate our traffic panel inside of the HEREMap class so that we can easily provide layers to our new panel object.

Let's instantiate our newly created panel in the HEREMap constructor.

  var trafficPanelOptions = {
  trafficLayer: defaultLayers.normal.traffic,
  incidentsLayer: defaultLayers.incidents
  };
   
  var trafficPanelElement = document.querySelector('#traffic-panel');
   
  this.trafficPanel = new HERETrafficPanel(trafficPanelElement, this.map, trafficPanelOptions);
view raw gelary-part7-7.js hosted with ❤ by GitHub

Now the HERETrafficPanel is a stand alone object that handles rendering and user interaction with traffic and incident layers. Cool!

traffic.png

Wrapping up

We can now see the realtime traffic and incident data in our app and our ice cream drivers can select their route accordingly. Great! Ice cream can now be deliverd without delay!

In the next post we'll wrap up what we have learned so far and give some tips and ideas on how you can utilize HERE APIs even further. — Stay tuned!