Languages: English简体中文繁體中文

SensorThings API - Getting Started with Locations and Mapping

This is of a four-part series on mapping with SensorThings.

The SensorThings API handles a wide variety of data necessary for creating a geospatial-enabled Internet of Things (IoT) solution. One of the entities in SensorThings is the Location, which is used to indicate (unsurpisingly) the location of things in the system. Today, we're going to focus on how we can retrieve Locations from SensorThings, and display them in a map.

Sharing is Good

SensorThings allows you to share data using open standards, which is a good thing. The city of Toronto has a bike sharing program, which is also a good thing. This program shares bike availability and docking availability information via an open data feed, which is, you guessed it, a good thing. We've put these good things to good use by taking a snapshot of the Bike Share Toronto data and putting it in a SensorUp Cloud instance. We'll be using that instance as the data source for this tutorial.

Before we get our Locations from SensorThings, let's make sure we have a map to show them on!

Leaflet to the Rescue

One of the most popular mapping libraries on the web is Leaflet, and we'll be using it in this tutorial. Let's start by showing a basic map.
See the code on SensorThings Share

The full code to show the above map is available by clicking on the "See the code on SensorThings Share" button. Here's a few things of note.

This loads the CSS and JavaScript for the Leaflet library.
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
This creates a 500 pixel tall div tag. Later, we will tell Leaflet to show the map in this div.
<div id="map" style="height: 500px"></div>
This creates a Leaflet map in the map div we created earlier, sets the latitude/longitude to that of Toronto, and sets the zoom level of the map to 11.
var map = L.map('map')
  .setView([43.6532, -79.3832], 11);

At this point, we've created a map, but if we don't specify the map tiles to use, there would be literally nothing to see! Luckily, there are a lot of map tiles available.

L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
	attribution: '&copy; OpenStreetMap &copy; CartoDB',
	subdomains: 'abcd',
	maxZoom: 19
}).addTo(map);

The above code provides Leaflet with the information it needs to load and display map tiles made available by CartoDB. Feel free to experiment with other map tiles.

If you'd like to learn more about Leaflet, they provide a number of great tutorials for you to explore.

It's About Location, Location, Location

Great, we have our map. But it seems kinda empty.

Luckily, consuming Locations from SensorThings is an essential part of a complete diet. And it's easy as HTTP!

GET {{staBaseUrl}}/Locations

This HTTP GET request will retrieve the Locations from the SensorThings server. Feel free to copy-and-paste the above URL into your browser address bar, and you should see a JSON response equivalent to the one below.

You can see that each Location has a number of different properties, including name, description, encodingType and location (which specifies the geometry of the Location in GeoJSON).

Add the Bike Share Locations

Now let's add the Locations we retrieved from toronto-bike-snapshot.sensorup.com to the map.
See the code on SensorThings Share
We've added a library, axios, that can be used to make HTTP requests to SensorThings.
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.3/axios.min.js"></script>
And then we use that library to retrieve the Locations from the SensorThings server, convert them into a format that can be used by Leaflet, and then adjust the map so that it fits the Locations.
// Get the Locations from the SensorThings server
axios.get('https://toronto-bike-snapshot.sensorup.com/v1.0/Locations').then(function(success) {

  // Convert the Locations into GeoJSON Features
  var geoJsonFeatures = success.data.value.map(function(location) {
    return {
      type: 'Feature',
      geometry: location.location
    };
  });

  // Create a GeoJSON layer, and add it to the map
  var geoJsonLayerGroup = L.geoJSON(geoJsonFeatures);
  geoJsonLayerGroup.addTo(map);

  // Zoom in the map so that it fits the Locations
  map.fitBounds(geoJsonLayerGroup.getBounds());
});

What's Next?

We've barely scratched the surface of what you can do with SensorThings. Part 2 will show you how you can use data from SensorThings to style the map, as well as add some basic interactivity.

Proceed to Part 2 - Data-Driven Styling