Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

IoT - Asset Tracking with Leaflet and ArcGIS

In this Code Pattern composite, we'll demonstrate how to track mobile assets and visualize incoming sensor data on an interactive map. This demonstration is implemented as a Node.js application. On the front end, the Leaflet.js + ArcGIS libraries are leveraged to render the map and icons. On the backend we use the Express.js framework to serve the UI view and host API endpoints. Asset location updates are published to the Watson IoT Platform in the form of a JSON object like so.

"d" : {
  "node_id": "asset1",
  "lat": "-118.417392",
  "long": "34.0057",
  "timestamp": "2018-06-30T07:10:55.174Z",
  "sensor": {
    "sound": "72",

As each asset publishes their location updates, their corresponding marker is adjusted in the mapping application. Each update is also archived in a Cloudant database, so the user can easily trace back through the path traversed by the asset.


Install Prerequisites:

Node.js packages

If expecting to run this application locally, please continue by installing Node.js runtime and NPM. If your system requires multiple versions of Node for other projects, we'd suggest using nvm to easily switch between Node versions. NVM can be installed with the following commands

curl -o- | bash
# Place next three lines in ~/.bash_profile
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/" ] && \. "$NVM_DIR/"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
nvm install v8.9.0
nvm use 8.9.0

To run the UI locally, we'll need to install a few node libraries which are listed in our package.json file.

  • Leaflet.js: Open source library for interactive mapping
  • MQTT: Client package to subscribe to Watson IoT Platform and handle incoming messages

Install the listed node packages by running npm install in the project root directory.

npm install

Start the application with

node app.js


There are two methods we can use to deploy the application, either use the Deploy to IBM Cloud steps OR create the services and run locally.

  1. Clone repository
  2. Setup repository codebase locally OR Deploy to IBM Cloud
  3. Create Watson services with IBM Cloud
  4. Start the Application
  5. Retrieve service credentials
  6. Configure and run the application

1. Clone the repository

Clone the iot-mapping project locally. In a terminal, run:

git clone

2. Deploy Application to IBM Cloud

  1. To deploy the application to IBM Cloud, we'll need to leverage the IBM Cloud CLI. Ensure the cli is installed using the prerequisites section above, and then run the following command to deploy the application
bx cf push
  1. To see the app and services created and configured for this Code Pattern, use the IBM Cloud dashboard, or run bx cf apps and bx cf services in the terminal. The app should be named iot-mapping with a unique suffix.

2. Deploy Application locally

Install the IoT Mapping node packages by running npm install in the project root directory.

npm install

Start the application with

npm start

NOTE: These steps are only needed when running locally instead of using the Deploy to IBM Cloud button.

3. Create Services

Next, we'll need to deploy our service instances using the IBM Cloud dashboard.

Watson IoT Platform

Navigate to the IBM Cloud dashboard at and click the "Catalog" button in the upper right

In the search bar type "Internet of Things" and click the icon titled "Internet of Things Platform".

Select the pricing plan and click "Create". If deploying on an IBM Lite account, be sure to select the free "Lite" plan

Additional Configuration: Generate Watson IoT service credentials

After being provisioned, the IoT Platform service will need a bit of additional configuration, as we'll need to generate a set of credentials for connecting to the broker. We can do so by entering the IoT Platform dashboard, selecting "Devices" from the left hand menu, and then clicking the "Add Device" button.

Next, provide a device type and ID.

The next few tabs (Device Information, Groups, Security) can be left as is with the default settings.

Clicking the "Finish" button will register a device and generate a set of credentials that can be used to publish messages to the IoT Platform. Be sure to take note of the Device type and Device ID, and place both in the cfcreds.env file.

We'll need to generate a different set of credentials to be able to publish and subscribe to the MQTT Broker

We can do so by selecting the "Apps" option in the left hand menu. Then, click the "Generate API Key" button

We can leave the fields in the "Information" blank and click next. In the "Permissions" tab, we'll select the "Backend Trusted Application" role. Once this is selected, click "Generate Key"

The result will give us an API Key and Authentication Token. These can be supplied as the username and password for a MQTT client. To make setup a bit easier, place these values in the cfcreds.env file as IOT_API_KEY and IOT_APP_AUTH_TOKEN

5. Obtain service credentials

Now that we've instantiated our Watson IoT Platform service instance and the corresponding MQTT credentials, we'll next need to place the credentials into a .env file in our application root directory. This will allow for the application to authenticate to the MQTT broker and listen for updates from registered IoT devices.


6. Run the application

  1. Start the app locally with node app.js.

  2. Enter the following URL in a browser: http://localhost:3000/
    Note: If you run into an issue with the port already being used, set the PORT environment variable to the port you'd like to use.

7. Visualize assets in UI

Now, we can actually confirm that the UI is able to visualize asset locations and sensor data.

There are a few ways to import data to be viewed in the mapping application.

Each option requires the following

  • A unique string identifier, corresponding to the specific IoT device.
  • A set of Longitude/Latitude coordinates
  • A timestamp, which should be represented as either the UTC epoch format or the ISO-8601 format.
  • Sensor value(s) in a key/value format, ex. sound: 65 (Optional)

The first option is to create a node manually. This can be done by clicking the "Add Node" button and entering the required values. Once they have been entered, pressing "Create" should render a marker like so. A transparent circle will also be added if a sensor is provided, and the radius length is determined by the sensor value

In a live scenario, these updates should come in the form of MQTT messages sent by associated IoT devices. Each device can broadcast an update by publishing a MQTT message with the following payload:

mqtt_pub -v -i "a:${IOT_ORG_ID}:client_pub1" -u "${IOT_API_KEY}" -P "${IOT_AUTH_TOKEN}" -h '' -p 1883 -t "iot-2/type/${IOT_DEVICE_TYPE}/id/${IOT_DEVICE_ID}/evt/assetMapper/fmt/json" -m '{
    "d" : {
    "node_id": "node2",
    "lat": "-118.317392",
    "long": "34.100057",
    "timestamp": "2018-06-30T07:10:55.174Z",
    "sensor": {
      "sound": "72"

We can also bulk import CSV datasets. In this example, we'll use data from tracking a herd of zebra in Botswana, which can be downloaded here. This file can be loaded by clicking the "Import CSV File" button.

Once the file is loaded, headers will need to be selected to identify which columns correspond to each individual node id, location, and timestamp. This can be done by manually inspecting the file

Next, select the headers in the "Select Dataset Columns" form

Once the columns have been selected, markers for each node id should be visible like so.

We can also click the "Show all paths" button to draw the path traversed by each asset.

If there are multiple datapoints associated with an asset, we can use a "range slider" to trace back and view an assets path. As the slider is adjusted, each marker should update their location and sensor identifier. Also, the corresponding timestamp should be shown in the bottom right corner of the map.



This code pattern is licensed under the Apache Software License, Version 2. Separate third party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.

Apache Software License (ASL) FAQ

You can’t perform that action at this time.