Open nerik opened 5 years ago
setFilter
is currently a very expensive operation and is indeed problematic when used for animation use cases. Perhaps you could try a different approach — encoding values for different time intervals as feature properties (e.g. one feature would have value1: 12, value2: 15, value3: 20
etc. — and then you would switch between them by doing setPaintProperty('heatmap-weight', ... expression that depends on the right value)
. This is the approach https://electricitytransition.com is using and it seems to work well.
Hi Vladimir. Thanks you so much for the answer, this is indeed a very interesting approach. We will definitely try this, noting that this requires stable geometries somehow (ie gridded data in our case).
One comment: https://electricitytransition.com still has the same "delay" problem that I mentioned, which is barely visible at the framerate used on the live site (one frame every 100ms) but is very noticeable when setting a faster framerate (closer to 60 fps / 16ms frames). The animation performance is not really the main issue here, but reliability is. Is there a way to either:
repaint = false
and triggerRepaint
but it doesn't seem to yield any visible effectdata
and idle
events can't be really reliably used.Cheers
Were you able to find a solution on how to cancel filter queue and skip to last item in queue?
Any techniques learned on how to effectively animate using either setFilter or other techniques.
Hi @agusterodin.
Were you able to find a solution on how to cancel filter queue and skip to last item in queue?
No, it's not possible.
The way we (sort of) got around that limitation is to:
step
or case
expression (the value is directly the color bucket). This was just released, currently writing a technical blogpost about it.
(follow up of a conversation with @mikelmaron)
mapbox-gl-js version: 0.54
browser: Chrome and Firefox latest, macOS
Our current map is a combination of Mapbox GL layers for all non-animated layers, and a custom WebGL renderer for animated heatmaps, which is not performing well enough and is a battery drain (because it’s heavily CPU bound).
Steps to Trigger Behavior
See below
Link to Demonstration
On paper, using Mapbox GL heatmap layers would be an ideal solution: not only performance is much better, but also they look way better (and we could remove a huge legacy dependency from our front-end). The problem is that we can't get this to behave nicely with animation (ie repeatedly changing a timestamp filter on a layer). See for yourself: https://codepen.io/nerik8000/pen/rgMdqP?editors=0010
Expected Behavior
When clicking the start button on the top left, the filter value gets updated at each rAF call to display more or less points depending on a timestamp global value. When stopping the animation (stopping updates to filter), Mapbox GL should skip any pending update and display the filtered data that matches what the UI expects, which is the last timestamp.
Actual Behavior
As you can see in the demo, when clicking the stop button, there's seemingly a queue of rendering updates that get executed one by one. This result in a lag of several seconds between the expected value and what's actually visible in the map.
While I understand the performance implications of filtering that many points (several 10s of 1000s in the demo), there should be a mechanism to allow skipping frames to match as closely as possible whatever values are set from outside. The issue here being that the resulting discrepancy makes any numeric statement displayed outside the map wrong (until the animation's final frame).
Thanks for your help.