Skip to main content
1 of 3
user1249791
  • 419
  • 2
  • 12

mapboxgl applying map.setFeatureState to a group of vector-tiles filtered features

Doing some tests, trying to let user click on a COUNTY and all counties belonging to STATE x get highlighted.

You can see running here

var map = new mapboxgl.Map({
        container: 'map',
        style: {
            "version": 8,
            "name": "blank",
            "sources": {
                "empty": {
                    "type": "vector",
                    "url": ""
                }
            },
            "layers": [{
                "id": "background",
                "type": "background",
                "paint": {
                    "background-color": "#1d1f20"
                }
            }]
        },
        center: [-82, 39],
        zoom: 3,
        debug: 2
    });
    var hoveredStateId = null;

    map.on('load', function() {
        map.addSource("counties", {
            "type": "vector",
            "url": "mapbox://reyemtm.28b260nr"
        });

        // The feature-state dependent fill-opacity expression will render the hover effect
        //  when a feature's hover state is set to true.
        map.addLayer({
            "id": "fill",
            "type": "fill",
            "source": "counties",
            "source-layer": "us_counties-8xelrv",
            "layout": {},
            "paint": {
                "fill-color": ["case", ["boolean", ["feature-state", "hover"], false], "whitesmoke", "firebrick"],
                "fill-opacity": 1
            }
        })

        function getUniqueFeatures(array, comparatorProperty) {

            var existingFeatureKeys = {};
            var uniqueFeatures = array.filter(function(el) {
                if (existingFeatureKeys[el.properties[comparatorProperty]]) {
                    return false;
                } else {
                    existingFeatureKeys[el.properties[comparatorProperty]] = true;
                    return true;
                }
            });

            return uniqueFeatures;
        }

        map.on("click", "fill", function(e) {
            if (e.features.length > 0) {

                var state_code = e.features[0].properties.STATE;
                console.info(state_code)
                var relatedFeatures = map.querySourceFeatures('counties', {
                    sourceLayer: 'us_counties-8xelrv',
                    filter: ['==', 'STATE', state_code]
                });

                var uniqueFeatures_state = getUniqueFeatures(relatedFeatures, "STATE");
                var uniqueFeatures_id = getUniqueFeatures(relatedFeatures, "id");
                console.log(uniqueFeatures_state)


                relatedFeatures.forEach(function(f) {
                    console.log(f.id) //18
                    console.log(f.properties.STATE) //allways the same, this is good
                    var s = {
                        source: 'counties',
                        sourceLayer: 'us_counties-8xelrv',
                        id: f.id
                    };
                    map.setFeatureState(s, {
                        hover: true
                    });
                });
            }
        });
    });

Console gives the correct info (that is, ids are unique and state_code is the same for all filtered features when click on one county). Curiously Texas is one of the few working correctly, but, when zooming in/out, highlighting becomes a chaos.

I have also tried using uniqueFeatures_state as the object to iterate over, with no success.

thanks

user1249791
  • 419
  • 2
  • 12