21

Ok, since I already asked a very long question about this, but since it didn't get any new replies for a while, and not to get confused in details, I will keep this one simple the best way I can.

If I'm not mistaken, a setStyle function for a named, particular feature would be as follows:

var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
var rect = L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);

rect.setStyle({color: "#4B1BDE"});

...which would change the color from orange to blue. I'm also aware of the resetStyle() function that will revert the style to the original.

This is how I style my GeoJSON:

var everything = L.geoJson(myfile, {
    onEachFeature: function(feature){
        array_of_layers.addLayer(feature);
    },
    style: function(feature){
            switch(feature.properties.name){
            case "belgium": return belgium_style; break;
            case "bosnia": return bosnia_style; break;
            case "denmark": return denmark_style; break;
            case "great_britain": return britain_style; break;
            case "greece": return greece_style; break;
            case "italy": return italy_style; break;
            case "serbia": return serbia_style; break;
            case "spain": return spain_style; break;
            }
    }

});

What I want to do is to make just one country blue and the others gray, later in the code. It's a two-step thing, to paint all countries to gray, and then make one blue.

The first thing is, I need such a loop that would iterate over each feature and setStyle() for all countries to gray. Does it work if I just everything.setStyle({color: "#4B1BDE"}) or something?

The second thing is, (that's giving me sleepless nights) how do I select just one feature out of a group of GeoJSON polygons to work with? Just the country that I need to paint to blue.

If it was a matter of mouse hovering, I could place an event listener as are done in Leaflet tutorials. But regardless of user interaction, I want to set and reset the style by calling it with its name, as I did with the rectangle above.

  • 1
    Thank you for pointing out leaflet's setStyle() function. – berto Aug 19 '15 at 14:29
26

This works without needing to remove the layer and recreate a new one as described above:

geojson_layer.eachLayer(function (layer) {  
  if(layer.feature.properties.NAME == 'feature 1') {    
    layer.setStyle({fillColor :'blue'}) 
  }
});

It seems to be quite a bit more efficient than removing and recreating the geoJson layer. From the docs, a GeoJSON layer extends FeatureGroup which in turn extends LayerGroup.
Additionally, it seems that each geoJson feature has its own layer in the FeatureGroup!

  • How do I trigger this method when I want to change the style dynamically? – Karussell Jan 7 '16 at 16:33
  • 3
    I think is equivalent to geojson_layer.setStyle(function...) – PeterVermont Aug 9 '16 at 21:30
  • one problem here if you change the layers ie add child layers, they will be created from the original style in the options, not what you set it to – MikeT Feb 22 '18 at 13:16
18

I have written down a small code to style specific geojson feature using leaflet. you can try it on JSFiddle (Original, non-functional), Functional JSFiddle 2018-02-17, or use the following code test locally.

For this example i am using us-states.json files but it can be used for any geojson file.

I hope it will help.

Here is the code:

<!DOCTYPE html>
<html>
<head>
<title>Leaflet Coloring Geojson Features</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://leafletjs.com/dist/leaflet.css" />
<!--[if lte IE 8]><link rel="stylesheet" href="../dist/leaflet.ie.css" /><![endif]-->
<style>
#map {
    width: 800px;
    height: 500px;
}
.info {
    padding: 6px 8px;
    font: 14px/16px Arial, Helvetica, sans-serif;
    background: white;
    background: rgba(255, 255, 255, 0.8);
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
    border-radius: 5px;
}
.info h4 {
    margin: 0 0 5px;
    color: #777;
}
.legend {
    text-align: left;
    line-height: 18px;
    color: #555;
}
.legend i {
    width: 18px;
    height: 18px;
    float: left;
    margin-right: 8px;
    opacity: 0.7;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
<script src="http://leafletjs.com/dist/leaflet.js"></script> 
<script type="text/javascript" src="http://leafletjs.com/examples/us-states.js"></script> 
<script type="text/javascript">
    $(document).ready(function () {
        init_map();
        init_geojson();
        $("#btn").on('click', function () {
            var stateName = $('#statename').val();
            console.log(stateName);
            init_geojson(stateName);
        });
    });
    var map, geojson, sn;

    function init_map() {
        map = L.map('map').setView([37.8, -96], 4);
        L.tileLayer('http://{s}.tile.cloudmade.com/{key}/22677/256/{z}/{x}/{y}.png', {
            attribution: 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2012 CloudMade',
            key: 'BC9A493B41014CAABB98F0471D759707'
        }).addTo(map);
        geojson = L.geoJson(statesData, {
            style: style
            //onEachFeature: onEachFeature,
        }).addTo(map);
    }

    function init_geojson(n) {
        console.log(geojson.options);
        map.removeLayer(geojson);
        if (n != "") {
            sn = n;
            console.log(sn);
            geojson = L.geoJson(statesData, {
                style: style
            }).addTo(map);
        }
    }

    function style(feature) {
        console.log(sn);
        if (sn == feature.properties.name) {
            return {
                weight: 2,
                opacity: 1,
                color: 'white',
                dashArray: '3',
                fillOpacity: 0.3,
                fillColor: '#ff0000'
            };
        } else {
            return {
                weight: 2,
                opacity: 1,
                color: 'white',
                dashArray: '3',
                fillOpacity: 0.3,
                fillColor: '#666666'
            };
        }
    }
</script>
<input type="text" id="statename" value="Alaska">
<input type="button" id="btn" value="Set Color"/>
</body>
</html>
  • 2
    So, it was all about making a style(feature) function checking over the feature.properties.name value. Thanks! – Doruk Karınca Oct 29 '13 at 10:29
  • @DorukKarınca Yes :) – Farhat Abbas Oct 29 '13 at 10:36
  • Awesome! This is exactly what I was searching for! – joosthoek Nov 8 '15 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.