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
之间的变化可能更有用。