上一篇談到folium目前無法在建立geoJson時,同時包含popup,所以目前想到的方式是利用pandas讀取json資料,再以polygon讀取座標,並同時設定popup。
卡在上一篇的問題在於,polygon讀取的座標順序是[y, x]
,但是在geoJson裡面卻是以[x, y]
,所以要讓polygon能順利建立,需要再多做一步來轉換:
newList = []
def switchLatLng(geos):
for geo in geos:
if isinstance(geo[0],list):
switchLatLng(geo)
else:
newList.append([geo[1], geo[0]])
return newList
這邊利用迭代方式,讓程式判斷資料在剩下單一點位座標時,替換x, y座標。測試有成功將座標轉換,現在正拿去跑folium中,已經過了半小時依舊沒有動靜。可能是因為有891個里的關係?由於folium及leaflet製作html的資料,裡面包含所有資訊(例如座標點),所以如果要畫像是里界分佈的地圖,在那張地圖的html檔案裡面,就會有高雄市891個里的所有座標點資料。所以電腦很容易就當機,像是第27天時產出的區界地圖就有700多萬個字元,可想而知里界的話會有多可怕。
一個半小時後......
最後發現是我在裡面建立了newList,但是都沒有清空,所以累積了891個里的座標點,跑到電腦記憶體都爆了當然跑出來也不會是我們要的結果。最後改完成功的程式碼,用python跑也不用1分鐘......。
myMap = folium.Map([22.73444963475145, 120.28458595275877], zoom_start=6)
kaoVill = folium.FeatureGroup()
features = pd.read_json('../../dist/mapdata/KaoVillageRange.json')["features"]
for feature in features:
villpopup = '這裡是<h3>'+feature['properties']['TV_ALL']+'</h3>總面積為'+feature['properties']['AREA']+'平方公尺'
coors = [switchLatLng(feature['geometry']['coordinates'])]
newList = []
villRange = folium.Polygon(coors,
popup = villpopup,
fill = True).add_to(kaoVill)
kaoVill.add_to(myMap)
myMap.fit_bounds(kaoVill.get_bounds())
myMap.save('Folium_KaoVillpopup.html')
這裡我建立一個FeatureGroup,讓地圖能夠fitBounds,並在建立之後把newList清空,避免建立新的里界時也把之前的一起抓進來。
看一下成果吧!再開地圖的時候有一點頓頓的,不知道是因為電腦爛的關係還是檔案太大。
大功告成!!!
終於~~