5
votes

I am working on trying to create a basic, grid-based, but performant weather-arrow visualization system.

EDIT 2: Up-to-date version here: ( Mapbox Tracker ) of the system using the workflow which is described below

Usage Instructions: - Click on Wind icon (on the left) - Wait for triangles to occupy screen - Pan time-slider (at the bottom)

As you will observe (especially on larger resolutions or when panning time slider quickly) there is quite a performance hit when drawing the triangles.

I would greatly appreciate any advice on where to start with either using something in the current API which would help, or any ideas on how to tap into the current graphics pipeline with some type of custom buffer where I would only need to rotate, scale, change color of triangles already populated in screen space.

I feel as though my specific use-case would greatly benefit from something like this, I really just don't know how to approach it.

I have a naive implementation running using this workflow:

  • Create a geojson FeatureCollection source
  • Create a fill layer
  • Using Data Driven property: fill-color

Data function:

  1. Get map bounds
  2. Project sw & ne into screen points (map.project(LatLng))
  3. Divide height and width into portions
  4. Loop through width and height portions
  5. Lookup data
  6. Access data rotation property
  7. Create vertices based on center point + size
  8. Rotate vertices
  9. Create Point objects for vertices
  10. Unproject Point Object and wrap map.unproject(Point).wrap()
  11. Create Feature Object, assign Data driven Color
  12. Assign unprojected LatLng as Coordinates to Polygon geometry
  13. Add to Feature Array for Collection
  14. Call setData on layer

So while this works, I'm looking for advice for a more performance friendly approach.

What I'm thinking here is whether I can somehow create a custom layer, one where I only need to draw to screen co-ordinates to represent the data relative to its LatLng point. So that I can draw colored, scaled, rotated triangles in screen space, and then have them update to relevant data from the new relative LatLng position.

E.g. Update some type of Mesh on screen instead of having to: unproject, then update feature collection source using map.getSource('arrows').setData(d), requestAnimationFrame(function) etc.

I've done similar in three.js in other projects but I would much rather use something that is more mapbox native. Does this sound feasible? Am I going to see a decent performance boost if so? I've not dealt with raw gl calls before etc so I might need a pointer or two in the right direction if its going to need to get as low level as that.

EDIT:

Previous Implementation using gmaps / three.js : volvooceanrace (wait for button on left to go from grey to black) click on top button which shows a 'wind' label when hovered over, slide red time bar underneath to change data.

Added screenshot of current working implementation Mapbox GL Arrows

1

1 Answers

0
votes

Not sure what was available in 2016, but a reasonable approach these days might be to use symbol layers, and the icon-rotate data-driven property to rotate each icon based on the property of its data point.