5

enter image description here I am building a basic visualization system that layers can be toggled from the control box. I have layers that merge individual layers into one.

const [layers, setLayers] = useState([densityLayer, pedestrianLayer]);

I have filterState that tracks the activity in the control box. It contains the layer object as a property of linkTo

 const [filterState, setFilterState] = useState([
        {
          id: 'densityFilter',
          checked: true,
          description: 'Population density',
          linkedTo: densityLayer
        },
        {
          id: 'pedestrianFilter',      
          checked: true,
          description: 'Pedestrian volume',
          linkedTo: pedestrianLayer
        }
      ]);

and everytime checked property in filterState gets updated, it launches renderLayers() which will select corresponding layers whose checked property is true.

  useEffect(()=>{
        renderLayers();
      },[filterState]);

      const renderLayers = () => {
        const newLayers = []; 
        filterState.map(filter => (filter.checked && newLayers.push(filter.linkedTo)));
        setLayers(newLayers);
      }

Then layers is passed to DeckGL component as a layer prop.

   <DeckGL
        initialViewState={viewState}
        controller={true}
        layers={layers}
      >

In my program, turning off the layers works fine, but they do not turn back on. In the console, I noticed that the lifecycles between layers are different. Is there anything incorrect about my approach?

D Park
  • 504
  • 10
  • 19

1 Answers1

6

Have you try to use visible property of layers? If you are going to switch multiple time and often, deck.gl suggests to use visible instead of recreated a new layer. Some useful resources about this thread:

First, create a Control box, like you did. Then pass as props to DeckGL component what you selected from control box.

{
    layer1: true, layer2: false, layer3: false, layer4: false,
}

Create a state for layers.

const [activeLayers, setActiveLayers] = useState(layersProps);

Check with useEffect when something changes in layersProps.

useEffect(() => {
    const layers = {
        layer1: false,
        layer2: false,
        layer3: false,
        layer4: false,
    };

    if (typeMap === 'layer1') {
        layers.layer1 = true;
    } else if (typeMap === 'layer2') {
        layers.layer2 = true;
    }
    ...

    setActiveLayers(layers);
}, [layerProps]);

Or you can create a state

const [activeLayers, setActiveLayers] = useState({
    layer1: true, layer2: false,
});

And pass as props only what you selected from control box and check for changes.

useEffect(() => {
    const layers = {
        layer1: false,
        layer2: false,
    };

    if (typeMap === 'layer1') {
        layers.layer1 = true;
    } else if (typeMap === 'layer2') {
        layers.layer2 = true;
    }
    ...

    setActiveLayers(layers);
}, [inputLayerSelected]);

If you prefer you can also split each layer with a single one state (so you have a primitive value).

Finaly, you can create your layer

const layer1 = new ScatterplotLayer({
    id: 'scatter',
    data: data,
    ....
    visible: activeLayers.layer1, OR
    visible: layer1
});

and render

<DeckGL
    layers={[layer1, layer2, layer3, layer4]}
    ...
>
lezan
  • 759
  • 6
  • 23