使用 Google 地圖平台和 deck.gl 視覺化資料

1. 事前準備

本程式碼研究室會說明如何使用 Maps JavaScript API 和 deck.gl (開放原始碼的 WebGL 加速資料視覺化架構),建立大量地理空間資料的視覺化內容。

d01802e265548be1.png

必要條件

學習內容

  • 將 Google 地圖平台與 deck.gl 整合。
  • 從 BigQuery 將資料集匯入地圖。
  • 在地圖上定義資料點。

軟硬體需求

  • Google 帳戶
  • 您選擇的文字編輯器或 IDE
  • 具備 JavaScript、HTML 和 CSS 的基礎知識

2. 設定環境

開始使用 Google 地圖平台

如果您從未使用過 Google 地圖平台,請按照下列步驟操作:

  1. 建立帳單帳戶
  2. 建立專案
  3. 啟用 Google 地圖平台 API 和 SDK。
  4. 產生 API 金鑰。

下載 Node.js

如果沒有,請前往 https://nodejs.org/,在電腦上安裝 Node.js 執行階段。

Node.js 包含 npm,這是安裝本程式碼研究室依附元件時所需的套件管理工具。

設定範例專案

為節省時間,本程式碼研究室的範例專案包含例項地圖所需的所有樣板程式碼。

首先,請按照下列步驟操作:

  1. 複製或下載這個存放區
  2. 從指令列前往 /starter 目錄,其中包含完成本程式碼研究室所需的基本檔案結構。
  3. 執行下列指令,從 npm 安裝依附元件:
npm install
  1. 執行下列指令,透過 Webpack 開發伺服器在瀏覽器中執行入門專案:
npm start
    The starter app opens in your browser and displays a map.
  1. 在 IDE 中開啟專案,然後前往 /starter/src 目錄。
  2. 開啟 app.js 檔案。

您會在檔案的程式碼中,於這個部分進行所有編碼作業:

const googleMapsAPIKey = 'YOUR API KEY';
loadJSAPI();
function runApp() {
  // Your code goes here
}

您不會對檔案中的其餘程式碼執行任何操作,這些程式碼會載入 Maps JavaScript API 和地圖:

/* API and map loader helpers */
function loadJSAPI() {
  const googleMapsAPIURI = `https://maps.googleapis.com/maps/api/js?key=${googleMapsAPIKey}&callback=runApp`;
  const script = document.createElement('script');

  script.src = googleMapsAPIURI;
  script.defer = true;
  script.async = true;

  window.runApp = runApp;
  document.head.appendChild(script);
}

function initMap() {
  const mapOptions = {
    center: { lat: 40.75097, lng: -73.98765 },
    zoom: 14,
    styles: mapStyle
  };
  const mapDiv = document.getElementById('map');
  return new google.maps.Map(mapDiv, mapOptions);
}
  1. YOUR API KEY 替換為您在設定環境時產生的實際 API 金鑰:
const googleMapsAPIKey = 'YOUR API KEY';

3. 從 BigQuery 匯出資料

BigQuery 提供許多公開資料集,可用於資料分析或實驗。

按照下列步驟,使用 BigQuery 匯出公開資料集,其中包含紐約市 Citi Bike 的位置資料。Citi Bike 是共享單車計畫,共有 14,500 輛單車和 900 個地點:

  1. 前往 Cloud 控制台
  2. 依序點選「導覽選單」41e8e87b85b0f93.png >「BigQuery」
  3. 在查詢編輯器中輸入下列查詢,然後點按「執行」
SELECT
    longitude,
    latitude,
    name,
    capacity
FROM
    `bigquery-public-data.new_york_citibike.citibike_stations`
  1. 查詢完成後,按一下「儲存結果」,然後選取「JSON (本機檔案)」,即可匯出結果集。將檔案命名為 stations.json,並儲存至 /src 目錄。

2f4932829f7e1f78.png

取得資料後,您就可以使用 deck.gl 建立第一個視覺化項目。

4. 定義視覺化效果

deck.gl 是開放原始碼資料視覺化架構,使用 WebGL 產生極大型資料集的高解析度 2D 和 3D 算繪結果。可處理數十萬個資料點,經過最佳化後,甚至可處理數百萬個資料點。

如要建立視覺化效果,您需要兩個類別:GoogleMapsOverlay 和 deck.gl 的其中一個視覺化圖層。

首先,請建立 ScatterplotLayer 的例項,在地圖上將資料點算繪為圓圈:

  1. app.js 頂端新增下列內容,匯入 deck.gl 的 ScatterplotLayer 類別:
import { ScatterplotLayer } from '@deck.gl/layers';
  1. 從 deck.gl 散佈圖層提供的兩種屬性中選擇,設定圖層屬性

設定器屬性會提供視覺化效果所需的資訊,例如資料點的位置和半徑。樣式函數屬性可讓您自訂視覺化效果的樣式。

