Visualize data with Google Maps Platform and deck.gl

1. Before you begin

This codelab teaches you how to create a high-volume geospatial data visualization using the Maps JavaScript API and deck.gl, an open-source, WebGL-accelerated, data-visualization framework.

d01802e265548be1.png

Prerequisites

What you'll do

  • Integrate Google Maps Platform with deck.gl.
  • Import a dataset to a map from BigQuery.
  • Define the data points on the map.

What you'll need

  • A Google Account
  • A text editor or IDE of your choice
  • Basic knowledge of JavaScript, HTML, and CSS

2. Set up your environment

Get started with Google Maps Platform

If you haven't used Google Maps Platform before, follow these steps:

  1. Create a billing account.
  2. Create a project.
  3. Enable Google Maps Platform APIs and SDKs.
  4. Generate an API key.

Download Node.js

If you don't already have it, go to https://nodejs.org/, and download and install the Node.js runtime on your computer.

Node.js includes npm, a package manager that you need to install the dependencies for this codelab.

Set up the starter project

To save you time, the starter project for this codelab includes all the boilerplate code that you need to instantiate a map.

To get started, follow these steps:

  1. Clone or download this repository.
  2. From the command line, navigate to the /starter directory, which contains the basic file structure that you need to complete this codelab.
  3. Install dependencies from npm by running the following command:
npm install
  1. Run the starter project in your browser with Webpack Dev Server by running the following command:
npm start
    The starter app opens in your browser and displays a map.
  1. Open the project in your IDE and navigate to the /starter/src directory.
  2. Open the app.js file.

You'll do all your coding in this section of the code in the file:

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

You won't do anything with the rest of the code in the file, which loads the Maps JavaScript API and map:

/* 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. Replace YOUR API KEY with your actual API key, which you generated when you set up your environment:
const googleMapsAPIKey = 'YOUR API KEY';

3. Export data from BigQuery

BigQuery offers many public datasets that you can use for data analysis or experimental purposes.

Use BigQuery to export a publicly available dataset that includes location data for New York City's Citi Bike, a bikeshare program with 14,500 bikes and 900 locations, by following these steps:

  1. Go to Cloud Console.
  2. Click Navigation menu 41e8e87b85b0f93.png > BigQuery.
  3. In the Query editor, enter the following query and click Run:
SELECT
    longitude,
    latitude,
    name,
    capacity
FROM
    `bigquery-public-data.new_york_citibike.citibike_stations`
  1. After the query completes, click Save Results, then select JSON (local file) to export the result set. Name the file stations.json and save it in the /src directory.

2f4932829f7e1f78.png

Now that you obtained your data, you can create your first visualization with deck.gl.

4. Define the visualization

deck.gl is an open source data-visualization framework that uses WebGL to produce high-resolution 2D and 3D renderings of extremely large datasets. It can handle hundreds of thousands of data points and, when optimized, it can even handle millions of them.

To create a visualization, you need two classes—GoogleMapsOverlay and one of deck.gl's many visualization layers.

To start, create an instance of ScatterplotLayer—which renders data points as circles on the map:

  1. Import deck.gl's ScatterplotLayer class by adding the following to the top of app.js:
import { ScatterplotLayer } from '@deck.gl/layers';
  1. Set your layer properties by choosing from the two types of properties available for deck.gl's scatterplot layer.

Setter properties provide the visualization with the information that it needs to render, such as the position and radius of data points. Styler properties let you customize the visualization's style.

Here's a breakdown of the properties that you use in the following code snippet:

  • id allows the renderer to identify layers for various reasons, such as repaints and other updates to the visualization. All deck.gl layers require a unique ID, which you assign.
  • data specifies the data source of the visualization. Set it to ‘./stations.json' to use the dataset that you exported from BigQuery.
  • getPosition retrieves each object's position from the data source. Notice that the value of the property is a function. deck.gl uses the function to iterate over every row in the dataset. The function tells the renderer how to access the latitude and longitude of the data point in each row. In this dataset, the data in each row is a JSON object with the position set in the latitude and longitude properties, so the function that you provide to getPosition is d => [parseFloat(d.longitude), parseFloat(d.latitude)].
  • getRadius defines each object's radius in meters. In this case, the radius is set to d => parseInt(d.capacity), which sets the size of the data points based on each station's capacity.
  • stroked sets whether the rendered data points have a stroke on their outer edges.
  • getFillColor sets the fill color of each data point as an RGB color code.
  • getLineColor sets the stroke color of each data point as an RGB color code.
  • radiusMinPixels sets the minimum pixel width for each data point. As users zoom in and out, deck.gl automatically resizes the scale of data points to keep the visualization clearly visible on the map. This property lets you control the extent to which this resizing occurs.
  • radiusMaxPixels sets the maximum pixel width for each data point.
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. Create an instance of deck.gl's ScatterplotLayer class:
const scatterplotLayer = new ScatterplotLayer(layerOptions);

After you complete this section, your code should look like this:

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. Apply the visualization to the map

Now you can apply your ScatterplotLayer instance to the map with the GoogleMapsOverlay class, which uses the Maps JavaScript API OverlayView API to inject a WebGL context on top of the map.

Once that's in place, you can pass any of deck.gl's visualization layers to GoogleMapsOverlay, which renders the layer and syncs it with the map.

To apply your ScatterplotLayer to the map, follow these steps:

  1. Import deck.gl's GoogleMapsOverlay class:
import { GoogleMapsOverlay } from '@deck.gl/google-maps';
  1. Create an instance of the GoogleMapsOverlay class and pass it the scatterplotLayer instance that you created earlier in the layers property of an object:
const googleMapsOverlay = new GoogleMapsOverlay({
    layers: [scatterplotLayer]
  });
  1. Apply the overlay to the map:
 googleMapsOverlay.setMap(map);

After you complete this section, your code should look like this:

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

Go back to your browser, where you should see an awesome data visualization of all the Citi Bike stations in New York City.

d01802e265548be1.png

6. Congratulations

Congratulations! You produced a high-volume data visualization of New York City's Citi Bike data with Google Maps Platform and deck.gl.

Learn more

The Maps JavaScript API gives you access to everything Google Maps Platform offers for the web. Learn more about working with Google Maps Platform on the web by checking out these links:

deck.gl offers numerous data-visualization layers that you can use to display data to your users. Learn more about using deck.gl with the Maps JavaScript API by checking out these links: