4

Leaflet js beginner following/adapting the choropleth example. I need to get something like this mapbox map where the feature styles change according to zoom level. I am loading a line geojson that gets style from getColor / getWidth functions related to feature.properties. How do I get the weight to be 1 when currentZoom is <= 16?

var geojson = L.geoJson(roads, {
      style: style
    }).addTo(map);

function getColor(p) {
  return p >= 100 ? '#00F7BD' :
    p >= 40 ? '#24abc9' :
    p >= 20 ? '#ef561a' : 
    p >= 0 ? '#4D2A2D' : 
    '#feffbd';
}

function getWidth(w) {
   return w > 20 ? 4.8 :
          w > 17 ? 4.5 :
          w > 16 ? 4 :
          w > 15 ? 3.5 :
          w > 14 ? 2.5 :
          w > 10 ? 1.5 :
          w > 0 ? 0.5 :
          0;
}

// map.on('zoomend', function () {
  var currentZoom = map.getZoom();

function style(feature) {
      if (currentZoom <= 16) {
        return {
          color: getColor(feature.properties.paP),
          weight: 1, 
          opacity: 0.5,
        };
      }
      else {
        return {
          weight: getWidth(feature.properties.stW),
          color: getColor(feature.properties.paP),
        };
      }
}
// });

Second approach inspired by Stephen's answer @Stephen Lead

   function style(feature) {
      var fa;
      return {
          color: getColor(feature.properties.paP),
          weight: fa * getWidth(feature.properties.stW),
          opacity: 0.6,
          lineCap: 'square',
          lineJoin: 'square',
        };
    }

    map.on('zoomend', function () {
        var currentZoom = map.getZoom();
            if (currentZoom <= 16) {
                  fa = 0.5;
            }
            else {
                  fa = 3;
            }
    });
4
  • If you call the function style () with a feature in argument it should work. Do you get any js error when you try this? – Hugo Roussaffa - GeoDatup Sep 27 '17 at 19:58
  • Thanks for your answer, but I'm too beginner to get it. Can you develop further? Look, I'm tweaking my attempts here plnkr.co/edit/HClAOxy0jnYdneOVjG5s?p=preview – Nico P Sep 27 '17 at 20:03
  • When you declare the style properties of geojson features call your function named "style()" like that style: style(feature) – Hugo Roussaffa - GeoDatup Sep 27 '17 at 20:20
  • No, your suggestion doesn't work. Actually, for your reference in the code, the 'else' statement does works. – Nico P Sep 27 '17 at 20:41
1

One approach is to set the style's width property based on the current map scale, and update this whenever the scale changes.

See the JS Fiddle for an example, and zoom in to see the width increase:

enter image description here

function addStates() {
    // this function adds the states layer with the style's weight determined
    // by the current zoom level
    geojson = L.geoJson(statesData, {
        style: style
    }).addTo(map);
  }

function style(feature) {
    // the weight is a function of the current map scale
    var wt;
    if (map.getZoom() <= 6) {
        wt = 1;
    } else {
        wt = 20;
    }
    return {
        weight: wt,
        ....
    };
}  

// whenever the zoom level changes, remove the layer and re-add it to 
// force the style to update based on the current map scale
map.on("zoomend", function(){
  geojson.removeFrom(map);
  addStates();
});

This suggested approach removes the layer each time the scale changes, then adds it again to force the setStyle function to recalculate based on the current map scale. It may be possible to make this more efficient, but it seems to work reasonably well.

(I picked zoom level 6 and a width of 20 for an easy demonstration of the effects - it's difficult to determine the difference between a width of 1 and 2 visually)

4
  • Thanks. For some reason I can not make it work with the line geojson I am working with. However, your answer made think of a possible ('beginner') solution (see the second approach I added below the original question) Sadly, it still doesn't work. Any thoughts? – Nico P Sep 28 '17 at 1:02
  • you need to set fa as a global variable - your current code over-writes whatever value of fa exists when the style function runs – Stephen Lead Sep 28 '17 at 1:15
  • Also, you need something to trigger the style function and feed it a feature - that's why my demo removes the layer and re-adds it, to force the style function to be re-run. Simply changing the fa value isn't enough to cause the change – Stephen Lead Sep 28 '17 at 1:17
  • A simple update to my sample is to replace line 33 with something like: weight: wt * (feature.properties.density / 10), - this demonstrates how to use a factor based on the map scale * an attribute from the dataset (I've used density since that's available on the sample States json file, and divided by 10 so it displays OK) – Stephen Lead Sep 28 '17 at 1:48

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.