資料導向的即時樣式設定

本文說明為何要使用 Maps JavaScript API 實作 Google 邊界的動態資料導向樣式,以及如何實作,這項功能適用於各產業和區隔的多種用途。

紐約市計程車數量 (依郵遞區號劃分)
紐約市計程車數量動畫 (依郵遞區號邊界劃分,模擬縮時攝影):
紐約市計程車數量 (依郵遞區號劃分,縮時) 地圖圖例

資料導向樣式是 Google Maps Platform 的一項功能,可讓您使用 Google 的行政界線多邊形、為這些多邊形套用樣式並顯示在地圖上,以及結合自己的資料,建立內容豐富的自訂地圖,用於視覺分析及進一步瞭解資料。本文將探討一些用途,說明為何要整合動態資料動態饋給,以及如何運用資料導向樣式,在地圖上近乎即時地以視覺化方式呈現資料。

您可以透過資料導向樣式,建立顯示資料地理分布的地圖、動態自訂多邊形樣式,以及透過點擊事件與資料互動。這些功能可用於建立資訊豐富且引人入勝的地圖,適用於各種用途和產業。

以下列舉幾個用途,說明如何在地圖上顯示資料導向樣式的動態資料更新:

  • 共乘:即時更新可用於找出高需求區域,部分供應商可能會在這些區域提高價格。
  • 交通運輸:即時更新資訊可用於找出壅塞區域,協助判斷最佳替代路線。
  • 選舉:在大選之夜,即時民調資料可用於呈現即時結果。
  • 工作人員安全:即時更新可用於追蹤事件的即時發展、找出高風險區域,並為現場應變人員提供情境感知。
  • 天氣:即時更新資訊可用於追蹤暴風雨的移動、識別目前的危害,以及提供警告和警報。
  • 環境:即時更新可用於追蹤火山灰和其他污染物的移動、找出環境退化的區域,以及監控人類活動的影響。

在上述所有情況下,客戶可以結合即時資料動態饋給和 Google 的邊界,在地圖上快速輕鬆地以視覺化方式呈現資料,進而發揮更多價值,並近乎即時地取得深入分析資訊,做出更明智的決策。

解決方案的架構方法

現在,我們來逐步說明如何使用資料導向樣式建立地圖,以視覺化方式呈現動態資料。如前所述,這個用途是依郵遞區號以圖表呈現紐約市計程車數量。這有助於使用者瞭解叫計程車的難易度。

架構
以下是這個方法的應用程式架構圖:
應用程式架構

動態資料導向樣式解決方案

接下來,我們將逐步說明如何為資料集導入動態資料導向樣式 choropleth 地圖。

這項解決方案可讓您以郵遞區號為依據,將紐約市周邊即時計程車密度的假設資料集視覺化。雖然這可能不是真實世界的資料,但有實際應用價值,可讓您瞭解資料導向樣式在地圖上呈現動態資料的強大功能。

步驟 1:選擇要以圖表呈現的資料,並彙整至邊界地點 ID

首先,請找出要顯示的資料,並確認資料能與 Google 的邊界對應。您可以在用戶端執行這項比對,方法是針對每個 postalCode 呼叫 findPlaceFromQuery 回呼方法。請注意,美國的郵遞區號有專屬名稱,但其他行政區層級則沒有。如果查詢結果可能不夠明確,請務必選取正確的地點 ID。


const request = {
    query: postalCode,
    fields: ['place_id'],
};
 
function findPlaceId() {
   placesService.findPlaceFromQuery(request, function (results, status) {
      if (status === google.maps.places.PlacesServiceStatus.OK) {
         console.log(results[0]);
      }
   });
}

如果資料含有經緯度值,您也可以使用 Geocoding API 搭配元件篩選功能,將這些經緯度值解析為所需地圖項目圖層的地點 ID 值。在本例中,您將設定 POSTAL_CODE 地圖項目圖層的樣式。

