deck.gl + tripslayer without react.js
Asked Answered
S

3

6

How can I enable animation of TripsLayer without react? TripsLayer example uses React and I really don't know, how to convert it to pure js. Please look at "animate" function in the code below. I tried to update state of layer but it doesn't work (there is no animation of TripsLayer). I don't know, where should I assign "time" variable.

Demo of TripsLayer: https://deck.gl/#/examples/custom-layers/trip-routes

React version my code: https://github.com/uber/deck.gl/blob/master/examples/website/trips/app.js

Docs for TripsLayer: https://github.com/uber/deck.gl/tree/master/modules/experimental-layers/src/trips-layer

My code:

import {MapboxLayer} from '@deck.gl/mapbox';
import {TripsLayer} from '@deck.gl/experimental-layers';
import mapboxgl from 'mapbox-gl';

class App
{
  constructor()
  {
    this.stateInfo = { time: 600 };
  }

  get state()
  {
    return this.stateInfo;
  }

  animate() {
    var loopLength = 18000; // unit corresponds to the timestamp in source data
    var animationSpeed = 30; // unit time per second

    const timestamp = Date.now() / 1000;
    const loopTime = loopLength / animationSpeed;

    var time = Math.round(((timestamp % loopTime) / loopTime) * loopLength);

    // HOW SHOULD I USE time VARIABLE???

    window.requestAnimationFrame(this.animate.bind(this)); 
  }
}

var obido = new App();

var tripsLayerObido = new TripsLayer({
  id: 'trips',
  data: 'trips/tripsKR.json',
  getPath: d => d.segments,
  getColor: d => (d.vendor === 0 ? [253, 128, 93] : [23, 184, 190]),
  opacity: 0.6,
  strokeWidth: 30,
  trailLength: 180,
  currentTime: obido.state.time
});

const LIGHT_SETTINGS = {
  lightsPosition: [-74.05, 40.7, 8000, -73.5, 41, 5000],
  ambientRatio: 0.05,
  diffuseRatio: 0.6,
  specularRatio: 0.8,
  lightsStrength: [2.0, 0.0, 0.0, 0.0],
  numberOfLights: 2
};

export const INITIAL_VIEW_STATE = {
  longitude: 19.93,
  latitude: 50.03,
  zoom: 12.8,
  maxZoom: 19,
  pitch: 60,
  bearing: 0
};


mapboxgl.accessToken = "XXX";
const map = new mapboxgl.Map({
  container: 'app',
  style: 'mapbox://styles/elninopl/cjnlge6rl094w2so70l1cf8y5',
  center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude],
  zoom: INITIAL_VIEW_STATE.zoom,
  pitch: INITIAL_VIEW_STATE.pitch,
  layers: [tripsLayerObido]
});

map.on('load', () => {
  obido.animate(0);
});
Southwestwards answered 10/11, 2018 at 21:10 Comment(2)
Hi, please edit your question to explain exactly what happens ('it doesn't work' isn't helpful). I would also have another look at the tags (suggest you add javascript, for a start). Finally, please clarify why you don't want to use react. Thanks.Tigress
I would also suggest that you create an example that someone can come along and easily pick up. I would suggest that your problem is that you are never telling anything to re-render. The this.setState in React triggers a render, which you aren't doing here. You want something along the lines of deck.setProps, but you're combining mapbox custom layers with Deck GL and I'm not sure how to do it there.Corkboard
R
0

Please try setProps, which makes my trips layer updates:

this.tripsLayer.setProps({ currentTime: this.currentTime });
Rebuff answered 25/7, 2019 at 3:59 Comment(0)
S
0

yes,it works.

function animate(timestamp) {
  var timestamp = Date.now() / 1000;
  var loopTime = loopLength / animationSpeed;
  curtime= ((timestamp % loopTime) / loopTime) * loopLength;
  requestAnimationFrame(animate);
  tripLayer.setProps({ currentTime: curtime });
}
Self answered 23/3, 2020 at 8:39 Comment(0)
B
0

I'm a bit late here, but here there is an example of using deck.gl TripsLayer with the Scripting API (without React).

<script src="https://unpkg.com/deck.gl@^8.4.0/dist.min.js"></script>
<script src="https://unpkg.com/@deck.gl/carto@^8.4.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" />

<div id="map" style="width: 100vw; height: 100vh"></div>

const ambientLight = new deck.AmbientLight({
  color: [255, 255, 255],
  intensity: 1.0
});

const pointLight = new deck.PointLight({
  color: [255, 255, 255],
  intensity: 2.0,
  position: [-74.05, 40.7, 8000]
});

const lightingEffect = new deck.LightingEffect({ ambientLight, pointLight });

const material = {
  ambient: 0.1,
  diffuse: 0.6,
  shininess: 32,
  specularColor: [60, 64, 70]
};

const theme = {
  buildingColor: [74, 80, 87],
  trailColor0: [253, 128, 93],
  trailColor1: [23, 184, 190],
  material,
  effects: [lightingEffect]
};

const LOOP_LENGTH = 1800;
const ANIMATION_SPEED = 0.4;

async function initialize() {
  deck.carto.setDefaultCredentials({
    username: 'public',
    apiKey: 'default_public',
  });

  // Fetch Data from CARTO
  // Notice that you can use any Deck.gl layer with CARTO datasets getting GeoJSON data from CARTO's API. This method is recommended for complex layers with datasets below 50Mb
  const tripsUrl = 'https://public.carto.com/api/v2/sql?q=SELECT the_geom, vendor, timestamps FROM sf_trips_v7&format=geojson';
  const geojsonTripsData = await fetch(tripsUrl).then(response => response.json());
  // TripsLayer needs data in the following format
  const layerData = geojsonTripsData.features.map(f => ({
    vendor: f.properties.vendor,
    timestamps: f.properties.timestamps,
    path: f.geometry.coordinates[0]
  }));

  const staticLayers = [
    // This is only needed when using shadow effects
    new deck.PolygonLayer({
      id: 'ground-layer',
      data: [[[-74.0, 40.7], [-74.02, 40.7], [-74.02, 40.72], [-74.0, 40.72]]],
      getPolygon: f => f,
      stroked: false,
       getFillColor: [0, 0, 0, 0]
    }),
    new deck.carto.CartoSQLLayer({
      id: 'buildings-layer',
      data: 'SELECT the_geom_webmercator, height FROM sf_buildings',
      extruded: true,
      wireframe: true,
      opacity: 0.5,
      getElevation: f => f.properties.height,
      getFillColor: [74, 80, 87],
      material: theme.material
    })
  ];

  // Create Deck.GL map
  const deckgl = new deck.DeckGL({
    container: 'map',
    mapStyle: 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json',
    initialViewState: {
      longitude: -74,
      latitude: 40.73,
      zoom: 12,
      pitch: 45,
      bearing: 0
    },
    controller: true,
    layers: staticLayers,
    effects: theme.effects
  });

  let time = 0;

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

  setInterval(() => {
    deckgl.setProps({
      layers: [
        ...staticLayers,
        new deck.TripsLayer({
          id: 'trips-layer',
          data: layerData,
          getPath: d => d.path,
          getTimestamps: d => d.timestamps,
          getColor: d => (d.vendor === 0 ? theme.trailColor0 : theme.trailColor1),
          opacity: 0.3,
          widthMinPixels: 2,
          rounded: true,
          trailLength: 180,
          currentTime: time,
          shadowEnabled: false
        })
      ]
    });
  }, 50);

  window.requestAnimationFrame(animate);
 }

 initialize(); 
Bonaventure answered 19/2, 2021 at 18:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.