Trực quan hoá dữ liệu bằng Nền tảng Google Maps và deck.gl

1. Trước khi bắt đầu

Lớp học lập trình này hướng dẫn bạn cách tạo một hình ảnh trực quan về dữ liệu không gian địa lý có dung lượng lớn bằng Maps JavaScript API và deck.gl, một khung trực quan hoá dữ liệu mã nguồn mở, được tăng tốc bằng WebGL.

d01802e265548be1.png

Điều kiện tiên quyết

Bạn sẽ thực hiện

  • Tích hợp Nền tảng Google Maps với deck.gl.
  • Nhập một tập dữ liệu vào bản đồ từ BigQuery.
  • Xác định các điểm dữ liệu trên bản đồ.

Bạn cần có

  • Tài khoản Google
  • Trình chỉnh sửa văn bản hoặc IDE mà bạn chọn
  • Kiến thức cơ bản về JavaScript, HTML và CSS

2. Thiết lập môi trường

Bắt đầu sử dụng Nền tảng Google Maps

Nếu bạn chưa từng sử dụng Nền tảng Google Maps, hãy làm theo các bước sau:

  1. Tạo tài khoản thanh toán.
  2. Tạo một dự án.
  3. Bật API và SDK của Nền tảng Google Maps.
  4. Tạo một khoá API.

Tải Node.js xuống

Nếu bạn chưa có, hãy truy cập vào https://nodejs.org/, rồi tải và cài đặt thời gian chạy Node.js trên máy tính.

Node.js bao gồm npm, một trình quản lý gói mà bạn cần cài đặt các phần phụ thuộc cho lớp học lập trình này.

Thiết lập dự án khởi đầu

Để tiết kiệm thời gian, dự án khởi đầu cho lớp học lập trình này bao gồm tất cả mã khởi tạo mà bạn cần để tạo một bản đồ.

Để bắt đầu, hãy làm theo các bước sau:

  1. Sao chép hoặc tải kho lưu trữ này xuống.
  2. Từ dòng lệnh, hãy chuyển đến thư mục /starter. Thư mục này chứa cấu trúc tệp cơ bản mà bạn cần để hoàn tất lớp học lập trình này.
  3. Cài đặt các phần phụ thuộc từ npm bằng cách chạy lệnh sau:
npm install
  1. Chạy dự án khởi đầu trong trình duyệt bằng Webpack Dev Server bằng cách chạy lệnh sau:
npm start
    The starter app opens in your browser and displays a map.
  1. Mở dự án trong IDE và chuyển đến thư mục /starter/src.
  2. Mở tệp app.js.

Bạn sẽ viết tất cả mã trong phần mã này của tệp:

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

Bạn sẽ không làm gì với phần còn lại của mã trong tệp này. Phần mã này tải Maps JavaScript API và bản đồ:

