Search code examples
javascriptdata-visualizationdeck.gl

Updating Geojson layers dynamically in a deck.gl map


I can't update the layers I create in the deck dynamically.

I initialized the map after creating initial layers (a feature collection geojson that has city boundaries). After that, I pick a city and try to load district layers into the map with a drop-down menu which I listen with jquery-change. I validated both cities and districts geojson using gejosin.io and voth renders well. On my app, initial city layers show, but when I change layer instances (that share same id which is told to be so in the documents), it doesn't update on the view. I have used setProps and in the console I can see data of layers indeed changing. Only problem seems to be changes are not taking action in the map. I also tried using redraw() method of the deck(map) with no success.

One thing to note that, deck.gl doesn't update map elements with relevant methods manually. It says that it uses "The Reactive Programming Paradigm". From what I understand, when we change data, it updates itself. There are exceptions to that where we use external functions, which causes changes to not take any effect, but we don't use such a thing here.

var tarimDeck;
var typeColorList = {};

$(document).ready(function () {

    // Set the map view zone.
    $("#TarlaMapView").css("height", $(window).height() - 200 + "px").css("width", "100%");


    const LIGHT_SETTINGS = {
        lightsPosition: [-125, 50.5, 5000, -122.8, 48.5, 8000],
        ambientRatio: 0.2,
        diffuseRatio: 0.5,
        specularRatio: 0.3,
        lightsStrength: [1.0, 0.0, 2.0, 0.0],
        numberOfLights: 2
    };

    // Get cities with geojson data to place initial layers.
    // Currently cities are pulled from a local file.
    var ilData = {};
    $.getJSON("./tr_iller_geo.json", function (file_content) {
        ilData = file_content;

        const visibleLayers = new deck.GeoJsonLayer({
            id: "current-layers",
            data: ilData,
            opacity: 0.6,
            stroked: false,
            filled: true,
            extruded: true,
            wireframe: true,
            fp64: true,
            lightSettings: LIGHT_SETTINGS,
            getElevation: f => (5555),
            getFillColor: f => /*(colorSetter(f.properties.urunType) ? colorSetter(f
                        .properties.urunType) : [0, 0, 0]) */random_rgba(),
            getLineColor: f => [0, 0, 0],
            pickable: true,
            onHover: updateTooltip
        });

        // Load the initial map view with city layers.
        tarimDeck = new deck.DeckGL({
            mapboxAccessToken: 'pk.eyJ1IjoiaGFiaWwyNCIsImEiOiJjanU5cHk1a3QwbGZwNGRuMHc4dHZsMGJwIn0.Yrkp8-SSLDqHTRCKzXd8DA',
            mapStyle: 'https://free.tilehosting.com/styles/positron/style.json?key=2OrAmqAgbK4HwBOq6vWN',
            container: 'TarlaMapView',
            latitude: 38,
            longitude: 35.8,
            zoom: 5.9,
            maxZoom: 16,
            pitch: 45,
            layers: [visibleLayers]
        });

        $("#il-dropdown").dropdown('setting', 'onChange', function () {
            // Actions Here

                        var ilceFeatures = [];
                        response.forEach(x => {
                            if (x.geo) {
                                ilceFeatures.push(
                                    {
                                        "type": "Feature",
                                        "geometry": x.geo,
                                        "properties": {
                                            ilce_name: "salla_bisi"
                                        }
                                    });
                            }
                        });

                        var ilceFeatureCollection = {
                            "type": "FeatureCollection",
                            "features": ilceFeatures
                        };
                        console.log("ilce gejson: ", ilceFeatureCollection);
                        // Create new layers for  "ilce" geojson.
                        const newLayers = [new deck.GeoJsonLayer({
                            id: "current-layers",
                            data: ilceFeatureCollection,
                            opacity: 0.8,
                            stroked: false,
                            filled: true,
                            extruded: true,
                            wireframe: true,
                            fp64: true,
                            lightSettings: LIGHT_SETTINGS,
                            getElevation: f => (5555),
                            getFillColor: f => random_rgba(),
                            getLineColor: f => [0, 0, 0],
                            pickable: true,
                            onHover: updateTooltip

                        })];

                        tarimDeck.setProps(newLayers);
                        console.log("tarimdeck: ",tarimDeck);

                    },
                    error: function (err) {
                        console.log(err);
                    }
                });
            }

        });

    });

I would like to be able to change visible layers from cities to districts. Furthermore, I am going to change view-port as well, but first I need to have dynamic layers.


Solution

  • After posting an issue thread in the deckgl github page, I've been corrected as follows:

    tarimDeck.setProps(newLayers);
    

    Should be

    tarimDeck.setProps({layers: newLayers});
    

    For some reason I have assumed given a valid layer object as parameter, it would "magically" know which prop to update, I was wrong.

    I am sharing my mistake for further similar occurrences.