以下程式碼片段中使用的屬性說明如下:

  • id 可讓算繪器基於各種原因識別圖層,例如重新繪製及其他視覺化更新。所有 deck.gl 圖層都需要您指派的專屬 ID。
  • data 指定視覺化效果的資料來源。請將這個值設為 ‘./stations.json',使用從 BigQuery 匯出的資料集。
  • getPosition 會從資料來源擷取每個物件的位置。請注意,屬性的值是函式。deck.gl 會使用這個函式,逐一疊代資料集中的每一列。這個函式會告訴算繪器如何存取每個資料列中資料點的經緯度。在這個資料集中,每個資料列中的資料都是 JSON 物件,且位置是在緯度和經度屬性中設定,因此您提供給 getPosition 的函式是 d => [parseFloat(d.longitude), parseFloat(d.latitude)]
  • getRadius 會定義每個物件的半徑 (以公尺為單位)。在本例中,半徑設為 d => parseInt(d.capacity),這會根據每個電台的容量設定資料點的大小。
  • stroked 會設定所算繪資料點的外緣是否有筆觸。
  • getFillColor 會將每個資料點的填滿顏色設為 RGB 顏色代碼。
  • getLineColor 會將每個資料點的筆觸顏色設為 RGB 顏色代碼。
  • radiusMinPixels:為每個資料點設定最小像素寬度。使用者放大及縮小地圖時,deck.gl 會自動調整資料點的比例,確保地圖上的視覺化內容清楚可見。這項屬性可讓您控制縮放程度。
  • radiusMaxPixels:為每個資料點設定像素寬度上限。
const layerOptions = {
  id: 'scatter-plot',
  data: './stations.json',
  getPosition: d => [parseFloat(d.longitude), parseFloat(d.latitude)],
  getRadius: d => parseInt(d.capacity),
  stroked: true,
  getFillColor: [255, 133, 27],
  getLineColor: [255, 38, 27],    
  radiusMinPixels: 5,
  radiusMaxPixels: 50
};
  1. 建立 deck.gl 的 ScatterplotLayer 類別執行個體:
const scatterplotLayer = new ScatterplotLayer(layerOptions);

完成本節後,程式碼應如下所示:

import { ScatterplotLayer } from '@deck.gl/layers';

const googleMapsAPIKey = 'YOUR API KEY';

loadJSAPI();
function runApp() {
  const map = initMap();
  const layerOptions = {
    id: 'scatterplot',
    data: './stations.json',
    getPosition: d => [parseFloat(d.longitude), parseFloat(d.latitude)],
    getRadius: d => parseInt(d.capacity),
    stroked: true,
    getFillColor: [255, 133, 27],
    getLineColor: [255, 38, 27],    
    radiusMinPixels: 5,
    radiusMaxPixels: 50
  };

  const scatterplotLayer = new ScatterplotLayer(layerOptions);
}

5. 將視覺化效果套用至地圖

現在您可以使用 GoogleMapsOverlay 類別將 ScatterplotLayer 例項套用至地圖,該類別會使用 Maps JavaScript API OverlayView API,在地圖上注入 WebGL 環境。

完成上述步驟後,您可以將任何 deck.gl 的視覺化圖層傳遞至 GoogleMapsOverlay,系統會算繪圖層並與地圖同步。

如要將 ScatterplotLayer套用至地圖,請按照下列步驟操作:

  1. 匯入 deck.gl 的 GoogleMapsOverlay 類別:
import { GoogleMapsOverlay } from '@deck.gl/google-maps';
  1. 建立 GoogleMapsOverlay 類別的執行個體,並將您先前在物件的 layers 屬性中建立的 scatterplotLayer 執行個體傳遞給該執行個體:
const googleMapsOverlay = new GoogleMapsOverlay({
    layers: [scatterplotLayer]
  });
  1. 將疊加層套用至地圖:
 googleMapsOverlay.setMap(map);

完成本節後,程式碼應如下所示:

import { GoogleMapsOverlay } from '@deck.gl/google-maps';
import { ScatterplotLayer } from '@deck.gl/layers';

const googleMapsAPIKey = 'YOUR API KEY';

loadJSAPI();
function runApp() {
  const map = initMap();
  const layerOptions = {
    id: 'scatter-plot',
    data: './stations.json',
    getPosition: d => [parseFloat(d.longitude), parseFloat(d.latitude)],
    getRadius: d => parseInt(d.capacity),
    stroked: true,
    getFillColor: [255, 133, 27],
    getLineColor: [255, 38, 27],    
    radiusMinPixels: 5,
    radiusMaxPixels: 50
  };
  const scatterplotLayer = new ScatterplotLayer(layerOptions);
  const googleMapsOverlay = new GoogleMapsOverlay({
    layers: [scatterplotLayer]
  });
  googleMapsOverlay.setMap(map);
}

返回瀏覽器,您應該會看到紐約市所有 Citi Bike 車站的精彩資料視覺化效果。

d01802e265548be1.png

6. 恭喜

恭喜!您使用 Google 地圖平台和 deck.gl,製作了紐約市 Citi Bike 資料的大量資料視覺化。

瞭解詳情

透過 Maps JavaScript API,您可以存取 Google 地圖平台為網路提供的所有功能。如要進一步瞭解如何在網路上使用 Google 地圖平台,請參閱下列連結:

deck.gl 提供多種資料視覺化圖層,可供您向使用者顯示資料。如要進一步瞭解如何搭配使用 deck.gl 和 Maps JavaScript API,請參閱下列連結: