visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.08k stars 2.08k forks source link

MapboxLayer being duplicated when updating props for it #3763

Closed omguhh closed 3 years ago

omguhh commented 4 years ago

Description

First, I want to say thank you for the maintainers of this library - it's lovely work <3

We use mapbox on an internal project and I've added deck.gl for some of the layers supported, namely the HexagonLayer.

I add it to the mapbox instance the way the documentation recommends:

const deckGLLayer = new MapboxLayer({
        id: id,
        type: HexagonLayer,
        source: data,
        data: data,
        radius: radius,
        colorRange: COLOR_RANGE,
        extruded: false,
        getPosition: d => d.geometry.coordinates,
        opacity: 1,
        pickable: true
});

//after map is loaded
layers.forEach((layer) => {
      if (layer.id.indexOf('deckgl') === -1) {
          map.addLayer(layer);
      } else {
           const deckglLayer = new MapboxLayer(layer);
           map.addLayer(deckglLayer)
       }
}

In this project, we support mapbox style switching, so something like this that changes the style of the layer

Screen Shot 2019-10-09 at 11 55 53 AM

because mapbox removes all the layers when the style is changed, i force re-add the layers back (including the deck.gl layer) using map.addLayer(deckGLLayer) in a loop. This is when things get weird and I start seeing double/offset Hexagon layers. This is only visible after I change the zoom level and then change map style.

Screen Shot 2019-10-09 at 11 55 39 AM

I've tried what was suggested in the tips and tricks - I set depthTest to false & even tested with extrusion enabled, but I had the same problem.

Environment

Logs

I get this in the logs, but I'm not sure how this is happening since I am only ever adding after the map style has switched and there are no layers there.

deck: Multiple old layers with same id ColumnLayer({id: 'deckgl-incident-hexbin-hexagon-cell'})
deck: Multiple old layers with same id HexagonLayer({id: 'deckgl-incident-hexbin'})
omguhh commented 4 years ago

After some more debugging, I found that the layers are being duplicated after style change 🤔 I logged updateLayers in deck-utils.js and it returned two HexagonLayers.

[ HexagonLayer {props: {…}, id: "deckgl-incident-hexbin", count: 6, lifecycle: "Matched. State transferred from previous layer", parent: null, …}
 HexagonLayer {props: {…}, id: "deckgl-incident-hexbin", count: 7, lifecycle: "Initialized", parent: null, …} ]

If the state layer is matched, why don't we remove the older one? 💭 Do I need to remove it manually?

omguhh commented 4 years ago

So, I've tried seeing if the behavior would change if I used deck's layer stack (which I want to avoid) and it worked fine (but it's not something I can use in my project)

So the issue I'm having is when I'm updating a static mapbox layer, they continue being added to the stack even though it's matched when it should be deleted 🤷‍♀ any work arounds for this?

1chandu commented 4 years ago

In your code, is map a Mapbox object, so if this is related to Mapbox's Map.addLayer, better open issue in mapbox repo for help? If not, can you post code that shows how you are using Deck ?

Pessimistress commented 3 years ago

This seems to be a bug on Mapbox' part - it is supposed to call customLayer.onRemove when style changes:

https://github.com/visgl/deck.gl/blob/bddc36902a2535fa9430a1b450944f83cf4d9d11/modules/mapbox/src/mapbox-layer.js#L26

As a work around you can call map.removeLayer before changing the style.