# 2019_11_2_天氣資料結合地圖套件 ## 氣象資料 ###### tags: `讀書會` `python` `folium套件` ### Dataset 資料來源:https://data.gov.tw/dataset/9176 名稱:自動氣象站-氣象觀測資料 資料網址:https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0001-001?Authorization=rdec-key-123-45678-011121314 大家可以先簡單看一下這個資料集的樣子,這個是一個及時的API回傳。也就是觀測站的數據,會固定時間回傳,並且更新在這個網址上。 而我們今天要做的,就是及時的取用這個資料,並且將這個資料做一些計算,並且視覺化。 ### Data的樣子 這個Data是一個[JSON](https://zh.wikipedia.org/wiki/JSON)格式,也就是JavaScript Object Notation。這種格式適合用在網頁的傳輸上,也就是適合前端運用javascript去解析。 他的長相,很像是洋蔥,也就是一層一層的。以Python來說,可以想像是list以及dictionary的混合使用。 <pre> import requests import json import folium #畫地圖套件 url = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0001-001?Authorization=rdec-key-123-45678-011121314" req = requests.get(url) #method:get 去到頁面 json_content = req.content.decode('utf-8') jason_dict = json.loads(json_content) #轉成字典了 補充兩者差異:load 開檔案 loads 純文字 m = folium.Map((23.770876, 120.934757), zoom_start= 8 ) for location in jason_dict['records']['location']: folium.Marker( location=[location['lat'], location['lon']], popup=location['locationName'] + ' :' + location['weatherElement'][3]['elementValue'], icon=folium.Icon(color='blue') ).add_to(m) m.save('test.html') </pre> ### 延伸練習題目#*1* #### 超過平均給紅色icon低於平均給藍色icon 計算平均數 <pre> #算平均數 temp = [] for x in jason_dict['records']['location']: temp.append(float(x['weatherElement'][3]['elementValue'])) avtemp = float(sum(temp))/len(temp) </pre> 加入if的判斷式 <pre> for location in jason_dict['records']['location']: if float(location['weatherElement'][3]['elementValue']) >= avtemp: folium.Marker( location=[location['lat'], location['lon']], popup=location['locationName'] + ' 氣溫:' + location['weatherElement'][3]['elementValue'], icon=folium.Icon(color='red') ).add_to(m) else: folium.Marker( location=[location['lat'], location['lon']], popup=location['locationName'] + ' :' + location['weatherElement'][3]['elementValue'], icon=folium.Icon(color='blue') ).add_to(m) </pre> ### if 的寫法太過冗長~在python中有精簡的寫法 將if直接寫在變數後面 <pre> location['weatherElement'][3]['elementValue'], icon=folium.Icon(color='red' if float(location['weatherElement'][3]['elementValue']) >= avtemp else 'blue') ).add_to(m) </pre> ### 可以修改地圖樣式 可以在建立地圖地方修改地圖樣式 地圖樣式查詢網址: https://python-graph-gallery.com/288-map-background-with-folium/ <pre> m = folium.Map((23.770876, 120.934757), tiles='Stamen Terrain', zoom_start= 8 ) </pre> ### 修改icon樣式 icon查詢網址:https://fontawesome.com/icons?d=gallery <pre> Icon(color='blue', icon_color='white', icon='info-sign', angle=0, prefix='glyphicon', **kwargs) </pre> ### 顏色限制問題 由於icon本身顏色只能設定為下列: 'red', 'blue', 'green', 'purple', 'orange', 'darkred','lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue','darkpurple', 'white', 'pink', 'lightblue', 'lightgreen','gray', 'black', 'lightgray' icon內部顏色可以以色碼表示 所以改由icon內部顏色表示為溫度 #### 所需套件 導入套件將RGB色碼轉成HEX表示 <pre> from colormap import rgb2hex </pre> 自刻氣溫轉RGB色碼的套件 <pre> def temp2rgb(c): rgbt = (c + 0)/30*765 #括號內要依據最低溫修改,外側為最大溫差 #計算R r = rgbt - 255 if r <= 0: r = 0 elif r >= 255: r = 255 #計算G g = 765 - rgbt if g >= 255: g = 255 elif g <= 0: g = 0 #計算B b = 255 - rgbt if b <= 0: b = 0 elif b >= 255: b = 255 return r, g, b </pre> ### 成品敘述 讀取台灣氣象資料,並標示於地圖上,地圖以地形表示 icon中箭頭方向表示風向,顏色表示為氣溫 #### 用途:觀測地形對於風向以及氣溫的影響 ### 程式碼: <pre>import requests import json import folium #畫地圖套件 from colormap import rgb2hex def temp2rgb(c): rgbt = (c + 0)/30*765 #括號內要依據最低溫修改,外側為最大溫差 #計算R r = rgbt - 255 if r <= 0: r = 0 elif r >= 255: r = 255 #計算G g = 765 - rgbt if g >= 255: g = 255 elif g <= 0: g = 0 #計算B b = 255 - rgbt if b <= 0: b = 0 elif b >= 255: b = 255 return r, g, b url = "https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0001-001?Authorization=rdec-key-123-45678-011121314" req = requests.get(url) #method:get 去到頁面 json_content = req.content.decode('utf-8') jason_dict = json.loads(json_content) #轉成字典了 補充兩者差異:load 開檔案 loads 純文字 m = folium.Map((23.770876, 120.934757), tiles='Stamen Terrain', zoom_start= 8 ) #算平均數 temp = [] for x in jason_dict['records']['location']: temp.append(float(x['weatherElement'][3]['elementValue'])) avtemp = sum(temp)/len(temp) for location in jason_dict['records']['location']: rgb=temp2rgb(float(location['weatherElement'][3]['elementValue'])) folium.Marker( location=[location['lat'], location['lon']], popup=folium.Popup(location['locationName'] + ' 時間:' + location['time']['obsTime'] + ' 氣溫:' + location['weatherElement'][3]['elementValue'], max_width=300,min_width=150), icon=folium.Icon(color='darkred', icon='arrow-down', angle=int(location['weatherElement'][1]['elementValue']), icon_color=rgb2hex(int(rgb[0]), int(rgb[1]),int(rgb[2]))) ).add_to(m) m.save('test.html')</pre>