CARTO for deck.gl

CARTO for deck.gl

Contour Layer

This example shows how to use the ContourLayer to render isolines or isobands for a given threshold and cell size.

  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
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
<html>
  <head>
    <!-- FONT -->
    <link
      href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap"
      rel="stylesheet"
    />

    <script src="https://unpkg.com/deck.gl@^8.5.0/dist.min.js"></script>
    <script src="https://unpkg.com/@deck.gl/carto@^8.5.0/dist.min.js"></script>
    
    <script src="https://libs.cartocdn.com/mapbox-gl/v1.13.0/mapbox-gl.js"></script>
    <link href="https://libs.cartocdn.com/mapbox-gl/v1.13.0/mapbox-gl.css" rel="stylesheet" />
  </head>

  <body style="margin: 0; padding: 0; overflow: hidden; font-family: 'Open Sans', sans-serif">
    <div id="map" style="width: 100vw; height: 100vh"></div>
  </body>

  <script type="text/javascript">
    const BANDS = [
      { threshold: [0.1, 1], color: [255, 255, 178] },
      { threshold: [1, 10], color: [254, 204, 92] },
      { threshold: [10, 50], color: [253, 141, 60] },
      { threshold: [50, 100], color: [240, 59, 32] },
      { threshold: [100, 1000], color: [189, 0, 38] },
      { threshold: [1000, 10000], color: [159, 0, 80] }
    ];

    const MS_PER_WEEK = 1000 * 60 * 60 * 24 * 7;

    const WEEK = 50;

    function getTooltip(info) {
      if (!info.object) {
        return null;
      }

      const date = new Date(Date.UTC(2020, 0, 20) + WEEK * MS_PER_WEEK);
      const { threshold } = info.object.contour;

      let str;
      if (threshold[1] === 1) {
        str = '<1 new case';
      } else if (threshold[0] === 2000) {
        str = '>2,000 new cases';
      } else {
        str = `${threshold[0]}-${threshold[1]} new cases`;
      }

      return `\
        Week of ${date.toJSON().slice(0, 10)}
        ${str} per 100K residents`;
    };

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

      // Fetch Data from CARTO
      const geojsonData =  await deck.carto.getData({
        type: deck.carto.MAP_TYPES.QUERY,
        source: `SELECT geom, casesbyweek, population FROM cartobq.public_account.eeuu_covid_by_county`,
        connection: 'bqconn',
        format: deck.carto.FORMATS.GEOJSON
      });

      // Create deck.gl map
      const deckgl = new deck.DeckGL({
        container: 'map',
        mapStyle: deck.carto.BASEMAP.DARK_MATTER,
        initialViewState: {
          longitude: -100,
          latitude: 39,
          zoom: 3,
          maxZoom: 10
        },
        controller: true,
        layers: [
          new deck.ContourLayer({
            id: 'contour-layer',
            data: geojsonData.features,
            getPosition: d => d.geometry.coordinates,
            getWeight: d => ((d.properties.casesbyweek[WEEK] || 0) / d.properties.population) * 1e5,
            pickable: true,
            aggregation: 'MAX',
            contours: BANDS,
            cellSize: 90000
          })
        ],
        getTooltip
      });
    }

    initialize();    
  </script>
</html>