CARTO + Google Maps

CARTO + Google Maps

Getting started

CARTO provides a powerful way to visualize data from your datawarehouse with Google Maps Javascript API. By utilizing the CartoLayer class of deck.gl you can bring data from a table, a tileset or even a SQL directly all from JS.

After completing this guide, you will have your first Google Maps API map with data from your datawarehouse!

Basic setup

We are going to start with the Hello World example from the Google Maps Javascript API documentation, but centering the initial view on the United States and zoom level 4. To simplify the example, we are going to embed the JavaScript code and the CSS declarations in the HTML file.

We are going to use the new WebGL features for the Maps Javascript API. These features add support for vector maps, 3D graphic content, continuous zoom and tilt/heading parameters. Please follow the instructions to create a Map ID in the Google Cloud Console.

At this point you will have a simple map:

View this step here

Adding data from CARTO

The first step you need to perform is to add the deck.gl dependencies, including the CARTO submodule:

1
2
<script src="https://unpkg.com/deck.gl@^8.6.0/dist.min.js"></script>
<script src="https://unpkg.com/@deck.gl/carto@^8.6.0/dist.min.js"></script>

Then you need to provide the credentials for connecting to the CARTO 3 platform, as explained here. Here we are using a token with access to some public datasets in BigQuery. You will need to create a token with access to the datasets you want to visualize.

1
2
3
4
5
setDefaultCredentials({
  apiBaseUrl: 'https://gcp-us-east1.api.carto.com',
  apiVersion: API_VERSIONS.V3,
  accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJhIjoiYWNfbHFlM3p3Z3UiLCJqdGkiOiI1YjI0OWE2ZCJ9.Y7zB30NJFzq5fPv8W5nkoH5lPXFWQP0uywDtqUg8y8c'
});

Now you can add a map layer from the public account. In order to add the layer, we will use the GoogleMapsOverlay class from deck.gl. We need to specify the layers as an array. In this case, we only have one CartoLayer from the deck.gl CARTO submodule. We pass the following parameters to the constructor:

  • connection is the name of the connection to BigQuery in the CARTO 3 Workspace.

  • type defines the type of dataset. In this case, we are going to visualize a table so we use one of the constants defined in the MAP_TYPES enumeration.

  • data contains the dataset that we want to visualize. It can be the name of a table, the name of a tileset, or a SQL query. In this case we are going to provide a table name. The CartoLayer will make the appropriate requests to the Maps API to retrieve the GeoJSON features from the BigQuery table.

  • Style parameters. In order to display the information, the CartoLayer uses the GeoJsonLayer to style the features, so all the properties of this class are supported. The style parameters depend on the dataset type of geometry. In this case, we are adding a point layer, so we specify the point color using the getFillColor property, the circle outline color with the getLineColor property, and the point and outline sizes through the pointRadiusMinPixels and lineWidthMinPixels properties.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const deckOverlay = new deck.GoogleMapsOverlay({
    layers: [
        new deck.carto.CartoLayer({
            connection: 'bqconn',
            type: deck.carto.MAP_TYPES.TABLE,
            data: `cartobq.public_account.retail_stores`,
            getLineColor: [255, 255, 255],
            getFillColor: [238, 77, 90],
            pointRadiusMinPixels: 6,
            lineWidthMinPixels: 1,
        }),
    ]
});

Finally you need to use the setMap function on the GoogleMapsOverlay object to add the layer to the map.

1
deckOverlay.setMap(map);

All together

You can explore the final step here

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script src="https://unpkg.com/deck.gl@^8.6.0/dist.min.js"></script>
    <script src="https://unpkg.com/@deck.gl/carto@^8.6.0/dist.min.js"></script>  
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }

      /* Optional: Makes the sample page fill the window. */
      html,
      body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
  </head>

  <body>
    
    <div id="map"></div>

    <!-- Async script executes immediately and must be after any DOM elements used in callback. -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDvHtBZM79O5uGTBT1ZOWOKW2_FVMstHNs&callback=initMap&libraries=&v=beta"
      async
    ></script>
    
  </body>

  <script type="text/javascript">
    let map;

    function initMap() {
      map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: 38, lng: -98 },
        zoom: 4,
        mapId: '856f688f677c0bc3',
      });

      deck.carto.setDefaultCredentials({
        apiBaseUrl: 'https://gcp-us-east1.api.carto.com',
        apiVersion: deck.carto.API_VERSIONS.V3,
        accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJhIjoiYWNfbHFlM3p3Z3UiLCJqdGkiOiI1YjI0OWE2ZCJ9.Y7zB30NJFzq5fPv8W5nkoH5lPXFWQP0uywDtqUg8y8c'
      });

      const deckOverlay = new deck.GoogleMapsOverlay({
        layers: [
          new deck.carto.CartoLayer({
            connection: 'bqconn',
            type: deck.carto.MAP_TYPES.TABLE,
            data: `cartobq.public_account.retail_stores`,
            getLineColor: [255, 255, 255],
            getFillColor: [238, 77, 90],
            pointRadiusMinPixels: 6,
            lineWidthMinPixels: 1,
          }),
        ],
      });

      deckOverlay.setMap(map);
    }

  </script>
</html>