Languages: English • 简体中文 • 繁體中文
SensorThings API - 展示观测值(Observations)
SensorThings API可以处理各类创建地理空间相关的物联网(Internet of Things, IoT)解决方案的必备数据。SensorThings中有多个实体(entity),其中一个实体是观测值Observation,它是用于存储传感器(Sensor)观察值(observations)/读数。分析IoT数据的第一步就是可视化物体(thing)中的不同Observation。本教程将关注如何从SensorThings取回Observations并且显示在图表上。
多伦多自行车共享资料集
SensorThings允许您透过开放标准来共享数据。现在,多伦多市有一个自行车共享计划,这个计划通过开放数据源(open data feed)共享了可用自行车以及可用站点的数据。我们获取了一些多伦多的自行车数据,并且把这些数据上传到了SensoUp云平台。这个系列教程中将使用这些数据。
先决条件
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highstock/4.2.6/highstock.js"></script>
第一步: 从SensorThings服务器取回观测值(Observations)
在这一步中,我们会取回自行车共享数据的Observations。
SensorThings API中,每个Thing可以有多个数据流(Datastream),每个数据流Datastreams含有观测值Observation。我们可以将Datastreams看作是一个传感器sensor所有Observations的集合。
现在我们要做的就是将一个Datastreams(同属一个sensor)的所有Datastreams展现出来。所以接下来,首先是取回Datastream,然后取回这个Datastream的Observations,最后显示在图表上。
我们可以使用HTTP GET请求取得Datastream。
这是使用jQuery来取得一个Datastream的代码:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {});
然后,在这个回调函数中,我们可以跟随Observations的@iot.navigationLink取回这个Datastream的Observations,可继续用HTTP GET请求来实现。
这是取回一个Observations的代码:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
$.getJSON(datastream["Observations@iot.navigationLink"], function(observations) {});
});
现在我们已经得到了绘制图表所需的Observations数据。 然而,Highcharts接受的数据格式是不同的:
- 首先,数据需要按时间增序排列;
- 第二,数据格式须为数组
[timestamp,value],比如[[phenomneonTime1, result1],...]
。
因此,在开始准备图表之前,先调整数据格式。这是重新编排格式和排序后的观测值(Observations)数据的代码:
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
$.getJSON(datastream["Observations@iot.navigationLink"], function(observations) {
var data = $.map(observations.value, function(observation) {
var timestamp = moment(observation.phenomenonTime).valueOf();
return [[timestamp, parseFloat(observation.result)]];
});
data.sort(function(a, b) {
return a[0] - b[0];
});
});
});
现在我们的数据已经准备好了,让我们开始准备图表吧!
第二步: 显示图表
首先建立了一个div容器。接着,告诉Highcharts在这个div显示图表。
<div id="chart" style="height: 500px"></div>
现在我们已经在chart div建立了Highcharts图表,并且设定标题为"Loading chart data"。当我们将数据加载到图表中时,我们将更新此标题。
var chart = new Highcharts.StockChart("chart", {
title: { text: "Loading Chart Data..." },
series: []
});
我们可以让图表在加载数据的过程中显示“正在加载(loading)”,直至数据加载完毕再显示图表。Highcharts可以处理这个功能,而且代码很简单。
chart.showLoading();
首先,依据Datastream取回到的数据来更新图表标题,代码如下:
vchart.setTitle({ text: datastream.description });
然后,将准备好的数据加载到图表上,只需要使用Highcharts中的"addSeries"函数来加载数据。再通过给图表上的点设定数据点提示框,当鼠标滑过图表时,它将会提示unitOfMeasurement的讯息,代码如下:
var series = chart.addSeries({
data: data,
tooltip: {
valueSuffix: " " + datastream.unitOfMeasurement.symbol
}
});
最后,更新Y轴并加入unitOfMeasurement,然后从图表中删除"正在加载"。
series.yAxis.update({
title: {
text: datastream.unitOfMeasurement.name + " (" + datastream.unitOfMeasurement.symbol + ")"
}
});
chart.hideLoading();
确认结果
如何提升?
之前我们向Datastream以及它的Observations发送了两次HTTP GET请求。但其实,如果在Datastream中中扩展$expand它的Observations来进行查询,就只需要发送一次请求。
$expand;
var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)?$expand=Observations";
$.getJSON(datastreamURI, function(datastream) {
var data = $.map(datastream.Oservations, function(observation) {
var timestamp = moment(observation.phenomenonTime).valueOf();
return [[timestamp, parseFloat(observation.result)]];
});
data.sort(function(a, b) {
return a[0] - b[0];
});
});
$expand后的结果如下:
下一步?
我们的下一部分教程将向您展示,如何在同一图表上显示多个Datastream。这种类型的图表对于比较多个Datastreams之间的变化可能更有用。