Languages: English • 简体中文 • 繁體中文
SensorThings API - 數據驅動樣式設計
在第一部分中, 我們:
- 使用Leaflet製作了一個簡單地圖
- 使用多倫多自行車共享站點的位置信息
Locations
填充了這張地圖
首先,調整地圖
在我們深入了解數據驅動樣式設計的細節之前,讓我們對地圖進行一些微調。
- 把標記改成圓圈
- 為了使用戶了解數據來源,增加一行代碼來註明地圖中所提供的開放數據屬於自於多倫多市
pointToLayer
現在引入了一個函數,它回傳了圓形標記(circleMarker)來替代預設的標記圖案。
var geoJsonLayerGroup = L.geoJSON(geoJsonFeatures, {
// Change the default marker to a circle
pointToLayer: function(geoJsonPoint, latlng) {
return L.circleMarker(latlng);
}
});
map.attributionControl.addAttribution("Contains information licensed under the Open Government Licence – Toronto.");
自行車的去向?
現在,我們已經在地圖上放置了很多點,它們看起來還不錯,但不夠特別。因為雖然我們知道了自行車共享站點的位置,但如果能進一步知道每個共享站點有多少自行車將會更好。現在我們就來做這件事。
在SensorThings中,例如“可用的自行車(available bikes)”這樣的信息,可稱為觀測屬性ObservedProperty
。
此次教程中的使用的SensorThings服務器包含了兩個觀測屬性ObservedProperties
- 可用的自行車(Available bikes)
- 可用的站點(Available docks)
請參考以下代碼
雖然對我們而言,可用的自行車和可用的站點都是重要的信息。但依需要,這部分教程將只關注可用的自行車數量。
現在我們要做的,是找到在特定的Location
中可用自行車的數量。在SensorThings中,這類的信息被存儲在觀測值Observation
中。我們必須通過SensorThings中多個其他的實體(entities)來獲取觀測值Observation
。具體來說,我們需要先獲取在這個位置Location
的Things
,以及Things
對應的數據流Datastreams
(因為只有Datastream
包含可用自行車的信息),然後我們再獲取每個數據流Datastream
中的觀測值Observations
(我們只要最新的一份數據)。這些雖然看起來繁瑣,但這些實體可支持您進行複雜特定的查詢。
以上這個查詢看起來似乎有些難度,但實際上並不複雜。
-
/Locations
: 對Locations
的端點進行請求,與之前的請求相同。 -
$expand=Things/Datastreams($filter=ObservedProperty/name eq 'available_bikes')
: 通過擴展這個Location
來獲取Things
以及它對應的多個Datastreams
,然後在結果中過濾其他Datastreams
,僅保留ObservedProperty
中屬性名為'available_bikes'
的結果。 -
Things/Datastreams/Observations($orderby=phenomenonTime desc;$top=1)
: 這是擴展$expand
參數的第二部分。這部分對於剩下未被過濾的Datastreams
擴展獲得觀測值Observations
,並且獲取根據phenomenonTime
排序後的最新一份數據。因此只會傳回最新的觀測值Observation
。
這些響應包括:
Location
的經度和緯度座標(之前取回過)Location
最新一些的可用自行車數量(本次新增)
整合到地圖
現在我們知道如何從每個站點取回可用自行車的數量,接下來就準備建立我們的地圖了。
Features
裡增加了一行properties: location
,以便LeaFlet來訪問SensorThings響應中的Things
,Datastreams
, 和Observations
。
var geoJsonFeatures = success.data.value.map(function(location) {
return {
type: 'Feature',
geometry: location.location,
properties: location
};
});
#38f
)和"不足的"的自行車(顯示為紅色)。我們姑且設定了一個值(5),超過五輛自行車即為“足夠的”,小於則為“不足的”。
pointToLayer: function(geoJsonPoint, latlng) {
var enoughBikeColor = "#38f";
var fewBikesColor = "red";
var availableBikes = geoJsonPoint.properties.Things[0].Datastreams[0].Observations[0].result;
return L.circleMarker(latlng, {
color: availableBikes > 5 ? enoughBikeColor : fewBikesColor
});
}
下一步?
您是那種會告訴老師他們錯了的學生嗎?如果您是,此刻您肯定會舉手,事實上,也許此刻您會瘋狂地揮舞手臂引起老師注意。
那是因為您可能發現了,/Locations
的響應中"@iot.count": 199
,但其實只有100個 Locations
被傳回來。您也許還會注意到這裏暗藏了一個@iot.nextLink
屬性。
我們還沒有顯示所有的自行車分享站點。
所以,接下來請繼續第三部分。