【實習生日誌】Processing教學(1):讀取Youbike公開資訊

八月 10, 2015
Facebook
Twitter
文/鄭元傑
Open Data日益盛行,許多政府單位也將原有的資料開放出來供民眾使用,筆者使用Processing讀取JSON格式的資料,同時將資料顯示在地圖上。JSON是現在流行的文字結構資料,主要分物件(Object)以及陣列(Array),裏頭包含名稱:值(collection),過程會以實例說明。

工具

電腦一臺:需裝有Processing主程式,筆者是使用Mac(僅些許環境設定不同,Google皆有教學) 。

步驟一:安裝函式庫

https://github.com/runemadsen/HTTP-Requests-for-Processing
http://unfoldingmaps.org/downloads
將下載的資料匣放入「文件」→「Processing」→「 Libraries」當中
接著重新啟動Processing就可以了

步驟二

打開網頁瀏覽器到台北市政府開放資料網站,在「資料目錄」中找到Youbike即時資料
連結如下:http://data.taipei/opendata/datalist/datasetMeta?oid=8ef1626a-892a-4218-8344-f7ac46e1aa48
正常來說畫面如下:
先將「資料集ID」的範例網址貼上(http://data.taipei/opendata/datalist/apiAccess?scope=datasetMetadataSearch&q=id:8ef1626a-892a-4218-8344-f7ac46e1aa48
此時會面會跑出一整頁純文字的資訊介紹,格式是JSON
找到其中一欄「fieldDescription」中可以看到欄位對應中文資訊,先記住幾個自己需要的欄位
接著將「YouBike臺北市公共自行車即時資訊RID」的範例網址貼上(http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=ddb80380-f1b3-4f8e-8016-7ed9cba571d5
此時網址也會跑出一連串的文字資料。筆者是使用Google Chrome,瀏覽器會自動將整理JSON格式,也可以到Chrome線上應用程式商店安裝JSON viewer。
接著我們將介紹資料的架構:首先可以看到最上方是個「{」左大括號,這表示整個JSON文件是以JSONObject形式回傳;在這個JSONObject底下又有一個JSONObject:result,而result裏頭有幾個元素:limits、count…還有一個很長的results,results後面接著「[」左中括號,這表示results本身是個JSONArray,裏頭包含許多JSONObject,每個JSONObject中可以看到欄位都一樣。
內容對照上述資料集中的欄位介紹,不難看出這就是每個Youbike站的內容。接著我們將實作以Processing抓取幾個重要的元素
sna:場站名稱、lat:經度、lng:緯度、tot:場站的總停車格、 sbi:場站的目前車輛數
图片

步驟三:開啟Processing,載入第一個函式庫

import http.requests.*;
//宣告一個全域變數url,也就是「YouBike臺北市公共自行車即時資訊RID」的範例網址
String url = “http://data.taipei/opendata/datalist/apiAccess?scope=resourceAquire&rid=ddb80380-f1b3-4f8e-8016-7ed9cba571d5″;
void setup(){
//發送HTTP GET request,這個動作跟我們在瀏覽器上輸入網址是一樣的
   GetRequest get = new GetRequest(url);
  get.send();
//當Youbike公開資料是以一個JSONObject回傳,所以要用JSONObject來接收回傳的資料(紅框)
  JSONObject response = parseJSONObject(get.getContent());
//重要資料都是在results這個Array中,但是results被包含在result這個object中,所以特別讀取出來(綠框)->(黃框)
   JSONArray bikelists = response.getJSONObject(“result”).getJSONArray(“results”);
   //取得JSONArray後,就逐一讀出各站JSONObject資訊(藍框)
   for(int l=0;l<bikelists.size();l++){
     JSONObject bikelist = bikelists.getJSONObject(l);
    //getString()裏頭的變數是對照JSONObject中的欄位名
 println(“地點:” + bikelist.getString(“sna”) + “經度:” + bikelist.getString(“lat”) + “緯度:” + bikelist.getString(“lng”) + ” 總車位:” +bikelist.getString(“tot”) + ” 剩餘車位” + bikelist.getString(“sbi”));
    }
}
這樣就完成了,可以在Processing輸出的地方看到資訊
不過有時候Server會連不進去(還蠻容易發生的…..),所以會出錯「JSONObject must begin with “{”」,網頁部分也會無法正常顯示畫面,但只要稍待一兩分鐘就會恢復正常。
另外,發送Http request要寫入void draw()時要特別處理過,因為一般開放資料都會限定同一IP位置在單位時間內的讀取次數,放在draw裡頭而framerate又設成30,這樣一秒鐘程式會發送30次request,會大量耗損Server的資源,被視為惡意攻擊,這部分要特別留意。

更詳盡資料請參考data.taipei的開發指南
http://data.taipei/opendata/developer#

步驟四:使Processing支援中文

在IDE中輸出中文需要設定,不然讀取到的中文字都是亂碼,可參考下列網站。
http://shenshengpo.blogspot.tw/2013/06/processing-20.html
https://yuanchieh.wordpress.com/2015/05/20/processing-json-2-支援中文/

步驟五:將資料視覺化

筆者希望將資料依據地點在地圖上顯示,如下圖。
這時我們需要使用unfolding函式庫
http://unfoldingmaps.org/tutorials/markers-simple.html
unfolding 函式庫定義了地圖顯示以及Marker標記的方式,所以我們只要修改參數即可。這邊筆者是參照函式庫中的LabledMarkerApp範例改寫。

筆者希望每個標記點都保有各自的地點與腳踏車資訊(也就是我們從網站抓下來的資料),所以就定義了一個class Station,而每個Station都是地圖上的標記,相關的函式unfolding函式庫都處理好了,為了方便實作,所以直接擴充unfolding的SimplePointMarker。其餘內容註記於程式碼中。
https://github.com/sj82516/Processing_JSON_Youbike_Info-map

NOTE:

  1. 使用他人編寫好的函式庫可以加速開發的流程,只是需要細讀官方文件才能了解函式與變數的意義以及如何有效呼叫與使用。
  2.  unfolding函式庫真的不錯用,有多種地圖背景可以選擇,而且有mipmap效果。
  3. 目前只是初步套用函式庫,接著將改善整體UI,都黑黑灰灰的有點單調 。
  4. 未來將移植到Raspberry pi上,節合LED做更動態的顯示,同時架設Server儲存讀取資料,這樣在官方更新資料前就可以先讀取自身Server的數據,不用反覆Request。
  5. 筆者會持續增添功能,於第二篇有更詳盡的解析。

Social media & sharing icons powered by UltimatelySocial