TransWikia.com

Highlighting feature by Id with Leaflet

Geographic Information Systems Asked on April 17, 2021

I cannot work out the solution given in Leaflet highlight feature by ID.

I have the script below which adds a layer "commercial" and a layer "sector". What I want is that when I mouseover a commercial, its corresponding sector highlights (they have the same Id). So I added _featureId on both layers and I am stuck.

What do I need to do to make it work?

        var json_commercial = {
        "type": "FeatureCollection",
        "name": "commercial",
        "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
        "features": [
        { "type": "Feature", "properties": { "id": "1" }, "geometry": { "type": "Point", "coordinates": [ 1.305263516194724, 49.42360636638827 ] } },
        { "type": "Feature", "properties": { "id": "2" }, "geometry": { "type": "Point", "coordinates": [ 1.974762218487792, 49.283373530097158 ] } }
        ]
    }

    var json_secteurs = {
        "type": "FeatureCollection",
        "name": "secteurs",
        "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
        "features": [
        { "type": "Feature", "properties": { "id": "1" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.020274203732134, 49.305991729498949 ], [ 1.309787156075082, 49.56836284255975 ], [ 1.789292983393091, 49.455271845550783 ], [ 1.020274203732134, 49.305991729498949 ] ] ] ] } },
        { "type": "Feature", "properties": { "id": "2" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.789292983393091, 49.455271845550783 ], [ 1.309787156075082, 49.56836284255975 ], [ 1.775722063752015, 49.65883564016692 ], [ 1.789292983393091, 49.455271845550783 ] ] ] ] } },
        { "type": "Feature", "properties": { "id": "3" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.789292983393091, 49.455271845550783 ], [ 1.775722063752015, 49.65883564016692 ], [ 2.318558849395044, 49.305991729498949 ], [ 1.689772906025202, 49.002907857514927 ], [ 1.789292983393091, 49.455271845550783 ] ] ] ] } },
        { "type": "Feature", "properties": { "id": "4" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 1.789292983393091, 49.455271845550783 ], [ 1.689772906025202, 49.002907857514927 ], [ 1.020274203732134, 49.305991729498949 ], [ 1.789292983393091, 49.455271845550783 ] ] ] ] } }
        ]
    }

    var map = L.map('mapid').setView([49.4, 1.3], 8);

    L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox/streets-v11',
        tileSize: 512,
        zoomOffset: -1,
        accessToken: 'mypk'
    }).addTo(map);

    var myStyle = {
        "color": "#bb7800",
        "weight": 5,
        "opacity": 0.65
    };

    var commercial = L.geoJSON(json_commercial, {
        style: myStyle,
        onEachFeature: storeFeatureId
    }).addTo(map);


    var secteur = L.geoJSON(json_secteurs, {
        style: myStyle,
        onEachFeature: storeFeatureId
    }).addTo(map);


    function storeFeatureId(feature, layer) {
        layer._featureId = feature.properties.id
    }


    function highlightSecteur(e) {
        if (secteur._featureId = e.layer._featureId) {
            secteur.setStyle ({color: '#ffff00'});
        }
    }

    function resetStyle() {
        secteur.setStyle({color: "#bb7800"});
    }

    commercial.on('mouseover',highlightSecteur);
    commercial.on('mouseout',resetStyle);

One Answer

In the above code there are several things wrong or unnecessary.

First, there is no need to store feature id feature.properties.id in the layer object, since it can be always retrieved through layer properties with layer.feature.properties.id.

Second, when you are trying to compare features id in highlightSecteur function, your are using single = operator, so you are actually assigning value e.layer._featureId to secteur._featureId and consequently result of test is always true, since id's are not null.

Third, even if your comparison operator in highlightSecteur function would be correct ==, logic wouldn't work, since secteur is group layer, containing all feature layers.

As @IvanSanchez wrote in his comment, there are two approaches possible to make this work.

On is to iterate through all feature layers of secteur layer when doing comparison in highlightSecteur and compare feature id's. In this case relevant code could look something like this:

var commercial = L.geoJSON(json_commercial, {
  style: myStyle,
}).addTo(map);

var secteur = L.geoJSON(json_secteurs, {
  style: myStyle,
}).addTo(map);

var selectedLayer;

function highlightSecteur(e) {
  secteur.eachLayer(function (layer) {
    if (layer.feature.properties.id == e.layer.feature.properties.id) {
      layer.setStyle({color: '#ffff00'});
      selectedLayer = layer;
      return;
    }
  });
}

function resetStyle() {
  selectedLayer.setStyle({color: "#bb7800"});
}

commercial.on('mouseover',highlightSecteur);
commercial.on('mouseout',resetStyle);

The other approach is to store individual feature layers of secteur in an array where index is feature id. This way there is no need to loop through all the feataure layers when doing comparison, instead feature layer can be referenced by it's id. In this case code could look something like this:

var featureLayers = new Array();
var selectedLayer;

function storeFeatureLayer(feature, layer) {
  featureLayers[parseInt(feature.properties.id)] = layer;
}

function highlightSecteur(e) {
  selectedLayer = featureLayers[parseInt(e.layer.feature.properties.id)];
  selectedLayer.setStyle({color: '#ffff00'});
}

function resetStyle() {
  selectedLayer.setStyle({color: "#bb7800"});
}

var commercial = L.geoJSON(json_commercial, {
  style: myStyle,
}).addTo(map);

var secteur = L.geoJSON(json_secteurs, {
  style: myStyle,
  onEachFeature: storeFeatureLayer
}).addTo(map);

commercial.on('mouseover',highlightSecteur);
commercial.on('mouseout',resetStyle);

Correct answer by TomazicM on April 17, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP