CARTO dynamic tiling

by felixp

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>deck.gl+Google</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <script src="https://unpkg.com/[email protected]/dist.min.js"></script>
    <script src="https://unpkg.com/@deck.gl/[email protected]/dist.min.js"></script>

    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&v=beta&map_ids=fae05836df2dc8bb&callback=initMap" async
    ></script> 
    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

CSS

/* 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;
}

JavaScript

deck.carto.setDefaultCredentials({
  apiVersion: deck.carto.API_VERSIONS.V3,
  apiBaseUrl: 'https://gcp-us-east1-19.dev.api.carto.com',
  accessToken: 'eyJhbGciOiJIUzI1NiJ9.eyJhIjoiYWNfZmt0MXdsbCIsImp0aSI6IjNmM2NlMjA3In0.zzfm2xZSAjcTlLxaPQHDy8uVJbGtEC5gItOg8U_gfP4'
})

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: {lat: 40,  lng: -120},
    disableDefaultUI: true,
    gestureHandling: 'greedy',
    mapId: 'fae05836df2dc8bb',
    zoom: 3
  });


  const layer = new CartoLayer({
    type: deck.carto.MAP_TYPES.TABLE,
    connection: 'bigquery',
    data: 'cartobq.testtables.points_100k',
    pointRadiusMinPixels: 2,
    getFillColor: [200, 0, 80, 180],
    modelMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10000000, 1]
  })

  const overlay = new deck.GoogleMapsOverlay({
    layers: [layer]
  });
  overlay.setMap(map);
}

// Hack in new function as we don't have a public package yet
class CartoLayer extends deck.carto.CartoLayer {
  async _updateData() {
    try {
      const {
        type,
        data: source,
        connection,
        credentials,
        geoColumn,
        columns
      } = this.props;
      const localConfig = {
        ...credentials
      };

      let data;

      data = await deck.carto.getData({
        type,
        source,
        connection,
        credentials,
        geoColumn,
        columns,
        // force tilejson
        format: 'tilejson'
      });


      this.setState({
        data,
        apiVersion: 'v3'
      });
      this.props.onDataLoad(data);
    } catch (err) {
      if (this.props.onDataError) {
        this.props.onDataError(err);
      } else {
        throw err;
      }
    }
  }

  renderLayers() {
    const {
      data
    } = this.state;

    if (!data) return null;

    const {
      updateTriggers
    } = this.props;

    let layer;

    if (
      (data && data.tilejson === '2.2.0' && data.tiles)
    ) {
      layer = deck.MVTLayer;
    }...