CARTO + Google Maps

CARTO + Google Maps

Trips Layer

This example shows how to use the TripsLayer to render animated paths that represent vehicle trips.

  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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<!DOCTYPE html>
<html>

<head>
  <title>Extrusion</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>
    #map {
      height: 100%;
    }

    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>

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

  <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;
  const LOOP_LENGTH = 1800;
  const ANIMATION_SPEED = 0.4;
  let time = 0;
  let layerData = [];
  let deckOverlay;

  function initMap() {
    map = new google.maps.Map(document.getElementById("map"), {
      center: { lat: 40.73, lng: -74 },
      zoom: 13,
      tilt: 45,
      mapId: '2a9fc80dfecb64f8',
      fullscreenControl: false,
      streetViewControl: false,
      zoomControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM,
      },
    });

    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
    deck.carto.getData({
      type: deck.carto.MAP_TYPES.QUERY,
      source: `SELECT geom, vendor, 
                        TO_JSON_STRING(timestamps) AS timestamps 
                   FROM cartobq.public_account.new_york_trips`,
      connection: 'bqconn',
      format: deck.carto.FORMATS.GEOJSON
    }).then((geojsonData) => {
      // TripsLayer needs data in the following format
      layerData = geojsonData.features.map(f => ({
        vendor: f.properties.vendor,
        timestamps: JSON.parse(f.properties.timestamps),
        path: f.geometry.coordinates
      }));
    });

    deckOverlay = new deck.GoogleMapsOverlay({});

    deckOverlay.setMap(map);

    initAnimation();
  }

  function animate() {
    time = (time + ANIMATION_SPEED) % LOOP_LENGTH;
    window.requestAnimationFrame(animate);
  }

  function initAnimation() {

    setInterval(() => {
      deckOverlay.setProps({
        layers: [
          new deck.TripsLayer({
            id: 'trips-layer',
            data: layerData,
            getPath: d => d.path,
            getTimestamps: d => d.timestamps,
            getColor: d => (d.vendor === 0 ? [253, 128, 93] : [23, 184, 190]),
            opacity: 0.3,
            widthMinPixels: 2,
            rounded: true,
            trailLength: 180,
            currentTime: time,
            shadowEnabled: false
          })
        ]
      });
    }, 50);

    window.requestAnimationFrame(animate);
  }

</script>

</html>