Google Maps API 學習筆記 – 3:用熱圖 / Heat map 製作全台 12 小時雨量分佈圖

Google Map API學習筆記-3:用熱圖(Heat map)製作全台12小時雨量分佈圖
Google Map API學習筆記-3:用熱圖(Heat map)製作全台12小時雨量分佈圖

一、Google 處理掉很多事了

原本以為畫熱圖(Heat map)很難,後來看了 Google Maps API 的文件,Google 已經處理掉大部份的工作了,我們只要丟座標,加上每個座標的權重,剩下的事情 Google 都會幫你搞定。

如果會了系列第一篇的 放多個標記,跟第二篇的 畫圓形,其實 Heat Map 也就會了。

Heat Map 是把數據視覺化在地圖上的一種,這種數據視覺化的地圖,照文件上給的範例有二:

1 圓圈圖(Circle Map):用不同大小的圓圈當代表,像文件上示範的是地震狀況圖,每個圓圈大小就代表著不同的地震級數。Google Map Demo

2 熱圖(Heat Map):就是本篇要實作的,會配合地理因素跟權重大小,生成出很像是熱感應圖的東西。Google Map Demo

Circle Map 比較簡單,就是在放多個標記時,icon 用客製,都用成畫圓圈的 function 就行。

這篇來拿第二個 Heat Map 來實作,畫一個台灣 12 小時累積雨量的分佈圖。


二、取得氣象局雨量資料

在「接氣象局 API、跨網域 AJAX 資料」這篇中有寫怎麼拿氣象局 API 的授權碼,以及拿到 API 的 URL。

這邊寫另一個取得 URL 的方式。主要是最近氣象局一直在推他們的新版官網,搜尋「氣象局 api」,第一名的結果就是:氣象資料開放平台

找觀測雨量的資料,就會找到這頁:自動雨量站-雨量觀測資料

登入會員後,如果有取得授權碼,在「JSON」的連結,就可以當 AJAX 的 URL。不過加了想要限定回傳資料的參數,好像跟原有的 opendata API 不太一樣,至少只想回傳 12 小時內的就沒用。

附上 GET 回來後,每個主欄位的中文說明:

https://drive.google.com/viewerng/viewer?url=https://opendata.cwb.gov.tw/opendatadoc/DIV2/A0002-001.pdf

要注意的是,雖然文件中說雨量值是 -998.00 時,代表連著 6 小時內的值都是 0,但實作時遇到的情況是,除了會出現 -998.00,也會遇到 -999.00。為了避免權重上的影響,這 2 個值出現時都要換成 0。

以下是 AJAX 回來後的資料 Demo:

氣象局回傳的雨量資料
氣象局回傳的雨量資料

各觀測站的資料都在 cwbopendata.location 裡,總共有 798 個觀測站,再打開來會看到每個站的資料:

觀測站的資料
觀測站的資料

lat 是緯度、lon 是經度,合起來就是座標。

elemenetName 代表的意思,前面附上的 PDF 就有說明了。這邊用的是 12 小時累積雨量,所以是抓陣列裡的第 5 個。


三、資料整理成 Heat Map 要的

Heat Map 預設是只要一個資料就行,就是座標。

但只有座標,看不出影響的程度,再加上權重(Weight)會更清楚。

這邊拿雨量當作權重,整理的資料是這樣:

let rainData = {
  location: new google.maps.LatLng(經度, 緯度),
  weight: 雨量
};

forEach 把每個觀測站的雨量資料處理成上面的物件,再 push 進一個陣列裡,接著就可以拿這個資料陣列去畫Heat Map。


四、畫熱圖 Heat Map

畫 Heat Map 的 code 如下:

let heatmap = new google.maps.visualization.HeatmapLayer({
  data: heatmapData,
  dissipating: false,
  radius: 20, // 半徑
  gradient: [], // 顏色
  map: map
});

dissipating

dissipating 這個比較特別,是指地圖放大縮小時,熱點圖是否要跟著加強。false 就是會,true 就是不會。

之所以會說特別,是因為不知道是不是共有 798 個點,當設成 false 讓每個點跟著強加的結果,就會讓整個台灣像被 AT 力場包起來一樣,像這樣:

dissipating設成false
dissipating 設成 false

改成 true 以後才正常。

有可能是對這個參數的理解錯了,也有可能是其他原因,如果有知道的高手請不吝賜教。

gradient

這個也是很容易踩雷的參數。

他的值是一個陣列,原本以為是給一個色碼,程式就會自動用權重去加上深淺的分別,結果完全不是這麼一回事。

之所以用陣列,就是要填入很多不同的色碼,假設權重是 1–10,又希望這 10 個權重反應出的顏色都不一樣,就要照著 1–10 的順序填入不同的色碼。像這樣:

[
  '#000', // 給權重0的色碼
  '#111', // 給權重1的色碼
  '#222', // 給權重2的色碼
  '#333', // 給權重3的色碼
  ...
]

色碼,可以寫 white、black 等顏色名字,也可以寫 Hex 的六碼,或是寫 rgba。

可以寫 rgba 很重要,因為實作發現,第一個值會給權重 0,就是熱圖上其他沒有值的狀況,如果第一個值寫了紅色,那整張表都會加上一層紅色。

因此陣列第一個值給權重 0 的色碼,建議是填 rgba(255, 255, 255, 0),讓透明度為 0,才不會整張地圖都染上顏色。

這邊因為是要顯示雨量分佈,就直接用 Material Design 的色表

method 執行完後,雨量分佈的 Heat map 就完成了:

雨量分佈的Heat map
雨量分佈的 Heat map

五、原始碼

本篇的原始碼整理如下,替換氣象局跟 Google Maps API 的 key 就行了。


Google Maps API 學習筆記系列

  1. 地圖、標記、客製樣式
  2. 在地圖上畫個日本結界
  3. 用熱圖(Heat Map)製作全台 12 小時雨量分佈圖
  4. Place API 自動完成地址、地點評論摘要
  5. 抓目前位置、計算到各點距離
  6. 畫新冠肺炎分佈圖
Summary
Google Maps API 學習筆記 - 3:用熱圖(Heat map)製作全台12小時雨量分佈圖
Article Name
Google Maps API 學習筆記 - 3:用熱圖(Heat map)製作全台12小時雨量分佈圖
Description
本篇大綱:Google處理掉很多事了、取得氣象局雨量資料、資料整理成Heat Map要的、畫熱圖Heat Map、原始碼。原本以為畫熱圖(Heat map)很難,後來看了Google Maps API的文件,Google已經處理掉大部份的工作了。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg
訂閱
通知
guest

2 Comments
最舊
最新
Inline Feedbacks
看所有留言
Joshua
Joshua
4 年 之前

lat是緯度, long是經度哦, 你寫反了~
不過你的分享很棒! 獲益良多, 謝謝哦~

Last edited 4 年 之前 by Joshua