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