Languages: English简体中文繁體中文

SensorThings API - 过滤观测值(Observations)并显示图表

第一部分教程中,我们根据一个DatastreamObservation绘制了图表。在第二部分教程中,我们根据多个DatastreamObservation绘制了图表。在这部分教程中,我们会更进一步介绍如何获取特定日期的Observations并绘制图表。我们将会学习如何通过SensorThings API过滤Observations,同时也会学习如何取回分页的Observations

本次教学唯一与第一部分不同的是取回数据部分。我们会关注如何取回数据而不是绘制图表。您也可以回到第一部分回顾如何绘制图表。

SensorThings API 过滤功能

通过SensorThings API 提供的查询选项(query option)取回数据非常容易且灵活。$filter是查询选项其中之一,可以用来查询Observations。基本上,它可以根据Observations的属性(properties)来回传过滤后的Observations

我们要取回特定一天的Observations,可根据phenomenonTime过滤Observations。 我们将会使用两个操作符号,"大于等于(greater than or equal)" ge / >= 以及 "小于(less than)" lt / <

GET https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)/Observations?$filter=phenomenonTime ge '2017-02-07T00:00:00.000Z' and phenomenonTime lt '2017-02-08T00:00:00.000Z'
与之前的教程相比,除了发送HTTP GET请求的URI不同,其他方面没有区别。代码如下:

var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI , function(datastream) {
  $.getJSON(datastream["Observations@iot.navigationLink"]+"?$filter=phenomenonTime ge '2017-02-07T00:00:00.000Z' and phenomenonTime lt '2017-02-08T00:00:00.000Z'" , function(observations) {});
});

您可能注意到了上面的HTTP GET响应中,我们有@iot.nextLink。SensorThings 服务支持分页,并且下一页结果的链接可在@iot.nextLink属性中找到。在这种情况下,如需取回特定日期的所有Observations,如若存在@iot.nexLink,则需跟随@iot.nexLink来获取分页数据。所以为了确保在绘制图表前取回了所有数据,这里我们需要使用JavaScript Promise来控制加载数据的异步jQuery AJAX。

我们定义一个递归函数不断取得下一页,直到抵达最后一页(最后一页没有@iot.nextLink),然后转换Observations为图表可接受的格式。

代码如下:

function followNextLink(response){
  var data = [];
  // chart library expects an array of [timestamp, value]. Prepare the data returned from SensorThings for chart.
  $.map(response.value, function(observation) {
      var timestamp = moment(observation.phenomenonTime).valueOf();
      data = data.concat([[timestamp, parseFloat(observation.result)]]);
  });
  // If there is a nextLink. follow it to get all the data.
  if(response["@iot.nextLink"]!== undefined){
      return new Promise(function(resolve, reject) {
          $.getJSON(response["@iot.nextLink"], function(response){
              // Call followLink again on the response to recursively get all the data
              var resultPromise = followNextLink(response);
              resultPromise.then(function(d){
                  resolve(data.concat(d));
              });
          });
      });
  } else {
    //When there is no more next link return the data
    return Promise.resolve(data);
  }
}

在一个回调函数中调用这个递归函数,以下是修正过后的代码:

var datastreamURI = "https://toronto-bike-snapshot.sensorup.com/v1.0/Datastreams(1504)";
$.getJSON(datastreamURI, function(datastream) {
  var primaryPromise = new Promise(function(resolve, reject) {
      $.getJSON(datastream["Observations@iot.navigationLink"] + "?$filter=phenomenonTime ge '2017-02-07T00:00:00.000Z' and phenomenonTime lt '2017-02-08T00:00:00.000Z'", function(response) {
          //Follow the nextLink to retrieve all the Observations for that day
          resolve(followNextLink(response));
      });
  });
  //When the whole data is ready:
  primaryPromise.then(function(data) {
      data.sort(function(a, b) {
          return a[0] - b[0];
      });

      /** Now data is ready for plotting on chart **/
  });
});

最终绘制的图表如下:

在 SensorThings Share 上查看代码

下一步?

在本系列最后一部分教程中,我们将会向您介绍如何根据Datastream上最新一个Observation绘制一个仪表图。

第四部分 - 仪表图