简体   繁体   中英

Change Leaflet marker icon with data from external geoJSON file

I have a problem at changing the icons of my geoJSON data on my Leaflet map.

I'm loading my data from external geoJSON files. Therefore I'm using a XMLHttpRequest() to open the files (filenames are stored in an array orteDB ) and then add them to my layer orte where it's then added to the map:

for (var i = 0; i < orteDB.length; i++) {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', 'files/geoJSONfiles/orte/' + orteDB[i]);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.responseType = 'json';
    xhr.onload = function () {
        if (xhr.status !== 200) return
        L.geoJSON(xhr.response).addTo(orte).on('click', onClick);
    };
    xhr.send();
}

orte = L.geoJson(orte).addTo(map);

I already managed to change the default icon with the help of this example https://gist.github.com/geog4046instructor/80ee78db60862ede74eacba220809b64 . But what I actually want is the icon to change dynamically after the click of a button or the marker itself to this redIcon :

var redIcon = L.Icon.extend({
        iconUrl: 'files/marker-icon_red.png',
        iconSize:     [25, 41],
        iconAnchor:   [12, 40],
    });

I also tried working with the pointToLayer() function but it didn't work for me.

Each geoJSON point has a unique ID which I can call via e.layer.feature.properties.id . So in the end I'd like to change the marker icon individually by using it's unique ID.

My geoGSON files look like this:

{
 "type": "FeatureCollection",
 "name": "02_Roncesvalles",
 "features": [
  { 
   "type": "Feature", 
   "properties": 
     { 
      "id": 2 }, 
   "geometry": 
     { 
      "type":"Point", 
      "coordinates": [ 
        -1.320700314538876, 
        43.009378247303687 ] 
     } 
   }
  ]
}

Thank you very much for your help!

You can change the icon of a marker with marker.setIcon(icon) and you need to loop through all layers and find the correct one over the id.

I use map.eachLayer instead of orte.eachLayer() because the GeoJSON Group can also contains LayerGroups.

var wantedId = 1;
map.eachLayer((layer)=>{
   if(layer instanceof L.Marker && layer.feature && layer.feature.properties && layer.feature.properties.id == wantedId){
      layer.setIcon(new redIcon());
   }
});

Update

Thx to @ghybs, I didn't recognice the extend of the icon.

If you want to extend the icon class you need to put the options in a options property.

var redIcon = L.Icon.extend({
   options: {
        iconUrl: 'files/marker-icon_red.png',
        iconSize:     [25, 41],
        iconAnchor:   [12, 40],
   }
});

And then you can change the Icon with marker.setIcon(new redIcon())

But I suggest you to simply create a Icon variable instead of creating a new class.

var redIcon = L.icon({
        iconUrl: 'files/marker-icon_red.png',
        iconSize:     [25, 41],
        iconAnchor:   [12, 40],
    });

And then call marker.setIcon(redIcon)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM