上一篇和你們分享了《可視化之Berkeley Earth》,此次看一看下面這個網站---aqicn.org。先作一個提示:文末有驚喜~ 算法
該網站在中國有必定的權威性,PM2.5數據有一點敏感,它竟能提供全球級別,實時的,詳盡的AQI數據,以及每一個站點的經緯度(精度在十米內),它的口號「provide information as clean as the air one wish to have」——提供的每一份數據,如同每一個人所指望的空氣那樣乾淨。 json
但該網站又有一點神祕感,沒有過多的自我介紹,服務器IP來自美國,團隊成員主要在北京,可以獲取全球這麼詳細的數據,總感受背後有不少不能說的祕密,網上只找到一篇《MY FAVORITE POLLUTION WEBSITE: AQICN.ORG》,感興趣的能夠讀一下。 canvas
去年末抓取它的PM25實時數據,但以爲這是老外的良心網站,若是把URL和網站名稱曝光,有被牆的隱患,因此沒有透露。最近發現它居然推出了json api的服務,生意越作越大,那今天老夫就「好事作到底」,揭底該網站四個未公開的,倒是最重量級的服務。 api
這是bounds查詢的url:服務器
https://api.waqi.info/mapq/bounds/?bounds={RECTANGLE}&inc=placeholders&k={KEY}&_={DATE}dom
官網API裏僅開發了經緯度的點查詢,但它本身使用是bounds面查詢,另外一個比較坑的是DATE參數,我本身驗證是無效的,因此該API沒法作到對歷史數據的查詢,固然,這也能夠理解,畢竟每一個站點數據更新時間不一,好比中亞可能好幾個月才更新一次。由於以前的PM文章詳細介紹過這部分,再也不重複。 ide
如上是城市的天氣預報服務,對應的數據url以下:函數
其中@參數是City編碼,好比北京對應的id是1451。返回JSON對象以下: this
不難理解,簡單說一下框選的內容,city是該城市的內容,nearest是該城市範圍內的氣象站點,都有geo屬性,提供對應的經緯度,偏差在百米內。Iaqi留到下面說,先說相對簡單的—forecast屬性。顧名思義,也就是氣象預報的內容,包括aqi和wind兩部分。
先看上圖對應表格中的AQI數值,每一項對應該時間點AQI的最大最小值。再看下圖wind屬性:
這個就不那麼直觀了,你們能看出對應關係嗎?我看了一個多小時,沒看出來,只好調試源碼:三小時(採用UTC時間)爲一時間段,對應三組數據,如上圖,c是氣溫,獲取氣溫的最大值和最小值,w[0],w[1]對應當前時段風速的最小最大值,w[2]是以正南爲起始點,順時針方向的旋轉角度,表示風向,藍色是風速的柱狀圖效果。這樣看上去就很明白了吧。過後讓同事看對應關係,他居然很快就「蒙「對了。
實時天氣數據和forecast都在一個json對象中,對應iaqi屬性,以下圖所示,正好有11項,分別對應PM25,PM10等十一個指標。
對應的PM25屬性以下:
p標誌該指標名稱爲pm2.5,v中保存的是最近48小時內的極值和當前值,i是該數據的提供方。iaqi[0].h[2]下面的一堆亂碼是什麼,猜想應該是每一個小時的PM25數值,用於顯示左側柱狀圖,可肉眼看不出其中的數值映射關係,這時候就須要用心眼了---調試,原來Decode代碼以下:
我很好奇這段代碼的出處,由於以前看高德地圖中矢量瓦片中也採用了相似的解密方式,有了解的請告訴我,再次感謝。最終該函數將亂碼decode爲48個PM值。
當你在網頁上看到該動態圖時,假設你要實現這個效果,所須要的數據格式,用Canvas 2D仍是WebGL,以及流暢度和交互式操做?
首先,每個城市有本身的配置文件,應該是JSP動態網頁來獲取的,好比New York的配置信息以下:
如上請求的是pm25數據,model是ncep-aqm。根據這些參數,咱們可以獲取以下的url
https://forecast.waqi.info/forecast/aqi/ncep-aqm/best/pm25/conf.json
其對應的json信息以下:
如上也比較容易理解,其中size指該區域的像素寬高,bounds爲經緯度範圍,其中在usepa字段下有8.png(圖片)和jsmap(二進制)這兩種形式,能夠簡單的認爲是PM25的範圍分段。二者思路相同,網站使用的是jsmap這種形式。
如上,從lut可知pm25值分爲17份,範圍是0~500。將lut的17個區間歸類到domain中,domain[i]對應range[i]份。不管是jsmap仍是png,規範都一致(png更精細一些)。不一樣的是files,png對應的是圖片的相對路徑,效果以下。而jsmap是二進制流形式
代碼中會給出一個色帶"#ffffff", "#5ec569", "#b2d744","#f2c500", "#fe8d00", "#fa0067"],等分爲17份,造成漸變色,而後根據jsmap對應的lut構造出一個level-color的分段映射表。保存在this.stream.colors.lut屬性中。
建立好了顏色表,接着就會請求對應時段的數據,url以下:
https://forecast.waqi.info/forecast/aqi/ncep-aqm/best/pm25/jsmap/stream.jsmap
對該數據進行解碼後參與canvas的渲染,解碼的算法和上面的decode類似,最終會解析爲一個點串points,裏面有v,x,y,n四個份量,分別是pm25值對應顏色表中的value值,xy是對應該區域的像素偏移量,n標識該值連續的次數。這樣,創建了最終的value-level-color的完整映射關係,經過canvas 2d完整動態渲染的整個過程。
在技術角度,把AQICN分解的差很少了,不知道你們有什麼收穫,由於篇幅太長,因此本篇就到此結束吧。若是有不對的地方或疑問,不妨留言交流。
下一篇會介紹earth.nullschool這個可視化效果很棒的網站,而後會再來一篇我的對這三個網站的對比和分析,把一些我的的想法拿出來和你們分享。
今天就寫到這,在公衆號中回覆「AQICN」,不區分大小寫,能夠獲取本文的Demo。