步驟 2:連結至即時資料

連結資料來源的方法有很多種,最佳實作方式取決於您的具體需求和技術基礎架構。在本例中,假設資料位於 BigQuery 資料表,其中包含「zip_code」和「taxi_count」兩個資料欄,您將透過 Firebase Cloud 函式查詢資料。

async function queryNycTaxis() {
   // Queries the NYC Taxis dataset.

   // Create a client
   const bigqueryClient = new BigQuery();
  
   // The SQL query to run
   const sqlQuery = 'SELECT zip_code, taxi_count
      FROM \'YOUR_DATASET_ID.TABLE\' LIMIT 100';
      
   const options = {
      query: sqlQuery,
      // Location must match that of the dataset(s)
      // referenced in the query.
      location: 'US',
   };
  
   // Run the query
   const [rows] = await bigqueryClient.query(options);
  
   rows.forEach(row => {
      const postalCode = row['zip_code'];
      const taxiCount = row['taxi_count'];
   });
}

接下來,請務必確保資料保持最新狀態。其中一種做法是使用 Web Worker 呼叫上述查詢,並設定計時器,使用 setInterval 函式重新整理資料。您可以將間隔設為適當的值,例如每 15 秒重新整理一次地圖。每過一段時間,Web Worker 就會要求更新每個 postalCode 的 taxiCount 值。

現在可以查詢及重新整理資料,接著要確保地圖多邊形的外觀反映這些變更。

步驟 3:使用資料導向樣式設定地圖樣式

您已取得動態資料值,可建立視覺樣式並套用至 Maps JavaScript 執行個體中的郵遞區號界線 (以 JSON 物件表示),現在可以將其樣式設為 choropleth 地圖。

在這個範例中,您將根據每個郵遞區號的計程車數量設定地圖樣式,讓使用者瞭解所在區域的計程車密度和可用性。樣式會因計程車數量值而異。計程車最少的區域會套用紫色樣式,顏色漸層會依序變成紅色、橘色,最後在密度最高的區域變成紐約市計程車黃色。在這個色彩配置中,您會將這些顏色值套用至 fillColor 和 strokeColor。將 fillOpacity 設為 0.5,使用者就能看到底層地圖;將 strokeOpacity 設為 1.0,使用者就能區分顏色相同的多邊形邊界:


const featureLayer = map.getFeatureLayer(
   google.maps.FeatureType.POSTAL_CODE
);
featureLayer.style = (featureStyleFunctionOptions) => {
   const placeFeature = featureStyleFunctionOptions.feature;
   // taxiCount per (postal_code) PlaceID 
   const taxiCount = zips[placeFeature.placeId];
   let fillColor;
   let strokeColor;
// Apply colors to features based on taxiCount values
if (taxiCount < 8) {
   fillColor = "#571845";  
   strokeColor = "#571845"; 
} else if (taxiCount < 13) {
   fillColor = "#900c3e";
   strokeColor = "#900c3e";
} else if (taxiCount < 21) {
   fillColor = "#c60039"; 
   strokeColor = "#c60039"; 
} else if (taxiCount < 34) {
   fillColor = "#fe5733";
   strokeColor = "#fe5733";
// keep else if or the whole map gets this style with else
} else if (taxiCount >= 34) { 
   fillColor = "#fec30f";
   strokeColor = "#fec30f";
}  
return {
   fillColor,
   strokeColor,
   fillOpacity: 0.5,
   strokeOpacity: 1.0,
};
 

結論

Google 界線資料導向樣式功能可讓您使用資料設定地圖樣式,適用於各行各業和不同區隔的多種用途。連結即時資料後,您就能在事件發生當下,傳達什麼事件在哪裡發生。這項功能可望發揮即時資料的價值,協助使用者在現實世界中更瞭解即時資料。

後續行動

貢獻者

主要作者:

Jim Leflar | Google Maps Platform 解決方案工程師