/* 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. Thay thế YOUR API KEY bằng khoá API thực tế mà bạn đã tạo khi thiết lập môi trường:
const googleMapsAPIKey = 'YOUR API KEY';

3. Xuất dữ liệu từ BigQuery

BigQuery cung cấp nhiều tập dữ liệu công khai mà bạn có thể sử dụng cho mục đích phân tích dữ liệu hoặc thử nghiệm.

Sử dụng BigQuery để xuất một tập dữ liệu công khai bao gồm dữ liệu vị trí của Citi Bike ở Thành phố New York (một chương trình chia sẻ xe đạp với 14.500 xe đạp và 900 địa điểm) bằng cách làm theo các bước sau:

  1. Chuyển đến Cloud Console.
  2. Nhấp vào Trình đơn điều hướng 41e8e87b85b0f93.png > BigQuery.
  3. Trong Trình chỉnh sửa truy vấn, hãy nhập truy vấn sau rồi nhấp vào Chạy:
SELECT
    longitude,
    latitude,
    name,
    capacity
FROM
    `bigquery-public-data.new_york_citibike.citibike_stations`
  1. Sau khi truy vấn hoàn tất, hãy nhấp vào Lưu kết quả, rồi chọn JSON (tệp cục bộ) để xuất tập kết quả. Đặt tên tệp là stations.json rồi lưu vào thư mục /src.

2f4932829f7e1f78.png

Sau khi thu thập dữ liệu, bạn có thể tạo hình ảnh trực quan đầu tiên bằng deck.gl.

4. Xác định hình ảnh trực quan

deck.gl là một khung trực quan hoá dữ liệu nguồn mở sử dụng WebGL để tạo ra các bản kết xuất 2D và 3D có độ phân giải cao cho các tập dữ liệu cực lớn. Công cụ này có thể xử lý hàng trăm nghìn điểm dữ liệu và khi được tối ưu hoá, công cụ này thậm chí có thể xử lý hàng triệu điểm dữ liệu.

Để tạo một bản trực quan hoá, bạn cần có 2 lớp – GoogleMapsOverlay và một trong nhiều lớp trực quan hoá của deck.gl.

Để bắt đầu, hãy tạo một phiên bản ScatterplotLayer. Phiên bản này sẽ hiển thị các điểm dữ liệu dưới dạng hình tròn trên bản đồ:

  1. Nhập lớp ScatterplotLayer của deck.gl bằng cách thêm nội dung sau vào đầu app.js:
import { ScatterplotLayer } from '@deck.gl/layers';
  1. Đặt thuộc tính lớp bằng cách chọn trong số 2 loại thuộc tính có sẵn cho lớp biểu đồ phân tán của deck.gl.

Các thuộc tính của setter cung cấp cho hình ảnh trực quan thông tin cần thiết để hiển thị, chẳng hạn như vị trí và bán kính của các điểm dữ liệu. Các thuộc tính của trình tạo kiểu cho phép bạn tuỳ chỉnh kiểu của hình ảnh trực quan.

Sau đây là thông tin chi tiết về các thuộc tính mà bạn sử dụng trong đoạn mã sau:

  • id cho phép trình kết xuất xác định các lớp vì nhiều lý do, chẳng hạn như vẽ lại và các bản cập nhật khác cho hình ảnh trực quan. Tất cả các lớp deck.gl đều yêu cầu một mã nhận dạng duy nhất do bạn chỉ định.
  • data chỉ định nguồn dữ liệu của hình ảnh trực quan. Đặt thành ‘./stations.json' để sử dụng tập dữ liệu mà bạn đã xuất từ BigQuery.
  • getPosition truy xuất vị trí của từng đối tượng từ nguồn dữ liệu. Lưu ý rằng giá trị của thuộc tính là một hàm. deck.gl sử dụng hàm này để lặp lại mọi hàng trong tập dữ liệu. Hàm này cho trình kết xuất biết cách truy cập vào vĩ độ và kinh độ của điểm dữ liệu trong mỗi hàng. Trong tập dữ liệu này, dữ liệu trong mỗi hàng là một đối tượng JSON có vị trí được đặt trong các thuộc tính vĩ độ và kinh độ, vì vậy, hàm mà bạn cung cấp cho getPositiond => [parseFloat(d.longitude), parseFloat(d.latitude)].
  • getRadius xác định bán kính của từng đối tượng theo mét. Trong trường hợp này, bán kính được đặt thành d => parseInt(d.capacity), tức là đặt kích thước của các điểm dữ liệu dựa trên sức chứa của từng trạm.
  • stroked đặt xem các điểm dữ liệu được kết xuất có nét vẽ trên các cạnh ngoài hay không.
  • getFillColor đặt màu nền của mỗi điểm dữ liệu dưới dạng mã màu RGB.
  • getLineColor đặt màu nét vẽ của từng điểm dữ liệu dưới dạng mã màu RGB.
  • radiusMinPixels đặt chiều rộng tối thiểu tính bằng pixel cho mỗi điểm dữ liệu. Khi người dùng phóng to và thu nhỏ, deck.gl sẽ tự động điều chỉnh kích thước của các điểm dữ liệu để giữ cho hình ảnh trực quan luôn hiển thị rõ ràng trên bản đồ. Thuộc tính này cho phép bạn kiểm soát mức độ thay đổi kích thước này.
  • radiusMaxPixels đặt chiều rộng tối đa của pixel cho mỗi điểm dữ liệu.
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. Tạo một thực thể của lớp ScatterplotLayer trong deck.gl:
const scatterplotLayer = new ScatterplotLayer(layerOptions);

Sau khi hoàn tất phần này, mã của bạn sẽ có dạng như sau:

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. Áp dụng hình ảnh trực quan cho bản đồ

Giờ đây, bạn có thể áp dụng phiên bản ScatterplotLayer cho bản đồ bằng lớp GoogleMapsOverlay. Lớp này sử dụng API OverlayView của Maps JavaScript API để chèn một ngữ cảnh WebGL lên trên bản đồ.

Sau khi thiết lập xong, bạn có thể truyền bất kỳ lớp trực quan hoá nào của deck.gl đến GoogleMapsOverlay. Lớp này sẽ kết xuất lớp và đồng bộ hoá lớp đó với bản đồ.

Để áp dụng ScatterplotLayer cho bản đồ, hãy làm theo các bước sau:

  1. Nhập lớp GoogleMapsOverlay của deck.gl:
import { GoogleMapsOverlay } from '@deck.gl/google-maps';
  1. Tạo một phiên bản của lớp GoogleMapsOverlay và truyền phiên bản scatterplotLayer mà bạn đã tạo trước đó vào thuộc tính layers của một đối tượng:
const googleMapsOverlay = new GoogleMapsOverlay({
    layers: [scatterplotLayer]
  });
  1. Áp dụng lớp phủ cho bản đồ:
 googleMapsOverlay.setMap(map);

Sau khi hoàn tất phần này, mã của bạn sẽ có dạng như sau:

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);
}

Quay lại trình duyệt, bạn sẽ thấy một hình ảnh trực quan hoá dữ liệu tuyệt vời về tất cả các trạm Citi Bike ở Thành phố New York.

d01802e265548be1.png

6. Xin chúc mừng

Xin chúc mừng! Bạn đã tạo một hình ảnh trực quan hoá dữ liệu có dung lượng lớn về dữ liệu Citi Bike của Thành phố New York bằng Nền tảng Google Maps và deck.gl.

Tìm hiểu thêm

API JavaScript của Maps cho phép bạn sử dụng mọi tính năng mà Nền tảng Google Maps cung cấp cho web. Tìm hiểu thêm về cách sử dụng Nền tảng Google Maps trên web bằng cách xem các đường liên kết sau:

deck.gl cung cấp nhiều lớp trực quan hoá dữ liệu mà bạn có thể dùng để hiển thị dữ liệu cho người dùng. Tìm hiểu thêm về cách sử dụng deck.gl với Maps JavaScript API bằng cách xem các đường liên kết sau: