PM2.5是最近很熱門的一個話題,有興趣的人可以查一下為什麼PM2.5這麼夯。目前在網路上可以找到許多開放的即時資料,在這一個例子中是使用PM2.5開放資料入口網站中所提供的AIRBOX即時監測資料,來做一個應用。想像一個狀況,使用者目前位在某地,想要知道那附近的PM2.5、溫度與濕度等相關資訊,這時就可以使用上述的開放資料來查詢,不過這些資料並不會跟你說離你最近的監測站是那一點,而且它顯示出的資料格式一般人應是看不懂的。

這一個例子一開始的構想是使用者進到網頁後,頁面會抓取使用者目前所在位置的經緯度(使用Google Map API),再利用這個經緯度去開放資料中抓取離使用者最近的監測站的相關數值。但是後來在測試時發現,使用行動裝置的瀏覽器所抓到的使用者經緯度是相當準確的,但是由桌上電腦中的瀏覽器去抓到的經緯度跟實際的經緯度有相當的距離差異,嚇掉了我的下巴。

進入主題,首先是利用Google Map API來抓取使用者開啟瀏覽器時的經緯度,並將其值置入網頁中的元件備用

記得在網頁載入時呼叫它

頁面中安排了兩個元件,存放由javascript抓取的經緯度,以供ASP.NET進行後續的處理

就是在這個階段,我發現在我辦公室電腦瀏覽器所抓的經緯度(在家裡的電腦測試是一樣類似的狀況),跟實際位置有相當大的差距。呵呵,我明明坐在辦公室,卻說我在官田(在家裡是說我在安平,由行動裝置的瀏覽器不管在那裡測位置倒都是蠻正確的),所以後來有加了一個補強功能的作法

在取得經緯度後,就可去抓取開放資料來做進一步的處理,由於這裡用的開放資料是JSON格式,所以使用的解析方式是上次的文章"以超偷懶的方式解析JSON"中的方式來進行。JSON轉換成XML後就可以LINQ去操作其他的內容(以簡易的方式來解析XML中的資訊)。由於使用的開放資料似乎是5分鐘更新一次,所以這裡使用了一個Application變數來記錄最後抓取開放資料的時間,這可避免頻繁地到遠地的伺服器抓取開放資料,系統會檢查使用者觸發時是否超過5分鐘,若是還未超過就使用預先存下來的資料。由於Application變數是所有連到這個網站的使用者共用的變數,所以修改時要用Lock與Unlock函數來預防同時修改可能造成的異常狀況(關於Application變數的說明與使用,可參考ASP.NET網頁程式設計[全華,張峻彬著],第七章有說明)。

LINQ的操作與SQL很像,我在這裡是自訂了一個欄位(distance)去計算各監測站與目前位置的平方差和距離,並利用這個欄位排序以抓取離用者較近的監測站

取得根據監測站距離的排序資料後,在這個應用中只使用離使用者最近的三個監測站資料,去計算PM2.5、溫度與濕度的範圍資訊,以及產生用來後續標於Google地圖上的相關資料

在這個部分我又做了一個很偷懶的事,就是在進行Google地圖多點標註時,原本應是要自己寫一些程式來進行,但我一打開Google Map API的說明,看到那麼多字我就放棄,立馬進行B方案,上網找了一個Google地圖多點標註的例子來做樣版,將其中需要塞入經緯度與相關資料的部份放入自訂的變數(@@AA@@,@@BB@@)

做法是這樣,將上面的內容,加上一些自動產生的資料變數重新動態產生一個javascript檔,以供Google Map產生多個標註點,程式都下,(關於伺服器端文字檔的存取的說明與使用,可參考ASP.NET網頁程式設計[全華,張峻彬著],第十章有說明)

完成了前面的步驟就可以產生所需的資訊,地圖中紅色的記號就是使用者的位置,黃色記號就是附近的三個監測站。畫面中的燈號是根據PM2.5,0-35顯示綠燈,36-53顯示黃燈,54-70顯示紅燈,70以上顯示紫燈。

不過,這可以很明顯位置是不對的(我人在辦公室),所以我拿了個平板來測試,位置是正確的

由於發現電腦的瀏覽器去所抓到的經緯度跟實際的經緯度有相當的距離差異,所以我又寫了一個功能,那就是讓使用者輸入地址或可辨識出地點的關鍵字,透過Google Map API反查出其經緯度

查出經緯度後,就可用前述相同的方式去進行後績的處理了

點標記點可看到相關的資訊

寫完了,我好棒棒!